123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876 |
- /*
- * Copyright © 1998 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
- /*
- * This file defines functions for drawing some primitives using
- * underlying datatypes instead of masks
- */
- #define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000)
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #ifdef BITSMUL
- #define MUL BITSMUL
- #else
- #define MUL 1
- #endif
- #ifdef BITSSTORE
- #define STORE(b,x) BITSSTORE(b,x)
- #else
- #define STORE(b,x) WRITE((b), (x))
- #endif
- #ifdef BITSRROP
- #define RROP(b,a,x) BITSRROP(b,a,x)
- #else
- #define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x)))
- #endif
- #ifdef BITSUNIT
- #define UNIT BITSUNIT
- #define USE_SOLID
- #else
- #define UNIT BITS
- #endif
- /*
- * Define the following before including this file:
- *
- * BRESSOLID name of function for drawing a solid segment
- * BRESDASH name of function for drawing a dashed segment
- * DOTS name of function for drawing dots
- * ARC name of function for drawing a solid arc
- * BITS type of underlying unit
- */
- #ifdef BRESSOLID
- 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)
- {
- FbBits *dst;
- FbStride dstStride;
- int dstBpp;
- int dstXoff, dstYoff;
- FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
- UNIT *bits;
- FbStride bitsStride;
- FbStride majorStep, minorStep;
- BITS xor = (BITS) pPriv->xor;
- fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
- bits =
- ((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff) * MUL;
- bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
- if (signdy < 0)
- bitsStride = -bitsStride;
- if (axis == X_AXIS) {
- majorStep = signdx * MUL;
- minorStep = bitsStride;
- }
- else {
- majorStep = bitsStride;
- minorStep = signdx * MUL;
- }
- while (len--) {
- STORE(bits, xor);
- bits += majorStep;
- e += e1;
- if (e >= 0) {
- bits += minorStep;
- e += e3;
- }
- }
- fbFinishAccess(pDrawable);
- }
- #endif
- #ifdef BRESDASH
- 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)
- {
- FbBits *dst;
- FbStride dstStride;
- int dstBpp;
- int dstXoff, dstYoff;
- FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
- UNIT *bits;
- FbStride bitsStride;
- FbStride majorStep, minorStep;
- BITS xorfg, xorbg;
- FbDashDeclare;
- int dashlen;
- Bool even;
- Bool doOdd;
- fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
- doOdd = pGC->lineStyle == LineDoubleDash;
- xorfg = (BITS) pPriv->xor;
- xorbg = (BITS) pPriv->bgxor;
- FbDashInit(pGC, pPriv, dashOffset, dashlen, even);
- bits =
- ((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff) * MUL;
- bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
- if (signdy < 0)
- bitsStride = -bitsStride;
- if (axis == X_AXIS) {
- majorStep = signdx * MUL;
- minorStep = bitsStride;
- }
- else {
- majorStep = bitsStride;
- minorStep = signdx * MUL;
- }
- if (dashlen >= len)
- dashlen = len;
- if (doOdd) {
- if (!even)
- goto doubleOdd;
- for (;;) {
- len -= dashlen;
- while (dashlen--) {
- STORE(bits, xorfg);
- bits += majorStep;
- if ((e += e1) >= 0) {
- e += e3;
- bits += minorStep;
- }
- }
- if (!len)
- break;
- FbDashNextEven(dashlen);
- if (dashlen >= len)
- dashlen = len;
- doubleOdd:
- len -= dashlen;
- while (dashlen--) {
- STORE(bits, xorbg);
- bits += majorStep;
- if ((e += e1) >= 0) {
- e += e3;
- bits += minorStep;
- }
- }
- if (!len)
- break;
- FbDashNextOdd(dashlen);
- if (dashlen >= len)
- dashlen = len;
- }
- }
- else {
- if (!even)
- goto onOffOdd;
- for (;;) {
- len -= dashlen;
- while (dashlen--) {
- STORE(bits, xorfg);
- bits += majorStep;
- if ((e += e1) >= 0) {
- e += e3;
- bits += minorStep;
- }
- }
- if (!len)
- break;
- FbDashNextEven(dashlen);
- if (dashlen >= len)
- dashlen = len;
- onOffOdd:
- len -= dashlen;
- while (dashlen--) {
- bits += majorStep;
- if ((e += e1) >= 0) {
- e += e3;
- bits += minorStep;
- }
- }
- if (!len)
- break;
- FbDashNextOdd(dashlen);
- if (dashlen >= len)
- dashlen = len;
- }
- }
- fbFinishAccess(pDrawable);
- }
- #endif
- #ifdef DOTS
- 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)
- {
- INT32 *pts = (INT32 *) ptsOrig;
- UNIT *bits = (UNIT *) dst;
- UNIT *point;
- BITS bxor = (BITS) xor;
- BITS band = (BITS) and;
- FbStride bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
- INT32 ul, lr;
- INT32 pt;
- ul = coordToInt(pBox->x1 - xorg, pBox->y1 - yorg);
- lr = coordToInt(pBox->x2 - xorg - 1, pBox->y2 - yorg - 1);
- bits += bitsStride * (yorg + yoff) + (xorg + xoff) * MUL;
- if (and == 0) {
- while (npt--) {
- pt = *pts++;
- if (!isClipped(pt, ul, lr)) {
- point = bits + intToY(pt) * bitsStride + intToX(pt) * MUL;
- STORE(point, bxor);
- }
- }
- }
- else {
- while (npt--) {
- pt = *pts++;
- if (!isClipped(pt, ul, lr)) {
- point = bits + intToY(pt) * bitsStride + intToX(pt) * MUL;
- RROP(point, band, bxor);
- }
- }
- }
- }
- #endif
- #ifdef ARC
- #define ARCCOPY(d) STORE(d,xorBits)
- #define ARCRROP(d) RROP(d,andBits,xorBits)
- void
- ARC(FbBits * dst,
- FbStride dstStride,
- int dstBpp, xArc * arc, int drawX, int drawY, FbBits and, FbBits xor)
- {
- UNIT *bits;
- FbStride bitsStride;
- miZeroArcRec info;
- Bool do360;
- int x;
- UNIT *yorgp, *yorgop;
- BITS andBits, xorBits;
- int yoffset, dyoffset;
- int y, a, b, d, mask;
- int k1, k3, dx, dy;
- bits = (UNIT *) dst;
- bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
- andBits = (BITS) and;
- xorBits = (BITS) xor;
- do360 = miZeroArcSetup(arc, &info, TRUE);
- yorgp = bits + ((info.yorg + drawY) * bitsStride);
- yorgop = bits + ((info.yorgo + drawY) * bitsStride);
- info.xorg = (info.xorg + drawX) * MUL;
- info.xorgo = (info.xorgo + drawX) * MUL;
- MIARCSETUP();
- yoffset = y ? bitsStride : 0;
- dyoffset = 0;
- mask = info.initialMask;
- if (!(arc->width & 1)) {
- if (andBits == 0) {
- if (mask & 2)
- ARCCOPY(yorgp + info.xorgo);
- if (mask & 8)
- ARCCOPY(yorgop + info.xorgo);
- }
- else {
- if (mask & 2)
- ARCRROP(yorgp + info.xorgo);
- if (mask & 8)
- ARCRROP(yorgop + info.xorgo);
- }
- }
- if (!info.end.x || !info.end.y) {
- mask = info.end.mask;
- info.end = info.altend;
- }
- if (do360 && (arc->width == arc->height) && !(arc->width & 1)) {
- int xoffset = bitsStride;
- UNIT *yorghb = yorgp + (info.h * bitsStride) + info.xorg;
- UNIT *yorgohb = yorghb - info.h * MUL;
- yorgp += info.xorg;
- yorgop += info.xorg;
- yorghb += info.h * MUL;
- while (1) {
- if (andBits == 0) {
- ARCCOPY(yorgp + yoffset + x * MUL);
- ARCCOPY(yorgp + yoffset - x * MUL);
- ARCCOPY(yorgop - yoffset - x * MUL);
- ARCCOPY(yorgop - yoffset + x * MUL);
- }
- else {
- ARCRROP(yorgp + yoffset + x * MUL);
- ARCRROP(yorgp + yoffset - x * MUL);
- ARCRROP(yorgop - yoffset - x * MUL);
- ARCRROP(yorgop - yoffset + x * MUL);
- }
- if (a < 0)
- break;
- if (andBits == 0) {
- ARCCOPY(yorghb - xoffset - y * MUL);
- ARCCOPY(yorgohb - xoffset + y * MUL);
- ARCCOPY(yorgohb + xoffset + y * MUL);
- ARCCOPY(yorghb + xoffset - y * MUL);
- }
- else {
- ARCRROP(yorghb - xoffset - y * MUL);
- ARCRROP(yorgohb - xoffset + y * MUL);
- ARCRROP(yorgohb + xoffset + y * MUL);
- ARCRROP(yorghb + xoffset - y * MUL);
- }
- xoffset += bitsStride;
- MIARCCIRCLESTEP(yoffset += bitsStride;
- );
- }
- yorgp -= info.xorg;
- yorgop -= info.xorg;
- x = info.w;
- yoffset = info.h * bitsStride;
- }
- else if (do360) {
- while (y < info.h || x < info.w) {
- MIARCOCTANTSHIFT(dyoffset = bitsStride;
- );
- if (andBits == 0) {
- ARCCOPY(yorgp + yoffset + info.xorg + x * MUL);
- ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL);
- ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL);
- ARCCOPY(yorgop - yoffset + info.xorg + x * MUL);
- }
- else {
- ARCRROP(yorgp + yoffset + info.xorg + x * MUL);
- ARCRROP(yorgp + yoffset + info.xorgo - x * MUL);
- ARCRROP(yorgop - yoffset + info.xorgo - x * MUL);
- ARCRROP(yorgop - yoffset + info.xorg + x * MUL);
- }
- MIARCSTEP(yoffset += dyoffset;
- , yoffset += bitsStride;
- );
- }
- }
- else {
- while (y < info.h || x < info.w) {
- MIARCOCTANTSHIFT(dyoffset = bitsStride;
- );
- if ((x == info.start.x) || (y == info.start.y)) {
- mask = info.start.mask;
- info.start = info.altstart;
- }
- if (andBits == 0) {
- if (mask & 1)
- ARCCOPY(yorgp + yoffset + info.xorg + x * MUL);
- if (mask & 2)
- ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL);
- if (mask & 4)
- ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL);
- if (mask & 8)
- ARCCOPY(yorgop - yoffset + info.xorg + x * MUL);
- }
- else {
- if (mask & 1)
- ARCRROP(yorgp + yoffset + info.xorg + x * MUL);
- if (mask & 2)
- ARCRROP(yorgp + yoffset + info.xorgo - x * MUL);
- if (mask & 4)
- ARCRROP(yorgop - yoffset + info.xorgo - x * MUL);
- if (mask & 8)
- ARCRROP(yorgop - yoffset + info.xorg + x * MUL);
- }
- if ((x == info.end.x) || (y == info.end.y)) {
- mask = info.end.mask;
- info.end = info.altend;
- }
- MIARCSTEP(yoffset += dyoffset;
- , yoffset += bitsStride;
- );
- }
- }
- if ((x == info.start.x) || (y == info.start.y))
- mask = info.start.mask;
- if (andBits == 0) {
- if (mask & 1)
- ARCCOPY(yorgp + yoffset + info.xorg + x * MUL);
- if (mask & 4)
- ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL);
- if (arc->height & 1) {
- if (mask & 2)
- ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL);
- if (mask & 8)
- ARCCOPY(yorgop - yoffset + info.xorg + x * MUL);
- }
- }
- else {
- if (mask & 1)
- ARCRROP(yorgp + yoffset + info.xorg + x * MUL);
- if (mask & 4)
- ARCRROP(yorgop - yoffset + info.xorgo - x * MUL);
- if (arc->height & 1) {
- if (mask & 2)
- ARCRROP(yorgp + yoffset + info.xorgo - x * MUL);
- if (mask & 8)
- ARCRROP(yorgop - yoffset + info.xorg + x * MUL);
- }
- }
- }
- #undef ARCCOPY
- #undef ARCRROP
- #endif
- #ifdef GLYPH
- #if BITMAP_BIT_ORDER == LSBFirst
- #define WRITE_ADDR1(n) (n)
- #define WRITE_ADDR2(n) (n)
- #define WRITE_ADDR4(n) (n)
- #else
- #define WRITE_ADDR1(n) ((n) ^ 3)
- #define WRITE_ADDR2(n) ((n) ^ 2)
- #define WRITE_ADDR4(n) ((n))
- #endif
- #define WRITE1(d,n,fg) WRITE(d + WRITE_ADDR1(n), (BITS) (fg))
- #ifdef BITS2
- #define WRITE2(d,n,fg) WRITE((BITS2 *) &((d)[WRITE_ADDR2(n)]), (BITS2) (fg))
- #else
- #define WRITE2(d,n,fg) (WRITE1(d,n,fg), WRITE1(d,(n)+1,fg))
- #endif
- #ifdef BITS4
- #define WRITE4(d,n,fg) WRITE((BITS4 *) &((d)[WRITE_ADDR4(n)]), (BITS4) (fg))
- #else
- #define WRITE4(d,n,fg) (WRITE2(d,n,fg), WRITE2(d,(n)+2,fg))
- #endif
- void
- GLYPH(FbBits * dstBits,
- FbStride dstStride,
- int dstBpp, FbStip * stipple, FbBits fg, int x, int height)
- {
- int lshift;
- FbStip bits;
- BITS *dstLine;
- BITS *dst;
- int n;
- int shift;
- dstLine = (BITS *) dstBits;
- dstLine += x & ~3;
- dstStride *= (sizeof(FbBits) / sizeof(BITS));
- shift = x & 3;
- lshift = 4 - shift;
- while (height--) {
- bits = *stipple++;
- dst = (BITS *) dstLine;
- n = lshift;
- while (bits) {
- switch (FbStipMoveLsb(FbLeftStipBits(bits, n), 4, n)) {
- case 0:
- break;
- case 1:
- WRITE1(dst, 0, fg);
- break;
- case 2:
- WRITE1(dst, 1, fg);
- break;
- case 3:
- WRITE2(dst, 0, fg);
- break;
- case 4:
- WRITE1(dst, 2, fg);
- break;
- case 5:
- WRITE1(dst, 0, fg);
- WRITE1(dst, 2, fg);
- break;
- case 6:
- WRITE1(dst, 1, fg);
- WRITE1(dst, 2, fg);
- break;
- case 7:
- WRITE2(dst, 0, fg);
- WRITE1(dst, 2, fg);
- break;
- case 8:
- WRITE1(dst, 3, fg);
- break;
- case 9:
- WRITE1(dst, 0, fg);
- WRITE1(dst, 3, fg);
- break;
- case 10:
- WRITE1(dst, 1, fg);
- WRITE1(dst, 3, fg);
- break;
- case 11:
- WRITE2(dst, 0, fg);
- WRITE1(dst, 3, fg);
- break;
- case 12:
- WRITE2(dst, 2, fg);
- break;
- case 13:
- WRITE1(dst, 0, fg);
- WRITE2(dst, 2, fg);
- break;
- case 14:
- WRITE1(dst, 1, fg);
- WRITE2(dst, 2, fg);
- break;
- case 15:
- WRITE4(dst, 0, fg);
- break;
- }
- bits = FbStipLeft(bits, n);
- n = 4;
- dst += 4;
- }
- dstLine += dstStride;
- }
- }
- #undef WRITE_ADDR1
- #undef WRITE_ADDR2
- #undef WRITE_ADDR4
- #undef WRITE1
- #undef WRITE2
- #undef WRITE4
- #endif
- #ifdef POLYLINE
- void
- POLYLINE(DrawablePtr pDrawable,
- GCPtr pGC, int mode, int npt, DDXPointPtr ptsOrig)
- {
- INT32 *pts = (INT32 *) ptsOrig;
- int xoff = pDrawable->x;
- int yoff = pDrawable->y;
- unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
- BoxPtr pBox = RegionExtents(fbGetCompositeClip(pGC));
- FbBits *dst;
- int dstStride;
- int dstBpp;
- int dstXoff, dstYoff;
- UNIT *bits, *bitsBase;
- FbStride bitsStride;
- BITS xor = fbGetGCPrivate(pGC)->xor;
- BITS and = fbGetGCPrivate(pGC)->and;
- int dashoffset = 0;
- INT32 ul, lr;
- INT32 pt1, pt2;
- int e, e1, e3, len;
- int stepmajor, stepminor;
- int octant;
- if (mode == CoordModePrevious)
- fbFixCoordModePrevious(npt, ptsOrig);
- fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
- bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
- bitsBase =
- ((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff) * MUL;
- ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff);
- lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1);
- pt1 = *pts++;
- npt--;
- pt2 = *pts++;
- npt--;
- for (;;) {
- if (isClipped(pt1, ul, lr) | isClipped(pt2, ul, lr)) {
- fbSegment(pDrawable, pGC,
- intToX(pt1) + xoff, intToY(pt1) + yoff,
- intToX(pt2) + xoff, intToY(pt2) + yoff,
- npt == 0 && pGC->capStyle != CapNotLast, &dashoffset);
- if (!npt) {
- fbFinishAccess(pDrawable);
- return;
- }
- pt1 = pt2;
- pt2 = *pts++;
- npt--;
- }
- else {
- bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1) * MUL;
- for (;;) {
- CalcLineDeltas(intToX(pt1), intToY(pt1),
- intToX(pt2), intToY(pt2),
- len, e1, stepmajor, stepminor, 1, bitsStride,
- octant);
- stepmajor *= MUL;
- if (len < e1) {
- e3 = len;
- len = e1;
- e1 = e3;
- e3 = stepminor;
- stepminor = stepmajor;
- stepmajor = e3;
- SetYMajorOctant(octant);
- }
- e = -len;
- e1 <<= 1;
- e3 = e << 1;
- FIXUP_ERROR(e, octant, bias);
- if (and == 0) {
- while (len--) {
- STORE(bits, xor);
- bits += stepmajor;
- e += e1;
- if (e >= 0) {
- bits += stepminor;
- e += e3;
- }
- }
- }
- else {
- while (len--) {
- RROP(bits, and, xor);
- bits += stepmajor;
- e += e1;
- if (e >= 0) {
- bits += stepminor;
- e += e3;
- }
- }
- }
- if (!npt) {
- if (pGC->capStyle != CapNotLast &&
- pt2 != *((INT32 *) ptsOrig)) {
- RROP(bits, and, xor);
- }
- fbFinishAccess(pDrawable);
- return;
- }
- pt1 = pt2;
- pt2 = *pts++;
- --npt;
- if (isClipped(pt2, ul, lr))
- break;
- }
- }
- }
- fbFinishAccess(pDrawable);
- }
- #endif
- #ifdef POLYSEGMENT
- void
- POLYSEGMENT(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg)
- {
- INT32 *pts = (INT32 *) pseg;
- int xoff = pDrawable->x;
- int yoff = pDrawable->y;
- unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
- BoxPtr pBox = RegionExtents(fbGetCompositeClip(pGC));
- FbBits *dst;
- int dstStride;
- int dstBpp;
- int dstXoff, dstYoff;
- UNIT *bits, *bitsBase;
- FbStride bitsStride;
- FbBits xorBits = fbGetGCPrivate(pGC)->xor;
- FbBits andBits = fbGetGCPrivate(pGC)->and;
- BITS xor = xorBits;
- BITS and = andBits;
- int dashoffset = 0;
- INT32 ul, lr;
- INT32 pt1, pt2;
- int e, e1, e3, len;
- int stepmajor, stepminor;
- int octant;
- Bool capNotLast;
- fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
- bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
- bitsBase =
- ((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff) * MUL;
- ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff);
- lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1);
- capNotLast = pGC->capStyle == CapNotLast;
- while (nseg--) {
- pt1 = *pts++;
- pt2 = *pts++;
- if (isClipped(pt1, ul, lr) | isClipped(pt2, ul, lr)) {
- fbSegment(pDrawable, pGC,
- intToX(pt1) + xoff, intToY(pt1) + yoff,
- intToX(pt2) + xoff, intToY(pt2) + yoff,
- !capNotLast, &dashoffset);
- }
- else {
- CalcLineDeltas(intToX(pt1), intToY(pt1),
- intToX(pt2), intToY(pt2),
- len, e1, stepmajor, stepminor, 1, bitsStride,
- octant);
- if (e1 == 0 && len > 3
- #if MUL != 1
- && FbCheck24Pix(and) && FbCheck24Pix(xor)
- #endif
- ) {
- int x1, x2;
- FbBits *dstLine;
- int dstX, width;
- FbBits startmask, endmask;
- int nmiddle;
- if (stepmajor < 0) {
- x1 = intToX(pt2);
- x2 = intToX(pt1) + 1;
- if (capNotLast)
- x1++;
- }
- else {
- x1 = intToX(pt1);
- x2 = intToX(pt2);
- if (!capNotLast)
- x2++;
- }
- dstX = (x1 + xoff + dstXoff) * (sizeof(UNIT) * 8 * MUL);
- width = (x2 - x1) * (sizeof(UNIT) * 8 * MUL);
- dstLine = dst + (intToY(pt1) + yoff + dstYoff) * dstStride;
- dstLine += dstX >> FB_SHIFT;
- dstX &= FB_MASK;
- FbMaskBits(dstX, width, startmask, nmiddle, endmask);
- if (startmask) {
- WRITE(dstLine,
- FbDoMaskRRop(READ(dstLine), andBits, xorBits,
- startmask));
- dstLine++;
- }
- if (!andBits)
- while (nmiddle--)
- WRITE(dstLine++, xorBits);
- else
- while (nmiddle--) {
- WRITE(dstLine,
- FbDoRRop(READ(dstLine), andBits, xorBits));
- dstLine++;
- }
- if (endmask)
- WRITE(dstLine,
- FbDoMaskRRop(READ(dstLine), andBits, xorBits,
- endmask));
- }
- else {
- stepmajor *= MUL;
- bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1) * MUL;
- if (len < e1) {
- e3 = len;
- len = e1;
- e1 = e3;
- e3 = stepminor;
- stepminor = stepmajor;
- stepmajor = e3;
- SetYMajorOctant(octant);
- }
- e = -len;
- e1 <<= 1;
- e3 = e << 1;
- FIXUP_ERROR(e, octant, bias);
- if (!capNotLast)
- len++;
- if (and == 0) {
- while (len--) {
- STORE(bits, xor);
- bits += stepmajor;
- e += e1;
- if (e >= 0) {
- bits += stepminor;
- e += e3;
- }
- }
- }
- else {
- while (len--) {
- RROP(bits, and, xor);
- bits += stepmajor;
- e += e1;
- if (e >= 0) {
- bits += stepminor;
- e += e3;
- }
- }
- }
- }
- }
- }
- fbFinishAccess(pDrawable);
- }
- #endif
- #undef MUL
- #undef STORE
- #undef RROP
- #undef UNIT
- #undef USE_SOLID
- #undef isClipped
|