|
|
1.1 root 1: #ifndef lint
2: static char *rcsid_draw_c = "$Header: draw.c,v 10.1 86/11/19 10:41:27 jg Exp $";
3: #endif lint
4: /* draw.c - Draw lines, curves, and polygons on the screen
5: *
6: * DrawCurve Draw a generalized line/polygon/combination
7: *
8: * Author:
9: * Scott Bates
10: * Brown University
11: * IRIS, Box 1946
12: * Providence, RI 02912
13: *
14: *
15: * Copyright (c) 1986 Brown University
16: *
17: * Permission to use, copy, modify and distribute this software and its
18: * documentation for any purpose and without fee is hereby granted, provided
19: * that the above copyright notice appear in all copies, and that both
20: * that copyright notice and this permission notice appear in supporting
21: * documentation, and that the name of Brown University not be used in
22: * advertising or publicity pertaining to distribution of the software
23: * without specific, written prior permission. Brown University makes no
24: * representations about the suitability of this software for any purpose.
25: * It is provided "as-is" without express or implied warranty.
26: */
27:
28: #include "private.h"
29: #include "bitblt.h"
30:
31: DrawCurve (verts, vertcount, xbase, ybase, srcpix, altpix, mode,
32: bwidth, bheight, pat, patlen, patmul, clips, clipcount, func, zmask)
33: Vertex *verts;
34: int vertcount, xbase, ybase, srcpix, altpix, mode, bwidth, bheight;
35: int pat, patlen, patmul, clipcount, zmask;
36: int func;
37: CLIP *clips;
38: {
39: register NumberOfClips;
40: register CLIP *ClipPointer;
41: Vertex *newverts;
42: int newvertcount, i;
43:
44: #ifdef TRACE_X
45: fprintf(stderr, "In DrawCurve\n");
46: fflush(stderr);
47: #endif TRACE_X
48:
49: /*
50: * Limit draw operation to one plane and
51: * ignore requests of less than two points
52: */
53:
54: if ((zmask & 1) == 0 || vertcount < 2)
55: return;
56:
57: /*
58: * Convert vertex list to absolute straight lines
59: */
60:
61: if(PathListConverter(verts, vertcount, xbase, ybase, &newverts,
62: &newvertcount, DRAW_PATH_LIST) == NULL ) {
63: DeviceError("DrawCurve failure in PathListConverter()\n");
64: return;
65: }
66:
67: /*
68: * Single pixel wide line ?
69: */
70:
71: if (bwidth == 1 && bheight == 1) {
72: /*
73: * Loop thru vertex list
74: */
75:
76: for(i = 0; i < newvertcount; i += 2) {
77: ClipPointer = clips;
78: NumberOfClips = clipcount;
79:
80: /*
81: * Draw the same line ounce for each
82: * clipping rectangle
83: */
84:
85: for (;;) {
86: SinglePixelLine(&pbm, newverts[i].x,
87: newverts[i].y, newverts[i + 1].x,
88: newverts[i + 1].y, ClipPointer,
89: func, mode, srcpix, altpix, pat,
90: patlen, patmul);
91: /*
92: * Any more clips ?
93: */
94:
95: if(--NumberOfClips <= 0) {
96: /*
97: * No more clips so lets leave
98: */
99:
100: break;
101: }
102:
103: /*
104: * Point to next clip
105: */
106:
107: ClipPointer++;
108: }
109: }
110: } else {
111: Blt_Rectangle dst_rect;
112: Blt_Line line;
113: register Blt_Line *Line = &line;
114: register Blt_Rectangle *DstRect = &dst_rect;
115: register Blt_Rectangle *ClipRect = &Line->blt.clp_rect;
116:
117: /*
118: * Zero line data structure
119: */
120:
121: bzero((char *) Line, sizeof(Blt_Line));
122:
123: /*
124: * Fill in destination bitmap
125: */
126:
127: BitimageToBitmap((u_short *)pbm.data, 0, 0, pbm.width,
128: pbm.height, &Line->blt.dst_bitmap);
129:
130: /*
131: * Set brush size and tile pattern(s)
132: */
133:
134: Line->BrushX = bwidth;
135: Line->BrushY = bheight;
136: Line->blt.tile_ptr = (Blt_Tile *) ConstantTiles[srcpix & 1];
137: if(mode == DrawPatternedLine)
138: Line->AlternateTile =
139: (Blt_Tile *) ConstantTiles[altpix & 1];
140:
141: /*
142: * Fill in dash pattern
143: */
144:
145: if(mode != DrawSolidLine) {
146: Line->Pattern = (u_short) pat;
147: Line->PatternLength = (short) patlen;
148: Line->PatternMultiplier = (short) patmul;
149: }
150:
151: /*
152: * Fill in appropriate combination rule
153: */
154:
155: if(IS_RULE_TILE(func)) {
156: /*
157: * Fill in rule directly
158: */
159:
160: Line->blt.comb_rule = func;
161: } else {
162: /*
163: * Convert standard rule to tile rule
164: */
165:
166: Line->blt.comb_rule = MAKE_TILE_RULE(func);
167: }
168:
169: /*
170: * Fill in draw mode
171: */
172:
173: Line->DrawMode = mode;
174:
175: /*
176: * Loop thru vertex list
177: */
178:
179: for (;newvertcount > 0; newvertcount -= 2) {
180:
181: /*
182: * Set start and stop endpoints
183: */
184:
185: Line->StartX = newverts->x;
186: Line->StartY = (newverts++)->y;
187: Line->StopX = newverts->x;
188: Line->StopY = (newverts++)->y;
189:
190: /*
191: * Compute and set destination rectangle
192: */
193:
194: DstRect->origin_y = MIN(Line->StopY, Line->StartY);
195: DstRect->origin_x = MIN(Line->StopX, Line->StartX);
196: DstRect->corner_y =
197: MAX(Line->StopY, Line->StartY) + Line->BrushY;
198: DstRect->corner_x =
199: MAX(Line->StopX, Line->StartX) + Line->BrushX;
200: Line->blt.dst_rect = *DstRect;
201:
202: /*
203: * Setup for clips
204: */
205:
206: NumberOfClips = clipcount;
207: ClipPointer = clips;
208:
209: /*
210: * Draw same line ounce for each clip specified
211: */
212:
213: for(;;) {
214: /*
215: * Convert X clip to clipping rectangle
216: */
217:
218: ClipToRect(ClipPointer, ClipRect);
219:
220: /*
221: * If destination rectangle is inside the
222: * clipping rectangle then turn off clipping
223: * else turn it on.
224: */
225:
226: if(InsideBounds(DstRect, ClipRect)) {
227: Line->blt.blt_flags &= ~BLT_CLIPON;
228: } else {
229: Line->blt.blt_flags |= BLT_CLIPON;
230: }
231:
232: /*
233: * Call multi pixel line drawing routine
234: */
235:
236: MultiPixelLine(Line);
237:
238: /*
239: * Any more clips ?
240: */
241:
242: if(--NumberOfClips <= 0) {
243: /*
244: * No more clips so lets leave
245: */
246:
247: break;
248: }
249:
250: /*
251: * Point to next clip
252: */
253:
254: ClipPointer++;
255: }
256: }
257: }
258:
259: /*
260: * Free space used by new vertex list
261: */
262:
263: free((caddr_t)newverts);
264: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.