Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /* |
2 | * Copyright © 1998 Keith Packard | |
3 | * | |
4 | * Permission to use, copy, modify, distribute, and sell this software and its | |
5 | * documentation for any purpose is hereby granted without fee, provided that | |
6 | * the above copyright notice appear in all copies and that both that | |
7 | * copyright notice and this permission notice appear in supporting | |
8 | * documentation, and that the name of Keith Packard not be used in | |
9 | * advertising or publicity pertaining to distribution of the software without | |
10 | * specific, written prior permission. Keith Packard makes no | |
11 | * representations about the suitability of this software for any purpose. It | |
12 | * is provided "as is" without express or implied warranty. | |
13 | * | |
14 | * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |
16 | * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR | |
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | |
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
20 | * PERFORMANCE OF THIS SOFTWARE. | |
21 | */ | |
22 | ||
23 | /* | |
24 | * This file defines functions for drawing some primitives using | |
25 | * underlying datatypes instead of masks | |
26 | */ | |
27 | ||
28 | #define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000) | |
29 | ||
30 | #ifdef HAVE_DIX_CONFIG_H | |
31 | #include <dix-config.h> | |
32 | #endif | |
33 | ||
34 | #ifdef BITSMUL | |
35 | #define MUL BITSMUL | |
36 | #else | |
37 | #define MUL 1 | |
38 | #endif | |
39 | ||
40 | #ifdef BITSSTORE | |
41 | #define STORE(b,x) BITSSTORE(b,x) | |
42 | #else | |
43 | #define STORE(b,x) WRITE((b), (x)) | |
44 | #endif | |
45 | ||
46 | #ifdef BITSRROP | |
47 | #define RROP(b,a,x) BITSRROP(b,a,x) | |
48 | #else | |
49 | #define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x))) | |
50 | #endif | |
51 | ||
52 | #ifdef BITSUNIT | |
53 | #define UNIT BITSUNIT | |
54 | #define USE_SOLID | |
55 | #else | |
56 | #define UNIT BITS | |
57 | #endif | |
58 | ||
59 | /* | |
60 | * Define the following before including this file: | |
61 | * | |
62 | * BRESSOLID name of function for drawing a solid segment | |
63 | * BRESDASH name of function for drawing a dashed segment | |
64 | * DOTS name of function for drawing dots | |
65 | * ARC name of function for drawing a solid arc | |
66 | * BITS type of underlying unit | |
67 | */ | |
68 | ||
69 | #ifdef BRESSOLID | |
70 | void | |
71 | BRESSOLID(DrawablePtr pDrawable, | |
72 | GCPtr pGC, | |
73 | int dashOffset, | |
74 | int signdx, | |
75 | int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len) | |
76 | { | |
77 | FbBits *dst; | |
78 | FbStride dstStride; | |
79 | int dstBpp; | |
80 | int dstXoff, dstYoff; | |
81 | FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); | |
82 | UNIT *bits; | |
83 | FbStride bitsStride; | |
84 | FbStride majorStep, minorStep; | |
85 | BITS xor = (BITS) pPriv->xor; | |
86 | ||
87 | fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); | |
88 | bits = | |
89 | ((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff) * MUL; | |
90 | bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT)); | |
91 | if (signdy < 0) | |
92 | bitsStride = -bitsStride; | |
93 | if (axis == X_AXIS) { | |
94 | majorStep = signdx * MUL; | |
95 | minorStep = bitsStride; | |
96 | } | |
97 | else { | |
98 | majorStep = bitsStride; | |
99 | minorStep = signdx * MUL; | |
100 | } | |
101 | while (len--) { | |
102 | STORE(bits, xor); | |
103 | bits += majorStep; | |
104 | e += e1; | |
105 | if (e >= 0) { | |
106 | bits += minorStep; | |
107 | e += e3; | |
108 | } | |
109 | } | |
110 | ||
111 | fbFinishAccess(pDrawable); | |
112 | } | |
113 | #endif | |
114 | ||
115 | #ifdef BRESDASH | |
116 | void | |
117 | BRESDASH(DrawablePtr pDrawable, | |
118 | GCPtr pGC, | |
119 | int dashOffset, | |
120 | int signdx, | |
121 | int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len) | |
122 | { | |
123 | FbBits *dst; | |
124 | FbStride dstStride; | |
125 | int dstBpp; | |
126 | int dstXoff, dstYoff; | |
127 | FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); | |
128 | UNIT *bits; | |
129 | FbStride bitsStride; | |
130 | FbStride majorStep, minorStep; | |
131 | BITS xorfg, xorbg; | |
132 | ||
133 | FbDashDeclare; | |
134 | int dashlen; | |
135 | Bool even; | |
136 | Bool doOdd; | |
137 | ||
138 | fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); | |
139 | doOdd = pGC->lineStyle == LineDoubleDash; | |
140 | xorfg = (BITS) pPriv->xor; | |
141 | xorbg = (BITS) pPriv->bgxor; | |
142 | ||
143 | FbDashInit(pGC, pPriv, dashOffset, dashlen, even); | |
144 | ||
145 | bits = | |
146 | ((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff) * MUL; | |
147 | bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT)); | |
148 | if (signdy < 0) | |
149 | bitsStride = -bitsStride; | |
150 | if (axis == X_AXIS) { | |
151 | majorStep = signdx * MUL; | |
152 | minorStep = bitsStride; | |
153 | } | |
154 | else { | |
155 | majorStep = bitsStride; | |
156 | minorStep = signdx * MUL; | |
157 | } | |
158 | if (dashlen >= len) | |
159 | dashlen = len; | |
160 | if (doOdd) { | |
161 | if (!even) | |
162 | goto doubleOdd; | |
163 | for (;;) { | |
164 | len -= dashlen; | |
165 | while (dashlen--) { | |
166 | STORE(bits, xorfg); | |
167 | bits += majorStep; | |
168 | if ((e += e1) >= 0) { | |
169 | e += e3; | |
170 | bits += minorStep; | |
171 | } | |
172 | } | |
173 | if (!len) | |
174 | break; | |
175 | ||
176 | FbDashNextEven(dashlen); | |
177 | ||
178 | if (dashlen >= len) | |
179 | dashlen = len; | |
180 | doubleOdd: | |
181 | len -= dashlen; | |
182 | while (dashlen--) { | |
183 | STORE(bits, xorbg); | |
184 | bits += majorStep; | |
185 | if ((e += e1) >= 0) { | |
186 | e += e3; | |
187 | bits += minorStep; | |
188 | } | |
189 | } | |
190 | if (!len) | |
191 | break; | |
192 | ||
193 | FbDashNextOdd(dashlen); | |
194 | ||
195 | if (dashlen >= len) | |
196 | dashlen = len; | |
197 | } | |
198 | } | |
199 | else { | |
200 | if (!even) | |
201 | goto onOffOdd; | |
202 | for (;;) { | |
203 | len -= dashlen; | |
204 | while (dashlen--) { | |
205 | STORE(bits, xorfg); | |
206 | bits += majorStep; | |
207 | if ((e += e1) >= 0) { | |
208 | e += e3; | |
209 | bits += minorStep; | |
210 | } | |
211 | } | |
212 | if (!len) | |
213 | break; | |
214 | ||
215 | FbDashNextEven(dashlen); | |
216 | ||
217 | if (dashlen >= len) | |
218 | dashlen = len; | |
219 | onOffOdd: | |
220 | len -= dashlen; | |
221 | while (dashlen--) { | |
222 | bits += majorStep; | |
223 | if ((e += e1) >= 0) { | |
224 | e += e3; | |
225 | bits += minorStep; | |
226 | } | |
227 | } | |
228 | if (!len) | |
229 | break; | |
230 | ||
231 | FbDashNextOdd(dashlen); | |
232 | ||
233 | if (dashlen >= len) | |
234 | dashlen = len; | |
235 | } | |
236 | } | |
237 | ||
238 | fbFinishAccess(pDrawable); | |
239 | } | |
240 | #endif | |
241 | ||
242 | #ifdef DOTS | |
243 | void | |
244 | DOTS(FbBits * dst, | |
245 | FbStride dstStride, | |
246 | int dstBpp, | |
247 | BoxPtr pBox, | |
248 | xPoint * ptsOrig, | |
249 | int npt, int xorg, int yorg, int xoff, int yoff, FbBits and, FbBits xor) | |
250 | { | |
251 | INT32 *pts = (INT32 *) ptsOrig; | |
252 | UNIT *bits = (UNIT *) dst; | |
253 | UNIT *point; | |
254 | BITS bxor = (BITS) xor; | |
255 | BITS band = (BITS) and; | |
256 | FbStride bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT)); | |
257 | INT32 ul, lr; | |
258 | INT32 pt; | |
259 | ||
260 | ul = coordToInt(pBox->x1 - xorg, pBox->y1 - yorg); | |
261 | lr = coordToInt(pBox->x2 - xorg - 1, pBox->y2 - yorg - 1); | |
262 | ||
263 | bits += bitsStride * (yorg + yoff) + (xorg + xoff) * MUL; | |
264 | ||
265 | if (and == 0) { | |
266 | while (npt--) { | |
267 | pt = *pts++; | |
268 | if (!isClipped(pt, ul, lr)) { | |
269 | point = bits + intToY(pt) * bitsStride + intToX(pt) * MUL; | |
270 | STORE(point, bxor); | |
271 | } | |
272 | } | |
273 | } | |
274 | else { | |
275 | while (npt--) { | |
276 | pt = *pts++; | |
277 | if (!isClipped(pt, ul, lr)) { | |
278 | point = bits + intToY(pt) * bitsStride + intToX(pt) * MUL; | |
279 | RROP(point, band, bxor); | |
280 | } | |
281 | } | |
282 | } | |
283 | } | |
284 | #endif | |
285 | ||
286 | #ifdef ARC | |
287 | ||
288 | #define ARCCOPY(d) STORE(d,xorBits) | |
289 | #define ARCRROP(d) RROP(d,andBits,xorBits) | |
290 | ||
291 | void | |
292 | ARC(FbBits * dst, | |
293 | FbStride dstStride, | |
294 | int dstBpp, xArc * arc, int drawX, int drawY, FbBits and, FbBits xor) | |
295 | { | |
296 | UNIT *bits; | |
297 | FbStride bitsStride; | |
298 | miZeroArcRec info; | |
299 | Bool do360; | |
300 | int x; | |
301 | UNIT *yorgp, *yorgop; | |
302 | BITS andBits, xorBits; | |
303 | int yoffset, dyoffset; | |
304 | int y, a, b, d, mask; | |
305 | int k1, k3, dx, dy; | |
306 | ||
307 | bits = (UNIT *) dst; | |
308 | bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT)); | |
309 | andBits = (BITS) and; | |
310 | xorBits = (BITS) xor; | |
311 | do360 = miZeroArcSetup(arc, &info, TRUE); | |
312 | yorgp = bits + ((info.yorg + drawY) * bitsStride); | |
313 | yorgop = bits + ((info.yorgo + drawY) * bitsStride); | |
314 | info.xorg = (info.xorg + drawX) * MUL; | |
315 | info.xorgo = (info.xorgo + drawX) * MUL; | |
316 | MIARCSETUP(); | |
317 | yoffset = y ? bitsStride : 0; | |
318 | dyoffset = 0; | |
319 | mask = info.initialMask; | |
320 | ||
321 | if (!(arc->width & 1)) { | |
322 | if (andBits == 0) { | |
323 | if (mask & 2) | |
324 | ARCCOPY(yorgp + info.xorgo); | |
325 | if (mask & 8) | |
326 | ARCCOPY(yorgop + info.xorgo); | |
327 | } | |
328 | else { | |
329 | if (mask & 2) | |
330 | ARCRROP(yorgp + info.xorgo); | |
331 | if (mask & 8) | |
332 | ARCRROP(yorgop + info.xorgo); | |
333 | } | |
334 | } | |
335 | if (!info.end.x || !info.end.y) { | |
336 | mask = info.end.mask; | |
337 | info.end = info.altend; | |
338 | } | |
339 | if (do360 && (arc->width == arc->height) && !(arc->width & 1)) { | |
340 | int xoffset = bitsStride; | |
341 | UNIT *yorghb = yorgp + (info.h * bitsStride) + info.xorg; | |
342 | UNIT *yorgohb = yorghb - info.h * MUL; | |
343 | ||
344 | yorgp += info.xorg; | |
345 | yorgop += info.xorg; | |
346 | yorghb += info.h * MUL; | |
347 | while (1) { | |
348 | if (andBits == 0) { | |
349 | ARCCOPY(yorgp + yoffset + x * MUL); | |
350 | ARCCOPY(yorgp + yoffset - x * MUL); | |
351 | ARCCOPY(yorgop - yoffset - x * MUL); | |
352 | ARCCOPY(yorgop - yoffset + x * MUL); | |
353 | } | |
354 | else { | |
355 | ARCRROP(yorgp + yoffset + x * MUL); | |
356 | ARCRROP(yorgp + yoffset - x * MUL); | |
357 | ARCRROP(yorgop - yoffset - x * MUL); | |
358 | ARCRROP(yorgop - yoffset + x * MUL); | |
359 | } | |
360 | if (a < 0) | |
361 | break; | |
362 | if (andBits == 0) { | |
363 | ARCCOPY(yorghb - xoffset - y * MUL); | |
364 | ARCCOPY(yorgohb - xoffset + y * MUL); | |
365 | ARCCOPY(yorgohb + xoffset + y * MUL); | |
366 | ARCCOPY(yorghb + xoffset - y * MUL); | |
367 | } | |
368 | else { | |
369 | ARCRROP(yorghb - xoffset - y * MUL); | |
370 | ARCRROP(yorgohb - xoffset + y * MUL); | |
371 | ARCRROP(yorgohb + xoffset + y * MUL); | |
372 | ARCRROP(yorghb + xoffset - y * MUL); | |
373 | } | |
374 | xoffset += bitsStride; | |
375 | MIARCCIRCLESTEP(yoffset += bitsStride; | |
376 | ); | |
377 | } | |
378 | yorgp -= info.xorg; | |
379 | yorgop -= info.xorg; | |
380 | x = info.w; | |
381 | yoffset = info.h * bitsStride; | |
382 | } | |
383 | else if (do360) { | |
384 | while (y < info.h || x < info.w) { | |
385 | MIARCOCTANTSHIFT(dyoffset = bitsStride; | |
386 | ); | |
387 | if (andBits == 0) { | |
388 | ARCCOPY(yorgp + yoffset + info.xorg + x * MUL); | |
389 | ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL); | |
390 | ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL); | |
391 | ARCCOPY(yorgop - yoffset + info.xorg + x * MUL); | |
392 | } | |
393 | else { | |
394 | ARCRROP(yorgp + yoffset + info.xorg + x * MUL); | |
395 | ARCRROP(yorgp + yoffset + info.xorgo - x * MUL); | |
396 | ARCRROP(yorgop - yoffset + info.xorgo - x * MUL); | |
397 | ARCRROP(yorgop - yoffset + info.xorg + x * MUL); | |
398 | } | |
399 | MIARCSTEP(yoffset += dyoffset; | |
400 | , yoffset += bitsStride; | |
401 | ); | |
402 | } | |
403 | } | |
404 | else { | |
405 | while (y < info.h || x < info.w) { | |
406 | MIARCOCTANTSHIFT(dyoffset = bitsStride; | |
407 | ); | |
408 | if ((x == info.start.x) || (y == info.start.y)) { | |
409 | mask = info.start.mask; | |
410 | info.start = info.altstart; | |
411 | } | |
412 | if (andBits == 0) { | |
413 | if (mask & 1) | |
414 | ARCCOPY(yorgp + yoffset + info.xorg + x * MUL); | |
415 | if (mask & 2) | |
416 | ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL); | |
417 | if (mask & 4) | |
418 | ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL); | |
419 | if (mask & 8) | |
420 | ARCCOPY(yorgop - yoffset + info.xorg + x * MUL); | |
421 | } | |
422 | else { | |
423 | if (mask & 1) | |
424 | ARCRROP(yorgp + yoffset + info.xorg + x * MUL); | |
425 | if (mask & 2) | |
426 | ARCRROP(yorgp + yoffset + info.xorgo - x * MUL); | |
427 | if (mask & 4) | |
428 | ARCRROP(yorgop - yoffset + info.xorgo - x * MUL); | |
429 | if (mask & 8) | |
430 | ARCRROP(yorgop - yoffset + info.xorg + x * MUL); | |
431 | } | |
432 | if ((x == info.end.x) || (y == info.end.y)) { | |
433 | mask = info.end.mask; | |
434 | info.end = info.altend; | |
435 | } | |
436 | MIARCSTEP(yoffset += dyoffset; | |
437 | , yoffset += bitsStride; | |
438 | ); | |
439 | } | |
440 | } | |
441 | if ((x == info.start.x) || (y == info.start.y)) | |
442 | mask = info.start.mask; | |
443 | if (andBits == 0) { | |
444 | if (mask & 1) | |
445 | ARCCOPY(yorgp + yoffset + info.xorg + x * MUL); | |
446 | if (mask & 4) | |
447 | ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL); | |
448 | if (arc->height & 1) { | |
449 | if (mask & 2) | |
450 | ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL); | |
451 | if (mask & 8) | |
452 | ARCCOPY(yorgop - yoffset + info.xorg + x * MUL); | |
453 | } | |
454 | } | |
455 | else { | |
456 | if (mask & 1) | |
457 | ARCRROP(yorgp + yoffset + info.xorg + x * MUL); | |
458 | if (mask & 4) | |
459 | ARCRROP(yorgop - yoffset + info.xorgo - x * MUL); | |
460 | if (arc->height & 1) { | |
461 | if (mask & 2) | |
462 | ARCRROP(yorgp + yoffset + info.xorgo - x * MUL); | |
463 | if (mask & 8) | |
464 | ARCRROP(yorgop - yoffset + info.xorg + x * MUL); | |
465 | } | |
466 | } | |
467 | } | |
468 | ||
469 | #undef ARCCOPY | |
470 | #undef ARCRROP | |
471 | #endif | |
472 | ||
473 | #ifdef GLYPH | |
474 | #if BITMAP_BIT_ORDER == LSBFirst | |
475 | #define WRITE_ADDR1(n) (n) | |
476 | #define WRITE_ADDR2(n) (n) | |
477 | #define WRITE_ADDR4(n) (n) | |
478 | #else | |
479 | #define WRITE_ADDR1(n) ((n) ^ 3) | |
480 | #define WRITE_ADDR2(n) ((n) ^ 2) | |
481 | #define WRITE_ADDR4(n) ((n)) | |
482 | #endif | |
483 | ||
484 | #define WRITE1(d,n,fg) WRITE(d + WRITE_ADDR1(n), (BITS) (fg)) | |
485 | ||
486 | #ifdef BITS2 | |
487 | #define WRITE2(d,n,fg) WRITE((BITS2 *) &((d)[WRITE_ADDR2(n)]), (BITS2) (fg)) | |
488 | #else | |
489 | #define WRITE2(d,n,fg) (WRITE1(d,n,fg), WRITE1(d,(n)+1,fg)) | |
490 | #endif | |
491 | ||
492 | #ifdef BITS4 | |
493 | #define WRITE4(d,n,fg) WRITE((BITS4 *) &((d)[WRITE_ADDR4(n)]), (BITS4) (fg)) | |
494 | #else | |
495 | #define WRITE4(d,n,fg) (WRITE2(d,n,fg), WRITE2(d,(n)+2,fg)) | |
496 | #endif | |
497 | ||
498 | void | |
499 | GLYPH(FbBits * dstBits, | |
500 | FbStride dstStride, | |
501 | int dstBpp, FbStip * stipple, FbBits fg, int x, int height) | |
502 | { | |
503 | int lshift; | |
504 | FbStip bits; | |
505 | BITS *dstLine; | |
506 | BITS *dst; | |
507 | int n; | |
508 | int shift; | |
509 | ||
510 | dstLine = (BITS *) dstBits; | |
511 | dstLine += x & ~3; | |
512 | dstStride *= (sizeof(FbBits) / sizeof(BITS)); | |
513 | shift = x & 3; | |
514 | lshift = 4 - shift; | |
515 | while (height--) { | |
516 | bits = *stipple++; | |
517 | dst = (BITS *) dstLine; | |
518 | n = lshift; | |
519 | while (bits) { | |
520 | switch (FbStipMoveLsb(FbLeftStipBits(bits, n), 4, n)) { | |
521 | case 0: | |
522 | break; | |
523 | case 1: | |
524 | WRITE1(dst, 0, fg); | |
525 | break; | |
526 | case 2: | |
527 | WRITE1(dst, 1, fg); | |
528 | break; | |
529 | case 3: | |
530 | WRITE2(dst, 0, fg); | |
531 | break; | |
532 | case 4: | |
533 | WRITE1(dst, 2, fg); | |
534 | break; | |
535 | case 5: | |
536 | WRITE1(dst, 0, fg); | |
537 | WRITE1(dst, 2, fg); | |
538 | break; | |
539 | case 6: | |
540 | WRITE1(dst, 1, fg); | |
541 | WRITE1(dst, 2, fg); | |
542 | break; | |
543 | case 7: | |
544 | WRITE2(dst, 0, fg); | |
545 | WRITE1(dst, 2, fg); | |
546 | break; | |
547 | case 8: | |
548 | WRITE1(dst, 3, fg); | |
549 | break; | |
550 | case 9: | |
551 | WRITE1(dst, 0, fg); | |
552 | WRITE1(dst, 3, fg); | |
553 | break; | |
554 | case 10: | |
555 | WRITE1(dst, 1, fg); | |
556 | WRITE1(dst, 3, fg); | |
557 | break; | |
558 | case 11: | |
559 | WRITE2(dst, 0, fg); | |
560 | WRITE1(dst, 3, fg); | |
561 | break; | |
562 | case 12: | |
563 | WRITE2(dst, 2, fg); | |
564 | break; | |
565 | case 13: | |
566 | WRITE1(dst, 0, fg); | |
567 | WRITE2(dst, 2, fg); | |
568 | break; | |
569 | case 14: | |
570 | WRITE1(dst, 1, fg); | |
571 | WRITE2(dst, 2, fg); | |
572 | break; | |
573 | case 15: | |
574 | WRITE4(dst, 0, fg); | |
575 | break; | |
576 | } | |
577 | bits = FbStipLeft(bits, n); | |
578 | n = 4; | |
579 | dst += 4; | |
580 | } | |
581 | dstLine += dstStride; | |
582 | } | |
583 | } | |
584 | ||
585 | #undef WRITE_ADDR1 | |
586 | #undef WRITE_ADDR2 | |
587 | #undef WRITE_ADDR4 | |
588 | #undef WRITE1 | |
589 | #undef WRITE2 | |
590 | #undef WRITE4 | |
591 | ||
592 | #endif | |
593 | ||
594 | #ifdef POLYLINE | |
595 | void | |
596 | POLYLINE(DrawablePtr pDrawable, | |
597 | GCPtr pGC, int mode, int npt, DDXPointPtr ptsOrig) | |
598 | { | |
599 | INT32 *pts = (INT32 *) ptsOrig; | |
600 | int xoff = pDrawable->x; | |
601 | int yoff = pDrawable->y; | |
602 | unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); | |
603 | BoxPtr pBox = RegionExtents(fbGetCompositeClip(pGC)); | |
604 | ||
605 | FbBits *dst; | |
606 | int dstStride; | |
607 | int dstBpp; | |
608 | int dstXoff, dstYoff; | |
609 | ||
610 | UNIT *bits, *bitsBase; | |
611 | FbStride bitsStride; | |
612 | BITS xor = fbGetGCPrivate(pGC)->xor; | |
613 | BITS and = fbGetGCPrivate(pGC)->and; | |
614 | int dashoffset = 0; | |
615 | ||
616 | INT32 ul, lr; | |
617 | INT32 pt1, pt2; | |
618 | ||
619 | int e, e1, e3, len; | |
620 | int stepmajor, stepminor; | |
621 | int octant; | |
622 | ||
623 | if (mode == CoordModePrevious) | |
624 | fbFixCoordModePrevious(npt, ptsOrig); | |
625 | ||
626 | fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); | |
627 | bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT)); | |
628 | bitsBase = | |
629 | ((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff) * MUL; | |
630 | ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff); | |
631 | lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1); | |
632 | ||
633 | pt1 = *pts++; | |
634 | npt--; | |
635 | pt2 = *pts++; | |
636 | npt--; | |
637 | for (;;) { | |
638 | if (isClipped(pt1, ul, lr) | isClipped(pt2, ul, lr)) { | |
639 | fbSegment(pDrawable, pGC, | |
640 | intToX(pt1) + xoff, intToY(pt1) + yoff, | |
641 | intToX(pt2) + xoff, intToY(pt2) + yoff, | |
642 | npt == 0 && pGC->capStyle != CapNotLast, &dashoffset); | |
643 | if (!npt) { | |
644 | fbFinishAccess(pDrawable); | |
645 | return; | |
646 | } | |
647 | pt1 = pt2; | |
648 | pt2 = *pts++; | |
649 | npt--; | |
650 | } | |
651 | else { | |
652 | bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1) * MUL; | |
653 | for (;;) { | |
654 | CalcLineDeltas(intToX(pt1), intToY(pt1), | |
655 | intToX(pt2), intToY(pt2), | |
656 | len, e1, stepmajor, stepminor, 1, bitsStride, | |
657 | octant); | |
658 | stepmajor *= MUL; | |
659 | if (len < e1) { | |
660 | e3 = len; | |
661 | len = e1; | |
662 | e1 = e3; | |
663 | ||
664 | e3 = stepminor; | |
665 | stepminor = stepmajor; | |
666 | stepmajor = e3; | |
667 | SetYMajorOctant(octant); | |
668 | } | |
669 | e = -len; | |
670 | e1 <<= 1; | |
671 | e3 = e << 1; | |
672 | FIXUP_ERROR(e, octant, bias); | |
673 | if (and == 0) { | |
674 | while (len--) { | |
675 | STORE(bits, xor); | |
676 | bits += stepmajor; | |
677 | e += e1; | |
678 | if (e >= 0) { | |
679 | bits += stepminor; | |
680 | e += e3; | |
681 | } | |
682 | } | |
683 | } | |
684 | else { | |
685 | while (len--) { | |
686 | RROP(bits, and, xor); | |
687 | bits += stepmajor; | |
688 | e += e1; | |
689 | if (e >= 0) { | |
690 | bits += stepminor; | |
691 | e += e3; | |
692 | } | |
693 | } | |
694 | } | |
695 | if (!npt) { | |
696 | if (pGC->capStyle != CapNotLast && | |
697 | pt2 != *((INT32 *) ptsOrig)) { | |
698 | RROP(bits, and, xor); | |
699 | } | |
700 | fbFinishAccess(pDrawable); | |
701 | return; | |
702 | } | |
703 | pt1 = pt2; | |
704 | pt2 = *pts++; | |
705 | --npt; | |
706 | if (isClipped(pt2, ul, lr)) | |
707 | break; | |
708 | } | |
709 | } | |
710 | } | |
711 | ||
712 | fbFinishAccess(pDrawable); | |
713 | } | |
714 | #endif | |
715 | ||
716 | #ifdef POLYSEGMENT | |
717 | void | |
718 | POLYSEGMENT(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg) | |
719 | { | |
720 | INT32 *pts = (INT32 *) pseg; | |
721 | int xoff = pDrawable->x; | |
722 | int yoff = pDrawable->y; | |
723 | unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); | |
724 | BoxPtr pBox = RegionExtents(fbGetCompositeClip(pGC)); | |
725 | ||
726 | FbBits *dst; | |
727 | int dstStride; | |
728 | int dstBpp; | |
729 | int dstXoff, dstYoff; | |
730 | ||
731 | UNIT *bits, *bitsBase; | |
732 | FbStride bitsStride; | |
733 | FbBits xorBits = fbGetGCPrivate(pGC)->xor; | |
734 | FbBits andBits = fbGetGCPrivate(pGC)->and; | |
735 | BITS xor = xorBits; | |
736 | BITS and = andBits; | |
737 | int dashoffset = 0; | |
738 | ||
739 | INT32 ul, lr; | |
740 | INT32 pt1, pt2; | |
741 | ||
742 | int e, e1, e3, len; | |
743 | int stepmajor, stepminor; | |
744 | int octant; | |
745 | Bool capNotLast; | |
746 | ||
747 | fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); | |
748 | bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT)); | |
749 | bitsBase = | |
750 | ((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff) * MUL; | |
751 | ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff); | |
752 | lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1); | |
753 | ||
754 | capNotLast = pGC->capStyle == CapNotLast; | |
755 | ||
756 | while (nseg--) { | |
757 | pt1 = *pts++; | |
758 | pt2 = *pts++; | |
759 | if (isClipped(pt1, ul, lr) | isClipped(pt2, ul, lr)) { | |
760 | fbSegment(pDrawable, pGC, | |
761 | intToX(pt1) + xoff, intToY(pt1) + yoff, | |
762 | intToX(pt2) + xoff, intToY(pt2) + yoff, | |
763 | !capNotLast, &dashoffset); | |
764 | } | |
765 | else { | |
766 | CalcLineDeltas(intToX(pt1), intToY(pt1), | |
767 | intToX(pt2), intToY(pt2), | |
768 | len, e1, stepmajor, stepminor, 1, bitsStride, | |
769 | octant); | |
770 | if (e1 == 0 && len > 3 | |
771 | #if MUL != 1 | |
772 | && FbCheck24Pix(and) && FbCheck24Pix(xor) | |
773 | #endif | |
774 | ) { | |
775 | int x1, x2; | |
776 | FbBits *dstLine; | |
777 | int dstX, width; | |
778 | FbBits startmask, endmask; | |
779 | int nmiddle; | |
780 | ||
781 | if (stepmajor < 0) { | |
782 | x1 = intToX(pt2); | |
783 | x2 = intToX(pt1) + 1; | |
784 | if (capNotLast) | |
785 | x1++; | |
786 | } | |
787 | else { | |
788 | x1 = intToX(pt1); | |
789 | x2 = intToX(pt2); | |
790 | if (!capNotLast) | |
791 | x2++; | |
792 | } | |
793 | dstX = (x1 + xoff + dstXoff) * (sizeof(UNIT) * 8 * MUL); | |
794 | width = (x2 - x1) * (sizeof(UNIT) * 8 * MUL); | |
795 | ||
796 | dstLine = dst + (intToY(pt1) + yoff + dstYoff) * dstStride; | |
797 | dstLine += dstX >> FB_SHIFT; | |
798 | dstX &= FB_MASK; | |
799 | FbMaskBits(dstX, width, startmask, nmiddle, endmask); | |
800 | if (startmask) { | |
801 | WRITE(dstLine, | |
802 | FbDoMaskRRop(READ(dstLine), andBits, xorBits, | |
803 | startmask)); | |
804 | dstLine++; | |
805 | } | |
806 | if (!andBits) | |
807 | while (nmiddle--) | |
808 | WRITE(dstLine++, xorBits); | |
809 | else | |
810 | while (nmiddle--) { | |
811 | WRITE(dstLine, | |
812 | FbDoRRop(READ(dstLine), andBits, xorBits)); | |
813 | dstLine++; | |
814 | } | |
815 | if (endmask) | |
816 | WRITE(dstLine, | |
817 | FbDoMaskRRop(READ(dstLine), andBits, xorBits, | |
818 | endmask)); | |
819 | } | |
820 | else { | |
821 | stepmajor *= MUL; | |
822 | bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1) * MUL; | |
823 | if (len < e1) { | |
824 | e3 = len; | |
825 | len = e1; | |
826 | e1 = e3; | |
827 | ||
828 | e3 = stepminor; | |
829 | stepminor = stepmajor; | |
830 | stepmajor = e3; | |
831 | SetYMajorOctant(octant); | |
832 | } | |
833 | e = -len; | |
834 | e1 <<= 1; | |
835 | e3 = e << 1; | |
836 | FIXUP_ERROR(e, octant, bias); | |
837 | if (!capNotLast) | |
838 | len++; | |
839 | if (and == 0) { | |
840 | while (len--) { | |
841 | STORE(bits, xor); | |
842 | bits += stepmajor; | |
843 | e += e1; | |
844 | if (e >= 0) { | |
845 | bits += stepminor; | |
846 | e += e3; | |
847 | } | |
848 | } | |
849 | } | |
850 | else { | |
851 | while (len--) { | |
852 | RROP(bits, and, xor); | |
853 | bits += stepmajor; | |
854 | e += e1; | |
855 | if (e >= 0) { | |
856 | bits += stepminor; | |
857 | e += e3; | |
858 | } | |
859 | } | |
860 | } | |
861 | } | |
862 | } | |
863 | } | |
864 | ||
865 | fbFinishAccess(pDrawable); | |
866 | } | |
867 | #endif | |
868 | ||
869 | #undef MUL | |
870 | #undef STORE | |
871 | #undef RROP | |
872 | #undef UNIT | |
873 | #undef USE_SOLID | |
874 | ||
875 | #undef isClipped |