2 * Copyright © 1998 Keith Packard
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.
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.
24 * This file defines functions for drawing some primitives using
25 * underlying datatypes instead of masks
28 #define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000)
30 #ifdef HAVE_DIX_CONFIG_H
31 #include <dix-config.h>
41 #define STORE(b,x) BITSSTORE(b,x)
43 #define STORE(b,x) WRITE((b), (x))
47 #define RROP(b,a,x) BITSRROP(b,a,x)
49 #define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x)))
60 * Define the following before including this file:
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
71 BRESSOLID(DrawablePtr pDrawable
,
75 int signdy
, int axis
, int x1
, int y1
, int e
, int e1
, int e3
, int len
)
81 FbGCPrivPtr pPriv
= fbGetGCPrivate(pGC
);
84 FbStride majorStep
, minorStep
;
85 BITS
xor = (BITS
) pPriv
->xor;
87 fbGetDrawable(pDrawable
, dst
, dstStride
, dstBpp
, dstXoff
, dstYoff
);
89 ((UNIT
*) (dst
+ ((y1
+ dstYoff
) * dstStride
))) + (x1
+ dstXoff
) * MUL
;
90 bitsStride
= dstStride
* (sizeof(FbBits
) / sizeof(UNIT
));
92 bitsStride
= -bitsStride
;
94 majorStep
= signdx
* MUL
;
95 minorStep
= bitsStride
;
98 majorStep
= bitsStride
;
99 minorStep
= signdx
* MUL
;
111 fbFinishAccess(pDrawable
);
117 BRESDASH(DrawablePtr pDrawable
,
121 int signdy
, int axis
, int x1
, int y1
, int e
, int e1
, int e3
, int len
)
126 int dstXoff
, dstYoff
;
127 FbGCPrivPtr pPriv
= fbGetGCPrivate(pGC
);
130 FbStride majorStep
, minorStep
;
138 fbGetDrawable(pDrawable
, dst
, dstStride
, dstBpp
, dstXoff
, dstYoff
);
139 doOdd
= pGC
->lineStyle
== LineDoubleDash
;
140 xorfg
= (BITS
) pPriv
->xor;
141 xorbg
= (BITS
) pPriv
->bgxor
;
143 FbDashInit(pGC
, pPriv
, dashOffset
, dashlen
, even
);
146 ((UNIT
*) (dst
+ ((y1
+ dstYoff
) * dstStride
))) + (x1
+ dstXoff
) * MUL
;
147 bitsStride
= dstStride
* (sizeof(FbBits
) / sizeof(UNIT
));
149 bitsStride
= -bitsStride
;
150 if (axis
== X_AXIS
) {
151 majorStep
= signdx
* MUL
;
152 minorStep
= bitsStride
;
155 majorStep
= bitsStride
;
156 minorStep
= signdx
* MUL
;
168 if ((e
+= e1
) >= 0) {
176 FbDashNextEven(dashlen
);
185 if ((e
+= e1
) >= 0) {
193 FbDashNextOdd(dashlen
);
207 if ((e
+= e1
) >= 0) {
215 FbDashNextEven(dashlen
);
223 if ((e
+= e1
) >= 0) {
231 FbDashNextOdd(dashlen
);
238 fbFinishAccess(pDrawable
);
249 int npt
, int xorg
, int yorg
, int xoff
, int yoff
, FbBits
and, FbBits
xor)
251 INT32
*pts
= (INT32
*) ptsOrig
;
252 UNIT
*bits
= (UNIT
*) dst
;
254 BITS bxor
= (BITS
) xor;
255 BITS band
= (BITS
) and;
256 FbStride bitsStride
= dstStride
* (sizeof(FbBits
) / sizeof(UNIT
));
260 ul
= coordToInt(pBox
->x1
- xorg
, pBox
->y1
- yorg
);
261 lr
= coordToInt(pBox
->x2
- xorg
- 1, pBox
->y2
- yorg
- 1);
263 bits
+= bitsStride
* (yorg
+ yoff
) + (xorg
+ xoff
) * MUL
;
268 if (!isClipped(pt
, ul
, lr
)) {
269 point
= bits
+ intToY(pt
) * bitsStride
+ intToX(pt
) * MUL
;
277 if (!isClipped(pt
, ul
, lr
)) {
278 point
= bits
+ intToY(pt
) * bitsStride
+ intToX(pt
) * MUL
;
279 RROP(point
, band
, bxor
);
288 #define ARCCOPY(d) STORE(d,xorBits)
289 #define ARCRROP(d) RROP(d,andBits,xorBits)
294 int dstBpp
, xArc
* arc
, int drawX
, int drawY
, FbBits
and, FbBits
xor)
301 UNIT
*yorgp
, *yorgop
;
302 BITS andBits
, xorBits
;
303 int yoffset
, dyoffset
;
304 int y
, a
, b
, d
, mask
;
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
;
317 yoffset
= y
? bitsStride
: 0;
319 mask
= info
.initialMask
;
321 if (!(arc
->width
& 1)) {
324 ARCCOPY(yorgp
+ info
.xorgo
);
326 ARCCOPY(yorgop
+ info
.xorgo
);
330 ARCRROP(yorgp
+ info
.xorgo
);
332 ARCRROP(yorgop
+ info
.xorgo
);
335 if (!info
.end
.x
|| !info
.end
.y
) {
336 mask
= info
.end
.mask
;
337 info
.end
= info
.altend
;
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
;
346 yorghb
+= info
.h
* MUL
;
349 ARCCOPY(yorgp
+ yoffset
+ x
* MUL
);
350 ARCCOPY(yorgp
+ yoffset
- x
* MUL
);
351 ARCCOPY(yorgop
- yoffset
- x
* MUL
);
352 ARCCOPY(yorgop
- yoffset
+ x
* MUL
);
355 ARCRROP(yorgp
+ yoffset
+ x
* MUL
);
356 ARCRROP(yorgp
+ yoffset
- x
* MUL
);
357 ARCRROP(yorgop
- yoffset
- x
* MUL
);
358 ARCRROP(yorgop
- yoffset
+ x
* MUL
);
363 ARCCOPY(yorghb
- xoffset
- y
* MUL
);
364 ARCCOPY(yorgohb
- xoffset
+ y
* MUL
);
365 ARCCOPY(yorgohb
+ xoffset
+ y
* MUL
);
366 ARCCOPY(yorghb
+ xoffset
- y
* MUL
);
369 ARCRROP(yorghb
- xoffset
- y
* MUL
);
370 ARCRROP(yorgohb
- xoffset
+ y
* MUL
);
371 ARCRROP(yorgohb
+ xoffset
+ y
* MUL
);
372 ARCRROP(yorghb
+ xoffset
- y
* MUL
);
374 xoffset
+= bitsStride
;
375 MIARCCIRCLESTEP(yoffset
+= bitsStride
;
381 yoffset
= info
.h
* bitsStride
;
384 while (y
< info
.h
|| x
< info
.w
) {
385 MIARCOCTANTSHIFT(dyoffset
= bitsStride
;
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
);
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
);
399 MIARCSTEP(yoffset
+= dyoffset
;
400 , yoffset
+= bitsStride
;
405 while (y
< info
.h
|| x
< info
.w
) {
406 MIARCOCTANTSHIFT(dyoffset
= bitsStride
;
408 if ((x
== info
.start
.x
) || (y
== info
.start
.y
)) {
409 mask
= info
.start
.mask
;
410 info
.start
= info
.altstart
;
414 ARCCOPY(yorgp
+ yoffset
+ info
.xorg
+ x
* MUL
);
416 ARCCOPY(yorgp
+ yoffset
+ info
.xorgo
- x
* MUL
);
418 ARCCOPY(yorgop
- yoffset
+ info
.xorgo
- x
* MUL
);
420 ARCCOPY(yorgop
- yoffset
+ info
.xorg
+ x
* MUL
);
424 ARCRROP(yorgp
+ yoffset
+ info
.xorg
+ x
* MUL
);
426 ARCRROP(yorgp
+ yoffset
+ info
.xorgo
- x
* MUL
);
428 ARCRROP(yorgop
- yoffset
+ info
.xorgo
- x
* MUL
);
430 ARCRROP(yorgop
- yoffset
+ info
.xorg
+ x
* MUL
);
432 if ((x
== info
.end
.x
) || (y
== info
.end
.y
)) {
433 mask
= info
.end
.mask
;
434 info
.end
= info
.altend
;
436 MIARCSTEP(yoffset
+= dyoffset
;
437 , yoffset
+= bitsStride
;
441 if ((x
== info
.start
.x
) || (y
== info
.start
.y
))
442 mask
= info
.start
.mask
;
445 ARCCOPY(yorgp
+ yoffset
+ info
.xorg
+ x
* MUL
);
447 ARCCOPY(yorgop
- yoffset
+ info
.xorgo
- x
* MUL
);
448 if (arc
->height
& 1) {
450 ARCCOPY(yorgp
+ yoffset
+ info
.xorgo
- x
* MUL
);
452 ARCCOPY(yorgop
- yoffset
+ info
.xorg
+ x
* MUL
);
457 ARCRROP(yorgp
+ yoffset
+ info
.xorg
+ x
* MUL
);
459 ARCRROP(yorgop
- yoffset
+ info
.xorgo
- x
* MUL
);
460 if (arc
->height
& 1) {
462 ARCRROP(yorgp
+ yoffset
+ info
.xorgo
- x
* MUL
);
464 ARCRROP(yorgop
- yoffset
+ info
.xorg
+ x
* MUL
);
474 #if BITMAP_BIT_ORDER == LSBFirst
475 #define WRITE_ADDR1(n) (n)
476 #define WRITE_ADDR2(n) (n)
477 #define WRITE_ADDR4(n) (n)
479 #define WRITE_ADDR1(n) ((n) ^ 3)
480 #define WRITE_ADDR2(n) ((n) ^ 2)
481 #define WRITE_ADDR4(n) ((n))
484 #define WRITE1(d,n,fg) WRITE(d + WRITE_ADDR1(n), (BITS) (fg))
487 #define WRITE2(d,n,fg) WRITE((BITS2 *) &((d)[WRITE_ADDR2(n)]), (BITS2) (fg))
489 #define WRITE2(d,n,fg) (WRITE1(d,n,fg), WRITE1(d,(n)+1,fg))
493 #define WRITE4(d,n,fg) WRITE((BITS4 *) &((d)[WRITE_ADDR4(n)]), (BITS4) (fg))
495 #define WRITE4(d,n,fg) (WRITE2(d,n,fg), WRITE2(d,(n)+2,fg))
499 GLYPH(FbBits
* dstBits
,
501 int dstBpp
, FbStip
* stipple
, FbBits fg
, int x
, int height
)
510 dstLine
= (BITS
*) dstBits
;
512 dstStride
*= (sizeof(FbBits
) / sizeof(BITS
));
517 dst
= (BITS
*) dstLine
;
520 switch (FbStipMoveLsb(FbLeftStipBits(bits
, n
), 4, n
)) {
577 bits
= FbStipLeft(bits
, n
);
581 dstLine
+= dstStride
;
596 POLYLINE(DrawablePtr pDrawable
,
597 GCPtr pGC
, int mode
, int npt
, DDXPointPtr ptsOrig
)
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
));
608 int dstXoff
, dstYoff
;
610 UNIT
*bits
, *bitsBase
;
612 BITS
xor = fbGetGCPrivate(pGC
)->xor;
613 BITS
and = fbGetGCPrivate(pGC
)->and;
620 int stepmajor
, stepminor
;
623 if (mode
== CoordModePrevious
)
624 fbFixCoordModePrevious(npt
, ptsOrig
);
626 fbGetDrawable(pDrawable
, dst
, dstStride
, dstBpp
, dstXoff
, dstYoff
);
627 bitsStride
= dstStride
* (sizeof(FbBits
) / sizeof(UNIT
));
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);
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
);
644 fbFinishAccess(pDrawable
);
652 bits
= bitsBase
+ intToY(pt1
) * bitsStride
+ intToX(pt1
) * MUL
;
654 CalcLineDeltas(intToX(pt1
), intToY(pt1
),
655 intToX(pt2
), intToY(pt2
),
656 len
, e1
, stepmajor
, stepminor
, 1, bitsStride
,
665 stepminor
= stepmajor
;
667 SetYMajorOctant(octant
);
672 FIXUP_ERROR(e
, octant
, bias
);
686 RROP(bits
, and, xor);
696 if (pGC
->capStyle
!= CapNotLast
&&
697 pt2
!= *((INT32
*) ptsOrig
)) {
698 RROP(bits
, and, xor);
700 fbFinishAccess(pDrawable
);
706 if (isClipped(pt2
, ul
, lr
))
712 fbFinishAccess(pDrawable
);
718 POLYSEGMENT(DrawablePtr pDrawable
, GCPtr pGC
, int nseg
, xSegment
* pseg
)
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
));
729 int dstXoff
, dstYoff
;
731 UNIT
*bits
, *bitsBase
;
733 FbBits xorBits
= fbGetGCPrivate(pGC
)->xor;
734 FbBits andBits
= fbGetGCPrivate(pGC
)->and;
743 int stepmajor
, stepminor
;
747 fbGetDrawable(pDrawable
, dst
, dstStride
, dstBpp
, dstXoff
, dstYoff
);
748 bitsStride
= dstStride
* (sizeof(FbBits
) / sizeof(UNIT
));
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);
754 capNotLast
= pGC
->capStyle
== CapNotLast
;
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
);
766 CalcLineDeltas(intToX(pt1
), intToY(pt1
),
767 intToX(pt2
), intToY(pt2
),
768 len
, e1
, stepmajor
, stepminor
, 1, bitsStride
,
770 if (e1
== 0 && len
> 3
772 && FbCheck24Pix(and) && FbCheck24Pix(xor)
778 FbBits startmask
, endmask
;
783 x2
= intToX(pt1
) + 1;
793 dstX
= (x1
+ xoff
+ dstXoff
) * (sizeof(UNIT
) * 8 * MUL
);
794 width
= (x2
- x1
) * (sizeof(UNIT
) * 8 * MUL
);
796 dstLine
= dst
+ (intToY(pt1
) + yoff
+ dstYoff
) * dstStride
;
797 dstLine
+= dstX
>> FB_SHIFT
;
799 FbMaskBits(dstX
, width
, startmask
, nmiddle
, endmask
);
802 FbDoMaskRRop(READ(dstLine
), andBits
, xorBits
,
808 WRITE(dstLine
++, xorBits
);
812 FbDoRRop(READ(dstLine
), andBits
, xorBits
));
817 FbDoMaskRRop(READ(dstLine
), andBits
, xorBits
,
822 bits
= bitsBase
+ intToY(pt1
) * bitsStride
+ intToX(pt1
) * MUL
;
829 stepminor
= stepmajor
;
831 SetYMajorOctant(octant
);
836 FIXUP_ERROR(e
, octant
, bias
);
852 RROP(bits
, and, xor);
865 fbFinishAccess(pDrawable
);