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