Imported Upstream version 1.15.1
[deb_xorg-server.git] / fb / fbbits.h
CommitLineData
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
70void
71BRESSOLID(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
116void
117BRESDASH(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
243void
244DOTS(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
291void
292ARC(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
498void
499GLYPH(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
595void
596POLYLINE(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
717void
718POLYSEGMENT(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