|
|
1.1 root 1: #include <u.h>
2: #include <libg.h>
3: #include <gnot.h>
4:
5: #define PSHIFT(x, y) {if(LENDIAN) x <<= y; else x >>= y;}
6:
7: int
8: _setdda(int x, int y, Linedesc *l)
9: {
10: int e;
11:
12: /*
13: * Unfold all the symmetry folded out in gsetline()
14: */
15: if(l->slopeneg == 0)
16: e = ((2*(x-l->x0)+2)*l->dminor
17: -(2*(y-l->y0)+1)*l->dmajor);
18: else{
19: if(l->xmajor)
20: e = ((2*(x-l->x0)+2)*l->dminor
21: +(2*(l->y0+y)-1)*l->dmajor);
22: else
23: e = ((2*(l->x0-x)+2)*l->dminor
24: -(2*(l->y0+y)+1)*l->dmajor)-1;
25: }
26: return e;
27: }
28:
29: /*
30: * Strange, usually fast line code.
31: * Based on the observation that given src and f, src is constant
32: * for the call, so we can reduce f by that symmetry. Then we can
33: * reduce it again by choosing the src we actually run with; thus
34: * src, f -> src', f'
35: * In the code, src is replicated through the register m.
36: * The f's we choose (they are somewhat arbitrary) are
37: * f(0) = S & D
38: * and
39: * f(1) = S | ~D,
40: * chosen by the bits of the incoming f. In particular, if
41: * src == 0
42: * we select
43: * f' = f&1, src' = (f&2) >> 1
44: * else
45: * f' = (f>>2)&1, src' = ((f>>2)&2) >> 1
46: * If src is all 1's or all 0's (guaranteed true on a 1-bit display),
47: * this is all we need; otherwise (the slower case) we insert into the dest
48: * twice: once for the 1 bits in src, once for the 0 bits, using f' and src'
49: * each computed as above.
50: */
51:
52: void
53: gsegment(GBitmap *b, Point p, Point q, int src, Fcode f)
54: {
55: int i, dw, dx, dy;
56: int e, e1, e2;
57: uchar m, m1, k, k0, k1, f0, f1, lom, him, him0, him1, t, *dest;
58: int ld, bpp, xshift;
59: int m0, lo, lo0, lo1, kk, kk0, kk1;
60: Linedesc l;
61:
62: if(!_clipline(b->clipr, &p, &q, &l))
63: return;
64: /* line is now clipped and closed */
65: dx = q.x - p.x;
66: dy = q.y - p.y;
67: if(dx < 0) /* can't happen, but breaks code if it does */
68: return;
69:
70: ld = b->ldepth;
71: bpp = 8>>(3-ld);
72: lom = ((1<<bpp)-1);
73: him = lom<<(8-bpp);
74: xshift = (p.x&(7>>ld))<<ld;
75: if(LENDIAN)
76: xshift = 8-bpp - xshift;
77: k = him>>xshift; /* mask */
78: lo = src&lom;
79:
80: if(lo==lom || lo==0){
81: /*
82: * set new f, new src
83: */
84: if(lo)
85: f >>= 2;
86: f &= 3;
87: if(f & 2)
88: lo = lom;
89: else
90: lo = 0;
91: f &= 1;
92: /*
93: * develop m as a register full of pixels containing 'lo1'
94: */
95: m = lo;
96: for(i=1<<ld; i<8; i+=i)
97: m |= m<<i;
98: }else{
99: /*
100: * set *1 for 1 bits; *0 for 0 bits
101: */
102: f1 = (f>>2)&3;
103: if(f1 & 2)
104: lo1 = lom & lo;
105: else
106: lo1 = 0;
107: f1 &= 1;
108: him1 = (lom&lo)<<(8-bpp);
109: k1 = him1>>xshift; /* mask */
110: f0 = f&3;
111: if(f0 & 2)
112: lo0 = lom & ~lo;
113: else
114: lo0 = 0;
115: f0 &= 1;
116: him0 = (lom&~lo)<<(8-bpp);
117: k0 = him0>>xshift; /* mask */
118: /*
119: * develop m0, m1 as a register full of pixels containing 'lo1'
120: */
121: m0 = lo0;
122: m1 = lo1;
123: for(i=1<<ld; i<8; i+=i){
124: m0 |= m0<<i;
125: m1 |= m1<<i;
126: }
127: f = 2;
128: }
129:
130: if(LENDIAN){
131: him >>= 8-bpp;
132: him0 >>= 8-bpp;
133: him1 >>= 8-bpp;
134: }
135:
136: dw = b->width*sizeof(ulong);
137: if(dy < 0){
138: dw = -dw;
139: dy = -dy;
140: }
141: dest = (uchar*)gaddr(b, p) + ((p.x&(31>>ld))>>(3-ld));
142: e1 = 2*l.dminor;
143: e2 = e1 - 2*l.dmajor;
144: if(l.xmajor == 0)
145: goto majory;
146:
147: majorx:
148: e = _setdda(p.x, p.y, &l);
149: switch(f){
150: case 0:
151: kk = 0;
152: for(i=dx; i>=0; i--){
153: kk |= k;
154: PSHIFT(k, bpp);
155: if(e >= 0){
156: *dest &= m|~kk;
157: dest += dw;
158: e += e2;
159: kk = 0;
160: if(k == 0){
161: k = him;
162: dest++;
163: }
164: continue;
165: }
166: e += e1;
167: if(k == 0){
168: k = him;
169: *dest &= m|~kk;
170: dest++;
171: kk = 0;
172: }
173: }
174: if(kk)
175: *dest &= m|~kk;
176: return;
177:
178: case 1:
179: kk = 0;
180: for(i=dx; i>=0; i--){
181: kk |= k;
182: PSHIFT(k, bpp);
183: if(e >= 0){
184: t = *dest;
185: *dest = (kk ^ t) | (t & m);
186: dest += dw;
187: e += e2;
188: kk = 0;
189: if(k == 0){
190: k = him;
191: dest++;
192: }
193: continue;
194: }
195: e += e1;
196: if(k == 0){
197: t = *dest;
198: *dest = (kk ^ t) | (t & m);
199: dest++;
200: k = him;
201: kk = 0;
202: }
203: }
204: if(kk){
205: t = *dest;
206: *dest = (kk ^ t) | (t & m);
207: }
208: return;
209:
210: case 2:
211: kk = 0;
212: kk0 = 0;
213: kk1 = 0;
214: for(i=dx; i>=0; i--){
215: kk |= k;
216: kk0 |= k0;
217: kk1 |= k1;
218: PSHIFT(k, bpp);
219: PSHIFT(k0, bpp);
220: PSHIFT(k1, bpp);
221: if(e >= 0){
222: t = *dest;
223: if(f0 == 0)
224: t &= m0|~kk0;
225: else
226: t = (kk0 ^ t) | (t & m0);
227: if(f1 == 0)
228: *dest = t & (m1|~kk1);
229: else
230: *dest = (kk1 ^ t) | (t & m1);
231: dest += dw;
232: e += e2;
233: kk = 0;
234: kk0 = 0;
235: kk1 = 0;
236: if(k == 0){
237: k = him;
238: k0 = him0;
239: k1 = him1;
240: dest++;
241: }
242: continue;
243: }
244: e += e1;
245: if(k == 0){
246: t = *dest;
247: if(f0 == 0)
248: t &= m0|~kk0;
249: else
250: t = (kk0 ^ t) | (t & m0);
251: if(f1 == 0)
252: *dest = t & (m1|~kk1);
253: else
254: *dest = (kk1 ^ t) | (t & m1);
255: dest++;
256: k = him;
257: k0 = him0;
258: k1 = him1;
259: kk = 0;
260: kk0 = 0;
261: kk1 = 0;
262: }
263: }
264: if(kk){
265: t = *dest;
266: if(f0 == 0)
267: t &= m0|~kk0;
268: else
269: t = (kk0 ^ t) | (t & m0);
270: if(f1 == 0)
271: *dest = t & (m1|~kk1);
272: else
273: *dest = (kk1 ^ t) | (t & m1);
274: }
275: return;
276: }
277: return;
278:
279: majory:
280: e = _setdda(p.y, p.x, &l);
281: switch (f){
282: case 0:
283: for(i=dy; i>=0; --i){
284: *dest &= m|~k;
285: dest += dw;
286: if(e >= 0){
287: PSHIFT(k, bpp);
288: if(k == 0){
289: dest++;
290: k = him;
291: }
292: e += e2;
293: }else
294: e += e1;
295: }
296: return;
297:
298: case 1:
299: for(i=dy; i>=0; --i){
300: t = *dest;
301: *dest = (k ^ t) | (t & m);
302: dest += dw;
303: if(e >= 0){
304: PSHIFT(k, bpp);
305: if(k == 0){
306: dest++;
307: k = him;
308: }
309: e += e2;
310: }else
311: e += e1;
312: }
313: return;
314:
315: case 2:
316: for(i=dy; i>=0; --i){
317: t = *dest;
318: if(f0 == 0)
319: t &= m0|~k0;
320: else
321: t = (k0 ^ t) | (t & m0);
322: if(f1 == 0)
323: *dest = t & (m1|~k1);
324: else
325: *dest = (k1 ^ t) | (t & m1);
326: dest += dw;
327: if(e >= 0){
328: PSHIFT(k, bpp);
329: PSHIFT(k0, bpp);
330: PSHIFT(k1, bpp);
331: if(k == 0){
332: dest++;
333: k = him;
334: k0 = him0;
335: k1 = him1;
336: }
337: e += e2;
338: }else
339: e += e1;
340: }
341: }
342: return;
343: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.