|
|
1.1 root 1: #ifndef lint
2: static char *rcsid_mpixline_c = "$Header: mpixline.c,v 10.1 86/11/19 10:43:05 jg Exp $";
3: #endif lint
4: /* mpixline.c - multi pixel wide line drawing routines
5: *
6: * MultiPixelLine preprocessing routine for multi pixel wide line drawing
7: * SolidLine draws solid lines
8: * DashedLine draws dashed lines
9: * PatternedLine draws patterned lines
10: *
11: * Author:
12: * Scott Bates
13: * Brown University
14: * IRIS, Box 1946
15: * Providence, RI 02912
16: *
17: *
18: * Copyright (c) 1986 Brown University
19: *
20: * Permission to use, copy, modify and distribute this software and its
21: * documentation for any purpose and without fee is hereby granted, provided
22: * that the above copyright notice appear in all copies, and that both
23: * that copyright notice and this permission notice appear in supporting
24: * documentation, and that the name of Brown University not be used in
25: * advertising or publicity pertaining to distribution of the software
26: * without specific, written prior permission. Brown University makes no
27: * representations about the suitability of this software for any purpose.
28: * It is provided "as-is" without express or implied warranty.
29: */
30:
31: #include "private.h"
32: #include "bitblt.h"
33:
34: MultiPixelLine(Line)
35: register Blt_Line *Line;
36: {
37: register Blt *blt = &Line->blt;
38:
39: #ifdef TRACE_X
40: fprintf(stderr, "In MultiPixelLine\n");
41: fflush(stderr);
42: #endif TRACE_X
43:
44: #ifdef AED
45: blt->blt_flags |= BLT_ECHO;
46: #endif AED
47:
48: /*
49: * If the line is a solid horizontal or vertical tile
50: * the destination rectangle.
51: */
52:
53: if (Line->DrawMode == DrawSolidLine && (Line->StopX == Line->StartX ||
54: Line->StopY == Line->StartY)) {
55: /*
56: * Line is a solid horizontal or vertical so handle
57: * this as a tile fill of destination rectangle
58: */
59:
60: bitblt(blt);
61: } else { /* Line is a diagonal */
62: register short StartX = Line->StartX;
63: register short StartY = Line->StartY;
64: register short StopX = Line->StopX;
65: register short StopY = Line->StopY;
66: int BrushX = Line->BrushX;
67: int BrushY = Line->BrushY;
68: short *Top, *Left, *Bottom, *Right;
69: int DeltaX, DeltaY, SignY;
70:
71: /*
72: * Always draw line from left to right
73: */
74:
75: if (StopX < StartX) {
76: short Temp;
77:
78: Temp = StopX; StopX = StartX; StartX = Temp;
79: Temp = StopY; StopY = StartY; StartY = Temp;
80: }
81:
82: /*
83: * Initialize pointers to destination rectangle
84: */
85:
86: Top = &blt->dst_rect.origin_y;
87: Left = &blt->dst_rect.origin_x;
88: Bottom = &blt->dst_rect.corner_y;
89: Right = &blt->dst_rect.corner_x;
90:
91: /*
92: * Set destination rectangle to be the first
93: * the point in line
94: */
95:
96: *Left = StartX;
97: *Top = StartY;
98: *Right = StartX + Line->BrushX;
99: *Bottom = StartY + Line->BrushY;
100:
101: /*
102: * Compute X and Y deltas
103: */
104:
105: DeltaX = StopX - StartX;
106: DeltaY = StopY - StartY;
107:
108: /*
109: * Determine vertical drawing direction
110: * and adjust values if required
111: */
112:
113: if(DeltaY < 0) {
114: DeltaY = -DeltaY; /* bottom to top */
115: SignY = -1;
116: BrushY = -BrushY;
117: Top = &blt->dst_rect.corner_y;
118: Bottom = &blt->dst_rect.origin_y;
119: } else {
120: SignY = 1; /* top to bottom */
121: }
122:
123: /*
124: * Call appropriate line drawing routine
125: */
126:
127: switch (Line->DrawMode) {
128: case (DrawSolidLine):
129: SolidLine(Line, Top, Left, Bottom, Right,
130: DeltaX, DeltaY, BrushX, BrushY, SignY);
131: break;
132: case (DrawDashedLine):
133: DashedLine(Line, Top, Left, Bottom, Right,
134: DeltaX, DeltaY, BrushX, BrushY, SignY);
135: break;
136: case (DrawPatternedLine):
137: PatternedLine(Line, Top, Left, Bottom, Right,
138: DeltaX, DeltaY, BrushX, BrushY, SignY);
139: }
140: }
141: }
142:
143: /*
144: * Draw a solid line
145: */
146:
147: static
148: SolidLine(Line, Top, Left, Bottom, Right, DeltaX, DeltaY,
149: BrushX, BrushY, SignY)
150: Blt_Line *Line;
151: register short *Top, *Left;
152: register short *Bottom, *Right;
153: int DeltaX, DeltaY;
154: int BrushX, BrushY;
155: int SignY;
156: {
157: Blt *blt = &Line->blt;
158: register BitsLeftToDraw, Sentinel;
159:
160: #ifdef TRACE_X
161: fprintf(stderr, "In SolidLine\n");
162: fflush(stderr);
163: #endif TRACE_X
164:
165: /*
166: * draw solid line
167: */
168: /* line is more horizontal */
169: if(DeltaX > DeltaY) {
170: Sentinel = DeltaX >> 1;
171: BitsLeftToDraw = DeltaX;
172:
173: while (BitsLeftToDraw--) {
174: if ((Sentinel -= DeltaY) < 0) {
175: bitblt(blt);
176: *Left = *Right - BrushX + 1;
177: *Top += SignY;
178: *Bottom += SignY;
179: Sentinel += DeltaX;
180: }
181: (*Right)++;
182: }
183: bitblt(blt);
184: } else { /* line is more vertical */
185: Sentinel = DeltaY >> 1;
186: BitsLeftToDraw = DeltaY;
187:
188: while (BitsLeftToDraw--) {
189: if ((Sentinel -= DeltaX) < 0) {
190: bitblt(blt);
191: *Top = *Bottom - BrushY + SignY;
192: (*Left)++;
193: (*Right)++;
194: Sentinel += DeltaY;
195: }
196: *Bottom += SignY;
197: }
198: bitblt(blt);
199: }
200: }
201:
202: /*
203: * Draw a dashed line
204: */
205:
206: static
207: DashedLine(Line, Top, Left, Bottom, Right, DeltaX, DeltaY,
208: BrushX, BrushY, SignY)
209: Blt_Line *Line;
210: register short *Top, *Left;
211: register short *Bottom, *Right;
212: int DeltaX, DeltaY;
213: int BrushX, BrushY;
214: int SignY;
215: {
216: Blt *blt = &Line->blt;
217: u_short PatternFirstBit = 1 << (Line->PatternLength - 1);
218: u_short PatternBit = PatternFirstBit;
219: u_short Pattern = Line->Pattern;
220: short PatternMultiplier = Line->PatternMultiplier;
221: register BitsLeftToDraw, Sentinel;
222:
223: #ifdef TRACE_X
224: fprintf(stderr, "In DashedLine\n");
225: fflush(stderr);
226: #endif TRACE_X
227:
228: /*
229: * Draw dashed line
230: */
231:
232: /* line is more horizontal */
233: if(DeltaX > DeltaY) {
234: Sentinel = DeltaX >> 1;
235: BitsLeftToDraw = DeltaX;
236:
237: while (BitsLeftToDraw--) {
238: if(Pattern & PatternBit)
239: bitblt(blt);
240: if(--PatternMultiplier == 0) {
241: PatternMultiplier = Line->PatternMultiplier;
242: if((PatternBit >>= 1) == 0)
243: PatternBit = PatternFirstBit;
244: }
245: *Left = *Right - BrushX + 1;
246: (*Right)++;
247: if ((Sentinel -= DeltaY) < 0) {
248: *Top += SignY;
249: *Bottom += SignY;
250: Sentinel += DeltaX;
251: }
252: }
253: if(Pattern & PatternBit)
254: bitblt(blt);
255: } else { /* line is more vertical */
256: Sentinel = DeltaY >> 1;
257: BitsLeftToDraw = DeltaY;
258:
259: while (BitsLeftToDraw--) {
260: if(Pattern & PatternBit)
261: bitblt(blt);
262: if(--PatternMultiplier == 0) {
263: PatternMultiplier = Line->PatternMultiplier;
264: if((PatternBit >>= 1) == 0)
265: PatternBit = PatternFirstBit;
266: }
267: *Top = *Bottom - BrushY + SignY;
268: *Bottom += SignY;
269: if ((Sentinel -= DeltaX) < 0) {
270: (*Left)++;
271: (*Right)++;
272: Sentinel += DeltaY;
273: }
274: }
275: if(Pattern & PatternBit)
276: bitblt(blt);
277: }
278: }
279:
280: /*
281: * Draw a patterned line
282: */
283:
284: static
285: PatternedLine(Line, Top, Left, Bottom, Right, DeltaX, DeltaY,
286: BrushX, BrushY, SignY)
287: Blt_Line *Line;
288: register short *Top, *Left;
289: register short *Bottom, *Right;
290: int DeltaX, DeltaY;
291: int BrushX, BrushY;
292: int SignY;
293: {
294: Blt *blt = &Line->blt;
295: u_short PatternFirstBit = 1 << (Line->PatternLength - 1);
296: u_short PatternBit = PatternFirstBit;
297: u_short Pattern = Line->Pattern;
298: short PatternMultiplier = Line->PatternMultiplier;
299: Blt_Tile *SourceTile = blt->tile_ptr;
300: Blt_Tile *AltSourceTile = Line->AlternateTile;
301: register BitsLeftToDraw, Sentinel;
302:
303: #ifdef TRACE_X
304: fprintf(stderr, "In PatternedLine\n");
305: fflush(stderr);
306: #endif TRACE_X
307:
308: /*
309: * Draw patterned line
310: */
311:
312: /* line is more horizontal */
313: if(DeltaX > DeltaY) {
314: Sentinel = DeltaX >> 1;
315: BitsLeftToDraw = DeltaX;
316:
317: while (BitsLeftToDraw--) {
318: if(Pattern & PatternBit)
319: blt->tile_ptr = SourceTile;
320: else
321: blt->tile_ptr = AltSourceTile;
322: bitblt(blt);
323:
324: if(--PatternMultiplier == 0) {
325: PatternMultiplier = Line->PatternMultiplier;
326: if((PatternBit >>= 1) == 0)
327: PatternBit = PatternFirstBit;
328: }
329:
330: *Left = *Right - BrushX + 1;
331: (*Right)++;
332: if ((Sentinel -= DeltaY) < 0) {
333: *Top += SignY;
334: *Bottom += SignY;
335: Sentinel += DeltaX;
336: }
337: }
338: if(Pattern & PatternBit)
339: blt->tile_ptr = SourceTile;
340: else
341: blt->tile_ptr = AltSourceTile;
342: bitblt(blt);
343: blt->tile_ptr = SourceTile;
344: } else { /* line is more vertical */
345: Sentinel = DeltaY >> 1;
346: BitsLeftToDraw = DeltaY;
347:
348: while (BitsLeftToDraw--) {
349: if(Pattern & PatternBit)
350: blt->tile_ptr = SourceTile;
351: else
352: blt->tile_ptr = AltSourceTile;
353: bitblt(blt);
354:
355: if(--PatternMultiplier == 0) {
356: PatternMultiplier = Line->PatternMultiplier;
357: if((PatternBit >>= 1) == 0)
358: PatternBit = PatternFirstBit;
359: }
360:
361: *Top = *Bottom - BrushY + SignY;
362: *Bottom += SignY;
363: if ((Sentinel -= DeltaX) < 0) {
364: (*Left)++;
365: (*Right)++;
366: Sentinel += DeltaY;
367: }
368: }
369: if(Pattern & PatternBit)
370: blt->tile_ptr = SourceTile;
371: else
372: blt->tile_ptr = AltSourceTile;
373: bitblt(blt);
374: blt->tile_ptr = SourceTile;
375: }
376: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.