Introduction
Introduction Statistics Contact Development Disclaimer Help
gcs.c - sam - An updated version of the sam text editor.
git clone git://vernunftzentrum.de/sam.git
Log
Files
Refs
LICENSE
---
gcs.c (11581B)
---
1 /* Copyright (c) 1998 Lucent Technologies - All rights reserved. */
2 #include <u.h>
3 #include <libg.h>
4 #include "libgint.h"
5
6 /*
7 * Libg applications are written assuming that black is ~0
8 * and white is 0. Some screens use the reverse convention.
9 * We get the effect the application desired by seeing what
10 * happens if both the source and dest are converted to the
11 * black==~0 convention, and then converting the dest back
12 * to whatever convention it uses.
13 *
14 * Offscreen bitmaps of depth 1 use the black==~0 convention.
15 *
16 * Bitmaps of depth > 1 are probably in color. Libg operations that
17 * would produce a 1 should produce the foreground color, and
18 * libg operations that would produce a 0 should produce the background
19 * color. Operations that use bitmaps of depth > 1 as source
20 * should interpret the foreground pixel as "black" (1) and the
21 * background pixel as "white" (0). It is hard to make this work,
22 * but the important cases are Fcodes Zero, F, S, and S^D, so
23 * we make sure that those work. When a fill value is given for
24 * a bitmap of depth > 1, assume ~0 means foreground, but otherwise
25 * take any other value literally (assume it came from rgbpix).
26 * This may be wrong for the case of 0, but libg programmers
27 * usually use Fcode Zero instead of passing 0 with Fcode S.
28 *
29 * We assume there are at most two depths of bitmaps: depth 1
30 * and depth of the screen.
31 */
32
33 /*
34 * gx func code corresponding to libg func code when both
35 * source and dest use 1 for black. This is a straight translation.
36 */
37 static int gx[16] = {
38 GXclear, /* Zero */
39 GXnor, /* DnorS */
40 GXandInverted, /* DandnotS */
41 GXcopyInverted, /* notS */
42 GXandReverse, /* notDandS */
43 GXinvert, /* notD */
44 GXxor, /* DxorS */
45 GXnand, /* DnandS */
46 GXand, /* DandS */
47 GXequiv, /* DxnorS */
48 GXnoop, /* D */
49 GXorInverted, /* DornotS */
50 GXcopy, /* S */
51 GXorReverse, /* notDorS */
52 GXor, /* DorS */
53 GXset, /* F */
54 };
55
56 /*
57 * gx func code corresponding to libg func code when 0 means black
58 * in dst and 1 means black in src. These means the table has op'
59 * where dst <- dst op' src == not ( not(dst) op src ).
60 * The comment on each line is op, in Fcode terms.
61 */
62 static int d0s1gx[16] = {
63 GXset, /* Zero */
64 GXorReverse, /* DnorS */
65 GXor, /* DandnotS */
66 GXcopy, /* notS */
67 GXnand, /* notDandS */
68 GXinvert, /* notD */
69 GXxor, /* DxorS */
70 GXandReverse, /* DnandS */
71 GXorInverted, /* DandS */
72 GXequiv, /* DxnorS */
73 GXnoop, /* D */
74 GXand, /* DornotS */
75 GXcopyInverted, /* S */
76 GXnor, /* notDorS */
77 GXandInverted, /* DorS */
78 GXclear, /* F */
79 };
80 /*
81 * gx func code corresponding to libg func code when 1 means black
82 * in dst and 0 means black in src. These means the table has op'
83 * where dst <- dst op' src == dst op not(src) )
84 * The comment on each line is op, in Fcode terms.
85 */
86 static int d1s0gx[16] = {
87 GXclear, /* Zero */
88 GXandReverse, /* DnorS */
89 GXand, /* DandnotS */
90 GXcopy, /* notS */
91 GXnor, /* notDandS */
92 GXinvert, /* notD */
93 GXequiv, /* DxorS */
94 GXorReverse, /* DnandS */
95 GXandInverted, /* DandS */
96 GXxor, /* DxnorS */
97 GXnoop, /* D */
98 GXor, /* DornotS */
99 GXcopyInverted, /* S */
100 GXnand, /* notDorS */
101 GXorInverted, /* DorS */
102 GXset, /* F */
103 };
104
105 /*
106 * gx func code corresponding to libg func code when 0 means black
107 * in both the src and the dst. These means the table has op'
108 * where dst <- dst op' src == not (not(dst) op not(src)) )
109 * The comment on each line is op, in Fcode terms.
110 */
111 static int d0s0gx[16] = {
112 GXset, /* Zero */
113 GXnand, /* DnorS */
114 GXorInverted, /* DandnotS */
115 GXcopyInverted, /* notS */
116 GXorReverse, /* notDandS */
117 GXinvert, /* notD */
118 GXequiv, /* DxorS */
119 GXnor, /* DnandS */
120 GXor, /* DandS */
121 GXxor, /* DxnorS */
122 GXnoop, /* D */
123 GXandInverted, /* DornotS */
124 GXcopy, /* S */
125 GXandReverse, /* notDorS */
126 GXand, /* DorS */
127 GXclear, /* F */
128 };
129
130 /*
131 * 1 for those Fcodes that are degenerate (don't involve src)
132 */
133 static int degengc[16] = {
134 1, /* Zero */
135 0, /* DnorS */
136 0, /* DandnotS */
137 0, /* notS */
138 0, /* notDandS */
139 1, /* notD */
140 0, /* DxorS */
141 0, /* DnandS */
142 0, /* DandS */
143 0, /* DxnorS */
144 1, /* D */
145 0, /* DornotS */
146 0, /* S */
147 0, /* notDorS */
148 0, /* DorS */
149 1, /* F */
150 };
151
152 /*
153 * GCs are all for same screen, and depth is either 1 or screen depth.
154 * Return a GC for the depth of b, with values as specified by gcv.
155 *
156 * Also, set (or unset) the clip rectangle if necessary.
157 * (This implementation should be improved if setting a clip rectangle i…
158 */
159 GC
160 _getgc(Bitmap *b, uint64_t gcvm, XGCValues *pgcv)
161 {
162 static GC gc0, gcn;
163 static bool clipset = false;
164 GC g;
165 XRectangle xr;
166
167 g = (b->ldepth==0)? gc0 : gcn;
168 if(!g){
169 g = XCreateGC(_dpy, (Drawable)b->id, gcvm, pgcv);
170 if(b->ldepth==0)
171 gc0 = g;
172 else
173 gcn = g;
174 } else
175 XChangeGC(_dpy, g, gcvm, pgcv);
176 if(b->flag&CLIP){
177 xr.x = b->clipr.min.x;
178 xr.y = b->clipr.min.y;
179 xr.width = Dx(b->clipr);
180 xr.height = Dy(b->clipr);
181 if(b->flag&SHIFT){
182 xr.x -= b->r.min.x;
183 xr.y -= b->r.min.y;
184 }
185 XSetClipRectangles(_dpy, g, 0, 0, &xr, 1, YXBanded);
186 clipset = true;
187 }else if(clipset){
188 pgcv->clip_mask = None;
189 XChangeGC(_dpy, g, GCClipMask, pgcv);
190 clipset = false;
191 }
192 return g;
193 }
194
195 /*
196 * Return a GC that will fill bitmap b using a pixel value v and Fcode f.
197 * Pixel value v is according to libg convention, so 0 means
198 * white (or background) and ~0 means black (or foreground).
199 */
200 GC
201 _getfillgc(Fcode f, Bitmap *b, uint64_t val)
202 {
203 return _getfillgc2(f, b, val, _fgpixel, _bgpixel);
204 }
205
206 GC
207 _getfillgc2(Fcode f, Bitmap *b, uint64_t val, uint64_t fg, uint64_t bg)
208 {
209 int xf, m;
210 uint64_t v, spix, vmax;
211 XGCValues gcv;
212
213 f &= F;
214 vmax = _ld2dmask[b->ldepth];
215 v = val & vmax;
216 spix = v;
217 xf = GXcopy;
218 m = b->flag;
219 if(m & DP1){
220 xf = (m&BL1)? gx[f] : d0s1gx[f];
221 }else{
222 switch(f){
223 case Zero:
224 labZero:
225 spix = bg;
226 break;
227 case F:
228 labF:
229 spix = fg;
230 break;
231 case D:
232 labD:
233 xf = GXnoop;
234 break;
235 case notD:
236 labnotD:
237 xf = GXxor;
238 spix = fg^bg;
239 break;
240 case S:
241 if(val == ~0)
242 spix = fg;
243 else
244 spix = v;
245 break;
246 case notS:
247 if(val == ~0)
248 spix = bg;
249 else
250 spix = v;
251 break;
252 case DxorS:
253 xf = GXxor;
254 if(val == ~0)
255 spix = fg^bg;
256 else
257 spix = v;
258 break;
259 case DxnorS:
260 xf = GXxor;
261 if(val == 0)
262 spix = fg^bg;
263 else
264 spix = v;
265 break;
266 default:
267 /* hard to do anything other than v==0 or v==~0 case */
268 if(v < vmax-v){
269 /* v is closer to 0 than vmax */
270 switch(f&~S){
271 case D&~S: goto labD;
272 case notD&~S: goto labnotD;
273 case Zero&~S: goto labZero;
274 case F&~S: goto labF;
275 }
276 }else{
277 /* v is closer to vmax than 0 */
278 switch(f&S){
279 case D&S: goto labD;
280 case notD&S: goto labnotD;
281 case Zero&S: goto labZero;
282 case F&S: goto labF;
283 }
284 }
285
286 }
287 }
288 gcv.foreground = spix;
289 gcv.function = xf;
290 return _getgc(b, GCForeground|GCFunction, &gcv);
291 }
292
293 /*
294 * Return a GC to be used to copy an area from bitmap sb to
295 * bitmap db. Sometimes the calling function shouldn't use
296 * XCopyArea, but instead should use XCopyPlane or XFillRectangle.
297 * The *bltfunc arg is set to one of UseCopyArea, UseCopyPlane,
298 * UseFillRectangle.
299 */
300 GC
301 _getcopygc(Fcode f, Bitmap *db, Bitmap *sb, int *bltfunc)
302 {
303 return _getcopygc2(f, db, sb, bltfunc, _fgpixel, _bgpixel);
304 }
305
306 GC
307 _getcopygc2(Fcode f, Bitmap *db, Bitmap *sb, int *bltfunc, uint64_t fg, …
308 {
309 uint64_t spix, df, sf;
310 int xf, c;
311 XGCValues gcv;
312 uint64_t gcvm;
313
314 spix = xf = 0;
315 f &= F;
316 gcvm = 0;
317 df = db->flag;
318 if(degengc[f]){
319 *bltfunc = UseFillRectangle;
320 if(df&SCR || !(df&DP1)){
321 // nothing XXX
322 }else{
323 /* must be DP1 and BL1 */
324 fg = 1;
325 bg = 0;
326 }
327 switch(f){
328 case Zero:
329 xf = GXcopy;
330 spix = bg;
331 break;
332 case F:
333 xf = GXcopy;
334 spix = fg;
335 break;
336 case D:
337 xf = GXnoop;
338 spix = fg;
339 break;
340 case notD:
341 xf = GXxor;
342 spix = fg^bg;
343 break;
344 default:
345 /* ignored */
346 break;
347 }
348 gcv.function = xf;
349 gcv.foreground = spix;
350 gcvm = GCFunction|GCForeground;
351 }else{
352 /* src is involved in f */
353
354 #define code(f1,f2) ((((f1)&(DP1|BL1))<<2)|((f2)&(DP1|BL1)))
355
356 sf = sb->flag;
357 c = code(df,sf);
358 *bltfunc = UseCopyArea;
359 switch(code(df,sf)){
360 case code(DP1|BL1,DP1|BL1):
361 case code(BL1,BL1):
362 xf = gx[f];
363 break;
364 case code(DP1|BL1,DP1):
365 xf = d1s0gx[f];
366 break;
367 case code(DP1,DP1|BL1):
368 xf = d0s1gx[f];
369 break;
370 case code(DP1,DP1):
371 case code(0,0):
372 xf = d0s0gx[f];
373 break;
374 default:
375 /*
376 * One bitmap has depth 1, the other has screen depth.
377 * We know the bitmap must have BL1.
378 * CopyPlane must be used; it won't really work
379 * for more than fcode==S.
380 */
381
382 *bltfunc = UseCopyPlane;
383 xf = GXcopy;
384 switch(c){
385
386 case code(0,DP1|BL1):
387 case code(BL1,DP1|BL1):
388 // nothing XXX
389 break;
390 case code(DP1|BL1,0):
391 fg = 0;
392 bg = 1;
393 break;
394 case code(DP1|BL1,BL1):
395 fg = 1;
396 bg = 0;
397 break;
398 default:
399 berror("bad combination of copy bitmaps");
400 }
401 gcv.foreground = fg;
402 gcv.background = bg;
403 gcvm |= GCForeground|GCBackground;
404 }
405 gcv.function = xf;
406 gcvm |= GCFunction;
407
408 #undef code
409 }
410
411 return _getgc(db, gcvm, &gcv);
412 }
You are viewing proxied material from vernunftzentrum.de. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.