Commit | Line | Data |
---|---|---|
7c1d219e | 1 | /* |
07ab5ed6 | 2 | * @(#)display.c 1.2 %G% |
7c1d219e MO |
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. | |
7c1d219e MO |
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 | ||
07ab5ed6 MO |
72 | /* determine bounds for this element */ |
73 | minsunx = maxsunx = dbx_to_win(element->ptlist->x); | |
74 | minsuny = maxsuny = dby_to_win(element->ptlist->y); | |
7c1d219e MO |
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 | ||
7c1d219e | 141 | x = minsunx - 8; |
7c1d219e | 142 | y = minsuny - 8; |
07ab5ed6 | 143 | width = maxsunx + 8 - x; |
7c1d219e | 144 | height = maxsuny + 8 - y; |
7c1d219e MO |
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); | |
7c1d219e MO |
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. | |
7c1d219e MO |
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. | |
7c1d219e MO |
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 */ |