xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

fbbits.h (24904B)


      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
     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
    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
    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
    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
    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
    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
    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