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