1 /*
2  * @(#)display.c	1.2	01/03/85
3  *
4  * This file contains routines to implement the higher level display
5  * driver routines for the SUN Gremlin picture editor.
6  *
7  * Mark Opperman (opcode@monet.BERKELEY)
8  *
9  */
10 
11 #include <suntool/tool_hs.h>
12 #include "gremlin.h"
13 
14 /* imports from graphics.c */
15 
16 extern GRArc();
17 extern GRClear();
18 extern GRCurve();
19 extern GRCurrentSetOn();		/* force display of current set */
20 extern GRDisplayJustify();
21 extern GRNewElement();
22 extern GRPutText();
23 extern GRSetCurve();
24 extern GRSetLineStyle();
25 extern GRSetStippleStyle();
26 extern GRSetTextPos();
27 extern GRStippleFill();
28 extern GRVector();
29 
30 extern curve_set;			/* true if spline pre-computed */
31 
32 /* imports from main.c */
33 
34 extern struct pixwin *pix_pw;
35 extern struct rect pix_size;
36 extern struct pixrect *cset_pr;
37 extern struct pixrect *scratch_pr;
38 extern ELT *cset;
39 extern SHOWPOINTS;
40 extern SUN_XORIGIN;
41 extern SUN_YORIGIN;
42 
43 /* imports from long*.c */
44 
45 extern LGShowPoints();
46 
47 /* locals */
48 
49 int minsunx, maxsunx, minsuny, maxsuny;
50 
51 
52 /*
53  * This routine displays an arbitrary element type
54  * using the parameters stored with the element.
55  * Elements are drawn by Exclusive Oring the screen.
56  */
57 DISScreenAdd(element, mask)
58 register ELT *element;
59 int mask;
60 {
61     register POINT *p0, *p1, *p2;
62     POINT point;
63     register x, y, width, height;
64 
65     if (DBNullelt(element))
66 	return;
67 
68     /* clear scratch_pr */
69     pr_rop(scratch_pr, 0, 0, pix_size.r_width, pix_size.r_height,
70 						PIX_SRC, NULL, 0, 0);
71 
72     /* determine bounds for this element */
73     minsunx = maxsunx = dbx_to_win(element->ptlist->x);
74     minsuny = maxsuny = dby_to_win(element->ptlist->y);
75 
76     if (TEXT(element->type)) {
77 	GRSetTextPos(element->textpt, element->type, element->brushf,
78 			element->size, element->ptlist, &point);
79 	GRPutText(element->textpt, element->brushf, element->size,
80 			&point);
81 	if (mask & csetmask)	/* display justification marker */
82 	    GRDisplayJustify(element);
83     }
84     else {
85 	switch (element->type) {
86 	     case ARC:
87 		p1 = element->ptlist;
88 		p2 = PTNextPoint(p1);
89 		/* angle is stored in size */
90 		GRArc(p1, p2, (float) element->size, element->brushf);
91 		break;
92 	    case CURVE:
93 		if (!curve_set)
94 		    GRSetCurve(element->ptlist);
95 		GRCurve(element->brushf);
96 		curve_set = 0;
97 		break;
98 	    case POLYGON:
99 		if (element->brushf != 0) {	/* bordered polygon */
100 		    p0 = p1 = element->ptlist;
101 		    p2 = PTNextPoint(p1);
102 		    GRSetLineStyle(element->brushf);
103 
104 		    while (!Nullpoint(p2)) {
105 			GRVector(p1->x, p1->y, p2->x, p2->y);
106 			p1 = p2;
107 			p2 = PTNextPoint(p2);
108 		    }
109 
110 		    /* if last point not specified, join end points */
111 		    if ((p0->x != p1->x) || (p0->y != p1->y))
112 			    GRVector(p1->x, p1->y, p0->x, p0->y);
113 		}
114 		else {		/* unbordered: find min/max */
115 		    p0 = element->ptlist;
116 
117 		    while (!Nullpoint(p0)) {
118 			MINMAX(minsunx, maxsunx, dbx_to_win(p0->x));
119 			MINMAX(minsuny, maxsuny, dby_to_win(p0->y));
120 			p0 = PTNextPoint(p0);
121 		    }
122 		}
123 
124 		GRSetStippleStyle(element->size);
125 		GRStippleFill(element->ptlist);
126 		break;
127 	    case VECTOR:
128 		p1 = element->ptlist;
129 		p2 = PTNextPoint(p1);
130 		GRSetLineStyle(element->brushf);
131 
132 		while (!Nullpoint(p2)) {
133 		    GRVector(p1->x, p1->y, p2->x, p2->y);
134 		    p1 = p2;
135 		    p2 = PTNextPoint(p2);
136 		}
137 		break;
138 	}
139     }
140 
141     x = minsunx - 8;
142     y = minsuny - 8;
143     width = maxsunx + 8 - x;
144     height = maxsuny + 8 - y;
145 
146     if (mask & pixmask)
147 	pw_write(pix_pw, x, y, width, height, PIX_SRC ^ PIX_DST,
148 						    scratch_pr, x, y);
149 
150     if (mask & csetmask)
151 	pr_rop(cset_pr, x, y, width, height, PIX_SRC ^ PIX_DST,
152 						    scratch_pr, x, y);
153 }  /* end DISScreenAdd */
154 
155 
156 /*
157  * This routine erases an arbitrary element type by redrawing the
158  * element with XOR.  This is the same as drawing the element.
159  */
160 DISScreenErase(element, mask)
161 register ELT *element;
162 register mask;
163 {
164     DISScreenAdd(element, mask);
165 }  /* end ScreenErase */
166 
167 
168 /*
169  * This routine clears the current set pixrect.
170  */
171 DISClearSetDisplay()
172 {
173     register ELT *elist;
174 
175     GRCurrentSetOn();
176 
177     if (SHOWPOINTS)
178 	LGShowPoints();
179 
180     elist = cset;
181     while (!DBNullelt(elist)) {
182 	if (TEXT(elist->type))		/* turn off text handle */
183 	    GRDisplayJustify(elist);
184 	elist = DBNextofSet(elist);
185     }
186 
187     GRClear(csetmask);
188 }  /* end DISClearSetDisplay */
189