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 */
DISScreenAdd(element,mask)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 */
DISScreenErase(element,mask)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 */
DISClearSetDisplay()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