|
|
1.1 root 1: #ifndef lint
2: static char *rcsid_tile_c = "$Header: tile.c,v 10.3 86/11/29 13:49:10 jg Rel $";
3: #endif lint
4: #ifdef sun
5: /*
6: * The Sun X drivers are a product of Sun Microsystems, Inc. and are provided
7: * for unrestricted use provided that this legend is included on all tape
8: * media and as a part of the software program in whole or part. Users
9: * may copy or modify these drivers without charge, but are not authorized
10: * to license or distribute them to anyone else except as part of a product or
11: * program developed by the user.
12: *
13: * THE SUN X DRIVERS ARE PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND
14: * INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A
15: * PARTICULAR PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE
16: * PRACTICE.
17: *
18: * The Sun X Drivers are provided with no support and without any obligation
19: * on the part of Sun Microsystems, Inc. to assist in their use, correction,
20: * modification or enhancement.
21: *
22: * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
23: * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THE SUN X
24: * DRIVERS OR ANY PART THEREOF.
25: *
26: * In no event will Sun Microsystems, Inc. be liable for any lost revenue
27: * or profits or other special, indirect and consequential damages, even if
28: * Sun has been advised of the possibility of such damages.
29: *
30: * Sun Microsystems, Inc.
31: * 2550 Garcia Avenue
32: * Mountain View, California 94043
33: */
34:
35: #ifndef lint
36: static char sccsid[] = "@(#)tile.c 2.1 86/01/28 Copyright 1986 Sun Micro";
37: #endif
38:
39: /*-
40: * Copyright (c) 1986 by Sun Microsystems, Inc.
41: */
42:
43: /* tile.c Perform a raster operation involving a pattern
44: *
45: * TileFill Patterns a portion of the screen
46: * DrawFilled Draw a filled generalized line/polygon/combination
47: *
48: */
49:
50: /*
51: * ToDo:
52: * Implement draw filled
53: * Implement tile fill with xymap
54: * Use static pixrects
55: */
56:
57: #include "Xsun.h"
58:
59: extern struct pixrect *PixRect;
60:
61: char *Xalloc();
62:
63: static
64: PixrectFill(Tile, xymask, dstx, dsty, width, height, op, clips, clipcount, xoff, yoff)
65: struct pixrect *Tile;
66: BITMAP *xymask;
67: int dstx, dsty, width, height;
68: unsigned op;
69: CLIP *clips;
70: int clipcount;
71: int xoff, yoff;
72: {
73: if (xymask == NULL) {
74: /* spread tile from (dstx,dsty) by (width,height) */
75: do {
76: int cleft, ctop, cwidth, cheight;
77:
78: GetNextClip(clips, cleft, ctop, cwidth, cheight);
79: if (OverLap(cleft, ctop, cwidth, cheight, dstx, dsty, width, height)) {
80: int tleft = (cleft > dstx ? cleft : dstx);
81: int ttop = (ctop > dsty ? ctop : dsty);
82: int twidth = (cleft + cwidth < dstx + width ? cleft + cwidth : dstx + width) - tleft;
83: int theight = (ctop + cheight < dsty + height ? ctop + cheight : dsty + height) - ttop;
84: /* XXX - is this the right tile mode? */
85: CheckCursor(tleft, ttop, twidth, theight);
86: pr_replrop(PixRect, tleft, ttop, twidth, theight, op,
87: Tile, tleft - xoff, ttop - yoff);
88: }
89: } while (--clipcount > 0);
90: }
91: else {
92: /* spread tile thru xymask */
93: struct pixrect *stencil = mem_point(xymask->width, xymask->width, 1, xymask->data);
94:
95: #ifdef notdef
96: do {
97: int cleft, ctop, cwidth, cheight;
98:
99: GetNextClip(clips, cleft, ctop, cwidth, cheight);
100: if (OverLap(cleft, ctop, cwidth, cheight, dstx, dsty, width, height)) {
101: int tleft = (cleft > dstx ? cleft : dstx);
102: int ttop = (ctop > dsty ? ctop : dsty);
103: int twidth = (cleft + cwidth < dstx + width ? cleft + cwidth : dstx + width) - tleft;
104: int theight = (ctop + cheight < dsty + height ? ctop + cheight : dsty + height) - ttop;
105: CheckCursor(tleft, ttop, twidth, theight);
106: /* XXX - need combination of stencil & replrop */
107: pr_stencil(PixRect, tleft, ttop, twidth, theight, op, &stencil, tleft, ttop, NULL, 0, 0);
108: }
109: } while (--clipcount > 0);
110: #endif
111: pr_destroy(stencil);
112: }
113: }
114:
115: static
116: ConstantFill(tile, xymask, dstx, dsty, width, height, op, clips, clipcount)
117: PIXMAP *tile;
118: BITMAP *xymask;
119: int dstx, dsty, width, height;
120: unsigned op;
121: CLIP *clips;
122: int clipcount;
123: {
124: op |= PIX_COLOR((PINVERT(tile) ^ (int) tile->data));
125: if (xymask == NULL) {
126: /* spread constant from (dstx,dsty) by (width,height) */
127: do {
128: int cleft, ctop, cwidth, cheight;
129:
130: GetNextClip(clips, cleft, ctop, cwidth, cheight);
131: if (OverLap(cleft, ctop, cwidth, cheight, dstx, dsty, width, height)) {
132: int tleft = (cleft > dstx ? cleft : dstx);
133: int ttop = (ctop > dsty ? ctop : dsty);
134: int twidth = (cleft + cwidth < dstx + width ? cleft + cwidth : dstx + width) - tleft;
135: int theight = (ctop + cheight < dsty + height ? ctop + cheight : dsty + height) - ttop;
136: CheckCursor(tleft, ttop, twidth, theight);
137: /* XXX - is this the right tile mode? */
138: pr_rop(PixRect, tleft, ttop, twidth, theight, op, NULL, 0, 0);
139: }
140: } while (--clipcount > 0);
141: }
142: else {
143: /* spread constant thru xymask */
144: struct pixrect *stencil = mem_point(xymask->width, xymask->width, 1, xymask->data);
145:
146: do {
147: int cleft, ctop, cwidth, cheight;
148:
149: GetNextClip(clips, cleft, ctop, cwidth, cheight);
150: if (OverLap(cleft, ctop, cwidth, cheight, dstx, dsty, width, height)) {
151: int tleft = (cleft > dstx ? cleft : dstx);
152: int ttop = (ctop > dsty ? ctop : dsty);
153: int twidth = (cleft + cwidth < dstx + width ? cleft + cwidth : dstx + width) - tleft;
154: int theight = (ctop + cheight < dsty + height ? ctop + cheight : dsty + height) - ttop;
155:
156: CheckCursor(tleft, ttop, twidth, theight);
157: pr_stencil(PixRect, tleft, ttop, twidth, theight, op, stencil, tleft, ttop, NULL, 0, 0);
158: }
159: } while (--clipcount > 0);
160: pr_destroy(stencil);
161: }
162: }
163:
164:
165: /*ARGSUSED*/
166: TileFill (tile, xoff, yoff, xymask, dstx, dsty, width, height,
167: clips, clipcount, func, zmask)
168: PIXMAP *tile;
169: BITMAP *xymask;
170: int xoff, yoff, dstx, dsty, width, height, zmask;
171: register int func;
172: CLIP *clips;
173: {
174: int op = SUN_FROM_X_OP(func) | PIX_DONTCLIP;
175: int allmask = -1;
176:
177: if ((PixRect->pr_depth == 1) && !(zmask & 1))
178: return;
179: SetZmask(PixRect, &zmask);
180: switch (PTYPE(tile)) {
181: case BitmapPixmap:
182: {
183: struct pixrect *Tile =
184: mem_point(tile->width, tile->height, 1, ((BITMAP *) tile->data)->data); /* XXX - slow !!! */
185:
186: if (PINVERT(tile)) {
187: op = SUN_FROM_X_OP_INVERT(func) | PIX_DONTCLIP;
188: }
189: PixrectFill(Tile, xymask, dstx, dsty, width, height, op, clips, clipcount, xoff, yoff);
190: pr_destroy(Tile);
191: }
192: break;
193: case ConstantPixmap:
194: ConstantFill(tile, xymask, dstx, dsty, width, height, op, clips, clipcount);
195: break;
196: case XYColorPixmap:
197: /* XXX - not yet implemented - do plane by plane */
198: break;
199: case ZColorPixmap:
200: {
201: struct pixrect *Tile =
202: mem_point(tile->width, tile->height, PixRect->pr_depth, tile->data); /* XXX - slow !!! */
203:
204: PixrectFill(Tile, xymask, dstx, dsty, width, height, op, clips, clipcount, xoff, yoff);
205: pr_destroy(Tile);
206: }
207: break;
208: }
209: SetZmask(PixRect, &allmask);
210: RestoreCursor();
211: }
212:
213: /*
214: * MAXPOLYGONS is the greatest number of polygons possible. It should be
215: * large, but not too large and is used only when defining npts
216: */
217: #define MAXPOLYGONS 256
218:
219: /*ARGSUSED*/
220: DrawFilled (verts, vertcount, xbase, ybase, srcpix, tile, xoff, yoff,
221: clips, clipcount, func, zmask)
222: Vertex *verts;
223: register PIXMAP *tile;
224: int vertcount, xbase, ybase, srcpix, xoff, yoff, clipcount, zmask;
225: register int func;
226: CLIP *clips;
227: {
228: struct pr_pos *vertices; /* vertices for pr_polygon_2 */
229: register struct pr_pos *tvert; /* pointer into vertices */
230: int npts[MAXPOLYGONS]; /* # points per polygon */
231: int npgons; /* number of polygons */
232: struct pixrect *tilepr; /* tiling pixrect */
233: struct pixrect *pgons; /* polygon pgons */
234: struct pixrect *srcpr; /* src for filling tilepr */
235: register int curx, /* x coord of current vertex */
236: cury; /* y coord of current vertex */
237: int minx, /* smallest X */
238: miny, /* smallest Y */
239: maxx, /* greatest X */
240: maxy, /* greatest Y */
241: lastx, /* x coord of previous vertex */
242: lasty, /* y coord of previous vertex */
243: startx, /* x coord of first point in pgon */
244: starty; /* y coord of first point in pgon */
245: register Vertex *vp; /* current vertex */
246: register int cppts; /* # points in current polygon */
247: int tpts; /* total # of points in vertices */
248: int inpgon = 0; /* true if in a polygon */
249: int op; /* sun pr_ op */
250: int width, /* width of tilepr && pgons */
251: height; /* height of same */
252: int allmask = -1; /* all planes */
253: extern u_char Xstatus; /* return value for server */
254:
255: if ((PixRect->pr_depth == 1) && ! (zmask & 1))
256: return;
257:
258: vertices = (struct pr_pos *) calloc (vertcount, sizeof (struct pr_pos));
259: if (vertices == (struct pr_pos *) NULL) {
260: DeviceError ("Couldn't allocate array of vertices");
261: Xstatus = BadAlloc;
262: return;
263: }
264:
265: minx = -1;
266:
267: for (npgons = 0, vp = verts, tvert = vertices, tpts = cppts = 0;
268: vertcount != 0;
269: vertcount--, vp++) {
270: curx = vp->x; cury = vp->y;
271:
272: if (vp->flags & VertexRelative) {
273: curx += lastx; cury += lasty;
274: }
275: if (minx == -1) { /* all uninitialized */
276: minx = maxx = curx;
277: miny = maxy = cury;
278: } else {
279: if (curx < minx)
280: minx = curx;
281: else if (curx > maxx)
282: maxx = curx;
283:
284: if (cury < miny)
285: miny = cury;
286: else if (cury > maxy)
287: maxy = cury;
288: }
289:
290: if (vp->flags & VertexStartClosed) {
291: startx = curx;
292: starty = cury;
293: inpgon = 1;
294: }
295: if (vp->flags & VertexEndClosed) {
296: if (! inpgon || (curx != startx || cury != starty)) {
297: free (vertices);
298: DeviceError ("VertexEndClosed and either not in polygon or end doesn't match start");
299: Xstatus = BadValue;
300: return;
301: }
302: npts[npgons] = cppts;
303: npgons++;
304: cppts = 0;
305: inpgon = 0;
306:
307: if (npgons == MAXPOLYGONS) {
308: free (vertices);
309: DeviceError ("Too many vertices");
310: Xstatus = BadAlloc;
311: return;
312: }
313: continue;
314: }
315:
316: /*
317: * if not currently converting a polygon, this vertex has
318: * no business being here.
319: */
320: if (!inpgon)
321: continue;
322:
323: tvert->x = curx; tvert->y = cury;
324: tvert++; cppts++;
325: tpts++;
326: lastx = curx; lasty = cury;
327: }
328:
329: width = maxx - minx + 1;
330: height = maxy - miny + 1;
331:
332: tilepr = mem_create (width, height, PixRect->pr_depth);
333: pgons = mem_create (width, height, PixRect->pr_depth);
334:
335: if (tile != NULL) {
336: switch (tile->kind) {
337: case BitmapPixmap:
338: {
339: BITMAP *bm = (BITMAP *) tile->data;
340:
341: srcpr = mem_point (bm->width,
342: bm->height,
343: 1,
344: bm->data);
345: break;
346: }
347: case ConstantPixmap:
348: srcpr = (struct pixrect *) NULL;
349: srcpix = (int) tile->data;
350: break;
351: case XYColorPixmap:
352: /* ??? */
353: srcpr = (struct pixrect *) NULL;
354: srcpix = WhitePixel;
355: break;
356: case ZColorPixmap:
357: srcpr = mem_point (tile->width,
358: tile->height,
359: PixRect->pr_depth,
360: tile->data);
361: break;
362: }
363: } else {
364: srcpr = (struct pixrect *) NULL;
365: }
366:
367: for (tvert = vertices; tpts != 0; tvert++, tpts--) {
368: tvert->x -= minx;
369: tvert->y -= miny;
370: }
371:
372: xbase += minx;
373: ybase += miny;
374:
375: pr_rop (pgons, 0, 0, width, height, PIX_SRC | PIX_DONTCLIP,
376: PixRect, xbase, ybase);
377:
378: SetZmask (pgons, &zmask);
379:
380: op = SUN_FROM_X_OP(func) | PIX_DONTCLIP;
381:
382: if (srcpr != (struct pixrect *) NULL) {
383: pr_replrop (tilepr, 0, 0, width, height, PIX_SRC,
384: srcpr, xoff, yoff);
385: pr_destroy (srcpr);
386: pr_polygon_2 (pgons, 0, 0, npgons, npts, vertices,
387: op,
388: tilepr, 0, 0);
389: } else {
390: pr_polygon_2 (pgons, 0, 0, npgons, npts, vertices,
391: PIX_COLOR(srcpix) | op,
392: NULL, 0, 0);
393: }
394:
395: do {
396: int cleft, ctop, cwidth, cheight;
397:
398: GetNextClip (clips, cleft, ctop, cwidth, cheight);
399: if (OverLap (cleft, ctop, cwidth, cheight,
400: xbase, ybase, width, height)) {
401: int tleft = (cleft > xbase ? cleft : xbase);
402: int ttop = (ctop > ybase ? ctop : ybase);
403: int twidth = (cleft + cwidth < xbase + width ?
404: cleft + cwidth :
405: xbase + width) - tleft;
406: int theight = (ctop + cheight < ybase + height ?
407: ctop + cheight :
408: ybase + height) - ttop;
409:
410: CheckCursor (tleft, ttop, twidth, theight);
411: pr_rop (PixRect, tleft, ttop, twidth, theight,
412: PIX_SRC | PIX_DONTCLIP,
413: pgons, tleft - xbase, ttop - ybase);
414: }
415: } while (--clipcount);
416:
417: pr_destroy (pgons);
418: pr_destroy (tilepr);
419:
420: free (vertices);
421:
422: SetZmask (PixRect, &allmask);
423: RestoreCursor();
424: }
425: #endif sun
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.