1706f2543Smrg/* 2706f2543Smrg * Copyright © 1998 Keith Packard 3706f2543Smrg * 4706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its 5706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that 6706f2543Smrg * the above copyright notice appear in all copies and that both that 7706f2543Smrg * copyright notice and this permission notice appear in supporting 8706f2543Smrg * documentation, and that the name of Keith Packard not be used in 9706f2543Smrg * advertising or publicity pertaining to distribution of the software without 10706f2543Smrg * specific, written prior permission. Keith Packard makes no 11706f2543Smrg * representations about the suitability of this software for any purpose. It 12706f2543Smrg * is provided "as is" without express or implied warranty. 13706f2543Smrg * 14706f2543Smrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16706f2543Smrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20706f2543Smrg * PERFORMANCE OF THIS SOFTWARE. 21706f2543Smrg */ 22706f2543Smrg 23706f2543Smrg/* 24706f2543Smrg * This file defines functions for drawing some primitives using 25706f2543Smrg * underlying datatypes instead of masks 26706f2543Smrg */ 27706f2543Smrg 28706f2543Smrg#define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000) 29706f2543Smrg 30706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 31706f2543Smrg#include <dix-config.h> 32706f2543Smrg#endif 33706f2543Smrg 34706f2543Smrg#ifdef BITSMUL 35706f2543Smrg#define MUL BITSMUL 36706f2543Smrg#else 37706f2543Smrg#define MUL 1 38706f2543Smrg#endif 39706f2543Smrg 40706f2543Smrg#ifdef BITSSTORE 41706f2543Smrg#define STORE(b,x) BITSSTORE(b,x) 42706f2543Smrg#else 43706f2543Smrg#define STORE(b,x) WRITE((b), (x)) 44706f2543Smrg#endif 45706f2543Smrg 46706f2543Smrg#ifdef BITSRROP 47706f2543Smrg#define RROP(b,a,x) BITSRROP(b,a,x) 48706f2543Smrg#else 49706f2543Smrg#define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x))) 50706f2543Smrg#endif 51706f2543Smrg 52706f2543Smrg#ifdef BITSUNIT 53706f2543Smrg#define UNIT BITSUNIT 54706f2543Smrg#define USE_SOLID 55706f2543Smrg#else 56706f2543Smrg#define UNIT BITS 57706f2543Smrg#endif 58706f2543Smrg 59706f2543Smrg/* 60706f2543Smrg * Define the following before including this file: 61706f2543Smrg * 62706f2543Smrg * BRESSOLID name of function for drawing a solid segment 63706f2543Smrg * BRESDASH name of function for drawing a dashed segment 64706f2543Smrg * DOTS name of function for drawing dots 65706f2543Smrg * ARC name of function for drawing a solid arc 66706f2543Smrg * BITS type of underlying unit 67706f2543Smrg */ 68706f2543Smrg 69706f2543Smrg#ifdef BRESSOLID 70706f2543Smrgvoid 71706f2543SmrgBRESSOLID (DrawablePtr pDrawable, 72706f2543Smrg GCPtr pGC, 73706f2543Smrg int dashOffset, 74706f2543Smrg int signdx, 75706f2543Smrg int signdy, 76706f2543Smrg int axis, 77706f2543Smrg int x1, 78706f2543Smrg int y1, 79706f2543Smrg int e, 80706f2543Smrg int e1, 81706f2543Smrg int e3, 82706f2543Smrg int len) 83706f2543Smrg{ 84706f2543Smrg FbBits *dst; 85706f2543Smrg FbStride dstStride; 86706f2543Smrg int dstBpp; 87706f2543Smrg int dstXoff, dstYoff; 88706f2543Smrg FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); 89706f2543Smrg UNIT *bits; 90706f2543Smrg FbStride bitsStride; 91706f2543Smrg FbStride majorStep, minorStep; 92706f2543Smrg BITS xor = (BITS) pPriv->xor; 93706f2543Smrg 94706f2543Smrg fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 95706f2543Smrg bits = ((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff) * MUL; 96706f2543Smrg bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT)); 97706f2543Smrg if (signdy < 0) 98706f2543Smrg bitsStride = -bitsStride; 99706f2543Smrg if (axis == X_AXIS) 100706f2543Smrg { 101706f2543Smrg majorStep = signdx * MUL; 102706f2543Smrg minorStep = bitsStride; 103706f2543Smrg } 104706f2543Smrg else 105706f2543Smrg { 106706f2543Smrg majorStep = bitsStride; 107706f2543Smrg minorStep = signdx * MUL; 108706f2543Smrg } 109706f2543Smrg while (len--) 110706f2543Smrg { 111706f2543Smrg STORE(bits,xor); 112706f2543Smrg bits += majorStep; 113706f2543Smrg e += e1; 114706f2543Smrg if (e >= 0) 115706f2543Smrg { 116706f2543Smrg bits += minorStep; 117706f2543Smrg e += e3; 118706f2543Smrg } 119706f2543Smrg } 120706f2543Smrg 121706f2543Smrg fbFinishAccess (pDrawable); 122706f2543Smrg} 123706f2543Smrg#endif 124706f2543Smrg 125706f2543Smrg#ifdef BRESDASH 126706f2543Smrgvoid 127706f2543SmrgBRESDASH (DrawablePtr pDrawable, 128706f2543Smrg GCPtr pGC, 129706f2543Smrg int dashOffset, 130706f2543Smrg int signdx, 131706f2543Smrg int signdy, 132706f2543Smrg int axis, 133706f2543Smrg int x1, 134706f2543Smrg int y1, 135706f2543Smrg int e, 136706f2543Smrg int e1, 137706f2543Smrg int e3, 138706f2543Smrg int len) 139706f2543Smrg{ 140706f2543Smrg FbBits *dst; 141706f2543Smrg FbStride dstStride; 142706f2543Smrg int dstBpp; 143706f2543Smrg int dstXoff, dstYoff; 144706f2543Smrg FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); 145706f2543Smrg UNIT *bits; 146706f2543Smrg FbStride bitsStride; 147706f2543Smrg FbStride majorStep, minorStep; 148706f2543Smrg BITS xorfg, xorbg; 149706f2543Smrg FbDashDeclare; 150706f2543Smrg int dashlen; 151706f2543Smrg Bool even; 152706f2543Smrg Bool doOdd; 153706f2543Smrg 154706f2543Smrg fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 155706f2543Smrg doOdd = pGC->lineStyle == LineDoubleDash; 156706f2543Smrg xorfg = (BITS) pPriv->xor; 157706f2543Smrg xorbg = (BITS) pPriv->bgxor; 158706f2543Smrg 159706f2543Smrg FbDashInit (pGC, pPriv, dashOffset, dashlen, even); 160706f2543Smrg 161706f2543Smrg bits = ((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff) * MUL; 162706f2543Smrg bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT)); 163706f2543Smrg if (signdy < 0) 164706f2543Smrg bitsStride = -bitsStride; 165706f2543Smrg if (axis == X_AXIS) 166706f2543Smrg { 167706f2543Smrg majorStep = signdx * MUL; 168706f2543Smrg minorStep = bitsStride; 169706f2543Smrg } 170706f2543Smrg else 171706f2543Smrg { 172706f2543Smrg majorStep = bitsStride; 173706f2543Smrg minorStep = signdx * MUL; 174706f2543Smrg } 175706f2543Smrg if (dashlen >= len) 176706f2543Smrg dashlen = len; 177706f2543Smrg if (doOdd) 178706f2543Smrg { 179706f2543Smrg if (!even) 180706f2543Smrg goto doubleOdd; 181706f2543Smrg for (;;) 182706f2543Smrg { 183706f2543Smrg len -= dashlen; 184706f2543Smrg while (dashlen--) 185706f2543Smrg { 186706f2543Smrg STORE(bits,xorfg); 187706f2543Smrg bits += majorStep; 188706f2543Smrg if ((e += e1) >= 0) 189706f2543Smrg { 190706f2543Smrg e += e3; 191706f2543Smrg bits += minorStep; 192706f2543Smrg } 193706f2543Smrg } 194706f2543Smrg if (!len) 195706f2543Smrg break; 196706f2543Smrg 197706f2543Smrg FbDashNextEven(dashlen); 198706f2543Smrg 199706f2543Smrg if (dashlen >= len) 200706f2543Smrg dashlen = len; 201706f2543SmrgdoubleOdd: 202706f2543Smrg len -= dashlen; 203706f2543Smrg while (dashlen--) 204706f2543Smrg { 205706f2543Smrg STORE(bits,xorbg); 206706f2543Smrg bits += majorStep; 207706f2543Smrg if ((e += e1) >= 0) 208706f2543Smrg { 209706f2543Smrg e += e3; 210706f2543Smrg bits += minorStep; 211706f2543Smrg } 212706f2543Smrg } 213706f2543Smrg if (!len) 214706f2543Smrg break; 215706f2543Smrg 216706f2543Smrg FbDashNextOdd(dashlen); 217706f2543Smrg 218706f2543Smrg if (dashlen >= len) 219706f2543Smrg dashlen = len; 220706f2543Smrg } 221706f2543Smrg } 222706f2543Smrg else 223706f2543Smrg { 224706f2543Smrg if (!even) 225706f2543Smrg goto onOffOdd; 226706f2543Smrg for (;;) 227706f2543Smrg { 228706f2543Smrg len -= dashlen; 229706f2543Smrg while (dashlen--) 230706f2543Smrg { 231706f2543Smrg STORE(bits,xorfg); 232706f2543Smrg bits += majorStep; 233706f2543Smrg if ((e += e1) >= 0) 234706f2543Smrg { 235706f2543Smrg e += e3; 236706f2543Smrg bits += minorStep; 237706f2543Smrg } 238706f2543Smrg } 239706f2543Smrg if (!len) 240706f2543Smrg break; 241706f2543Smrg 242706f2543Smrg FbDashNextEven (dashlen); 243706f2543Smrg 244706f2543Smrg if (dashlen >= len) 245706f2543Smrg dashlen = len; 246706f2543SmrgonOffOdd: 247706f2543Smrg len -= dashlen; 248706f2543Smrg while (dashlen--) 249706f2543Smrg { 250706f2543Smrg bits += majorStep; 251706f2543Smrg if ((e += e1) >= 0) 252706f2543Smrg { 253706f2543Smrg e += e3; 254706f2543Smrg bits += minorStep; 255706f2543Smrg } 256706f2543Smrg } 257706f2543Smrg if (!len) 258706f2543Smrg break; 259706f2543Smrg 260706f2543Smrg FbDashNextOdd (dashlen); 261706f2543Smrg 262706f2543Smrg if (dashlen >= len) 263706f2543Smrg dashlen = len; 264706f2543Smrg } 265706f2543Smrg } 266706f2543Smrg 267706f2543Smrg fbFinishAccess (pDrawable); 268706f2543Smrg} 269706f2543Smrg#endif 270706f2543Smrg 271706f2543Smrg#ifdef DOTS 272706f2543Smrgvoid 273706f2543SmrgDOTS (FbBits *dst, 274706f2543Smrg FbStride dstStride, 275706f2543Smrg int dstBpp, 276706f2543Smrg BoxPtr pBox, 277706f2543Smrg xPoint *ptsOrig, 278706f2543Smrg int npt, 279706f2543Smrg int xorg, 280706f2543Smrg int yorg, 281706f2543Smrg int xoff, 282706f2543Smrg int yoff, 283706f2543Smrg FbBits and, 284706f2543Smrg FbBits xor) 285706f2543Smrg{ 286706f2543Smrg INT32 *pts = (INT32 *) ptsOrig; 287706f2543Smrg UNIT *bits = (UNIT *) dst; 288706f2543Smrg UNIT *point; 289706f2543Smrg BITS bxor = (BITS) xor; 290706f2543Smrg BITS band = (BITS) and; 291706f2543Smrg FbStride bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT)); 292706f2543Smrg INT32 ul, lr; 293706f2543Smrg INT32 pt; 294706f2543Smrg 295706f2543Smrg ul = coordToInt(pBox->x1 - xorg, pBox->y1 - yorg); 296706f2543Smrg lr = coordToInt(pBox->x2 - xorg - 1, pBox->y2 - yorg - 1); 297706f2543Smrg 298706f2543Smrg bits += bitsStride * (yorg + yoff) + (xorg + xoff) * MUL; 299706f2543Smrg 300706f2543Smrg if (and == 0) 301706f2543Smrg { 302706f2543Smrg while (npt--) 303706f2543Smrg { 304706f2543Smrg pt = *pts++; 305706f2543Smrg if (!isClipped(pt,ul,lr)) 306706f2543Smrg { 307706f2543Smrg point = bits + intToY(pt) * bitsStride + intToX(pt) * MUL; 308706f2543Smrg STORE(point,bxor); 309706f2543Smrg } 310706f2543Smrg } 311706f2543Smrg } 312706f2543Smrg else 313706f2543Smrg { 314706f2543Smrg while (npt--) 315706f2543Smrg { 316706f2543Smrg pt = *pts++; 317706f2543Smrg if (!isClipped(pt,ul,lr)) 318706f2543Smrg { 319706f2543Smrg point = bits + intToY(pt) * bitsStride + intToX(pt) * MUL; 320706f2543Smrg RROP(point,band,bxor); 321706f2543Smrg } 322706f2543Smrg } 323706f2543Smrg } 324706f2543Smrg} 325706f2543Smrg#endif 326706f2543Smrg 327706f2543Smrg#ifdef ARC 328706f2543Smrg 329706f2543Smrg#define ARCCOPY(d) STORE(d,xorBits) 330706f2543Smrg#define ARCRROP(d) RROP(d,andBits,xorBits) 331706f2543Smrg 332706f2543Smrgvoid 333706f2543SmrgARC (FbBits *dst, 334706f2543Smrg FbStride dstStride, 335706f2543Smrg int dstBpp, 336706f2543Smrg xArc *arc, 337706f2543Smrg int drawX, 338706f2543Smrg int drawY, 339706f2543Smrg FbBits and, 340706f2543Smrg FbBits xor) 341706f2543Smrg{ 342706f2543Smrg UNIT *bits; 343706f2543Smrg FbStride bitsStride; 344706f2543Smrg miZeroArcRec info; 345706f2543Smrg Bool do360; 346706f2543Smrg int x; 347706f2543Smrg UNIT *yorgp, *yorgop; 348706f2543Smrg BITS andBits, xorBits; 349706f2543Smrg int yoffset, dyoffset; 350706f2543Smrg int y, a, b, d, mask; 351706f2543Smrg int k1, k3, dx, dy; 352706f2543Smrg 353706f2543Smrg bits = (UNIT *) dst; 354706f2543Smrg bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT)); 355706f2543Smrg andBits = (BITS) and; 356706f2543Smrg xorBits = (BITS) xor; 357706f2543Smrg do360 = miZeroArcSetup(arc, &info, TRUE); 358706f2543Smrg yorgp = bits + ((info.yorg + drawY) * bitsStride); 359706f2543Smrg yorgop = bits + ((info.yorgo + drawY) * bitsStride); 360706f2543Smrg info.xorg = (info.xorg + drawX) * MUL; 361706f2543Smrg info.xorgo = (info.xorgo + drawX) * MUL; 362706f2543Smrg MIARCSETUP(); 363706f2543Smrg yoffset = y ? bitsStride : 0; 364706f2543Smrg dyoffset = 0; 365706f2543Smrg mask = info.initialMask; 366706f2543Smrg 367706f2543Smrg if (!(arc->width & 1)) 368706f2543Smrg { 369706f2543Smrg if (andBits == 0) 370706f2543Smrg { 371706f2543Smrg if (mask & 2) 372706f2543Smrg ARCCOPY(yorgp + info.xorgo); 373706f2543Smrg if (mask & 8) 374706f2543Smrg ARCCOPY(yorgop + info.xorgo); 375706f2543Smrg } 376706f2543Smrg else 377706f2543Smrg { 378706f2543Smrg if (mask & 2) 379706f2543Smrg ARCRROP(yorgp + info.xorgo); 380706f2543Smrg if (mask & 8) 381706f2543Smrg ARCRROP(yorgop + info.xorgo); 382706f2543Smrg } 383706f2543Smrg } 384706f2543Smrg if (!info.end.x || !info.end.y) 385706f2543Smrg { 386706f2543Smrg mask = info.end.mask; 387706f2543Smrg info.end = info.altend; 388706f2543Smrg } 389706f2543Smrg if (do360 && (arc->width == arc->height) && !(arc->width & 1)) 390706f2543Smrg { 391706f2543Smrg int xoffset = bitsStride; 392706f2543Smrg UNIT *yorghb = yorgp + (info.h * bitsStride) + info.xorg; 393706f2543Smrg UNIT *yorgohb = yorghb - info.h * MUL; 394706f2543Smrg 395706f2543Smrg yorgp += info.xorg; 396706f2543Smrg yorgop += info.xorg; 397706f2543Smrg yorghb += info.h * MUL; 398706f2543Smrg while (1) 399706f2543Smrg { 400706f2543Smrg if (andBits == 0) 401706f2543Smrg { 402706f2543Smrg ARCCOPY(yorgp + yoffset + x * MUL); 403706f2543Smrg ARCCOPY(yorgp + yoffset - x * MUL); 404706f2543Smrg ARCCOPY(yorgop - yoffset - x * MUL); 405706f2543Smrg ARCCOPY(yorgop - yoffset + x * MUL); 406706f2543Smrg } 407706f2543Smrg else 408706f2543Smrg { 409706f2543Smrg ARCRROP(yorgp + yoffset + x * MUL); 410706f2543Smrg ARCRROP(yorgp + yoffset - x * MUL); 411706f2543Smrg ARCRROP(yorgop - yoffset - x * MUL); 412706f2543Smrg ARCRROP(yorgop - yoffset + x * MUL); 413706f2543Smrg } 414706f2543Smrg if (a < 0) 415706f2543Smrg break; 416706f2543Smrg if (andBits == 0) 417706f2543Smrg { 418706f2543Smrg ARCCOPY(yorghb - xoffset - y * MUL); 419706f2543Smrg ARCCOPY(yorgohb - xoffset + y * MUL); 420706f2543Smrg ARCCOPY(yorgohb + xoffset + y * MUL); 421706f2543Smrg ARCCOPY(yorghb + xoffset - y * MUL); 422706f2543Smrg } 423706f2543Smrg else 424706f2543Smrg { 425706f2543Smrg ARCRROP(yorghb - xoffset - y * MUL); 426706f2543Smrg ARCRROP(yorgohb - xoffset + y * MUL); 427706f2543Smrg ARCRROP(yorgohb + xoffset + y * MUL); 428706f2543Smrg ARCRROP(yorghb + xoffset - y * MUL); 429706f2543Smrg } 430706f2543Smrg xoffset += bitsStride; 431706f2543Smrg MIARCCIRCLESTEP(yoffset += bitsStride;); 432706f2543Smrg } 433706f2543Smrg yorgp -= info.xorg; 434706f2543Smrg yorgop -= info.xorg; 435706f2543Smrg x = info.w; 436706f2543Smrg yoffset = info.h * bitsStride; 437706f2543Smrg } 438706f2543Smrg else if (do360) 439706f2543Smrg { 440706f2543Smrg while (y < info.h || x < info.w) 441706f2543Smrg { 442706f2543Smrg MIARCOCTANTSHIFT(dyoffset = bitsStride;); 443706f2543Smrg if (andBits == 0) 444706f2543Smrg { 445706f2543Smrg ARCCOPY(yorgp + yoffset + info.xorg + x * MUL); 446706f2543Smrg ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL); 447706f2543Smrg ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL); 448706f2543Smrg ARCCOPY(yorgop - yoffset + info.xorg + x * MUL); 449706f2543Smrg } 450706f2543Smrg else 451706f2543Smrg { 452706f2543Smrg ARCRROP(yorgp + yoffset + info.xorg + x * MUL); 453706f2543Smrg ARCRROP(yorgp + yoffset + info.xorgo - x * MUL); 454706f2543Smrg ARCRROP(yorgop - yoffset + info.xorgo - x * MUL); 455706f2543Smrg ARCRROP(yorgop - yoffset + info.xorg + x * MUL); 456706f2543Smrg } 457706f2543Smrg MIARCSTEP(yoffset += dyoffset;, yoffset += bitsStride;); 458706f2543Smrg } 459706f2543Smrg } 460706f2543Smrg else 461706f2543Smrg { 462706f2543Smrg while (y < info.h || x < info.w) 463706f2543Smrg { 464706f2543Smrg MIARCOCTANTSHIFT(dyoffset = bitsStride;); 465706f2543Smrg if ((x == info.start.x) || (y == info.start.y)) 466706f2543Smrg { 467706f2543Smrg mask = info.start.mask; 468706f2543Smrg info.start = info.altstart; 469706f2543Smrg } 470706f2543Smrg if (andBits == 0) 471706f2543Smrg { 472706f2543Smrg if (mask & 1) 473706f2543Smrg ARCCOPY(yorgp + yoffset + info.xorg + x * MUL); 474706f2543Smrg if (mask & 2) 475706f2543Smrg ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL); 476706f2543Smrg if (mask & 4) 477706f2543Smrg ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL); 478706f2543Smrg if (mask & 8) 479706f2543Smrg ARCCOPY(yorgop - yoffset + info.xorg + x * MUL); 480706f2543Smrg } 481706f2543Smrg else 482706f2543Smrg { 483706f2543Smrg if (mask & 1) 484706f2543Smrg ARCRROP(yorgp + yoffset + info.xorg + x * MUL); 485706f2543Smrg if (mask & 2) 486706f2543Smrg ARCRROP(yorgp + yoffset + info.xorgo - x * MUL); 487706f2543Smrg if (mask & 4) 488706f2543Smrg ARCRROP(yorgop - yoffset + info.xorgo - x * MUL); 489706f2543Smrg if (mask & 8) 490706f2543Smrg ARCRROP(yorgop - yoffset + info.xorg + x * MUL); 491706f2543Smrg } 492706f2543Smrg if ((x == info.end.x) || (y == info.end.y)) 493706f2543Smrg { 494706f2543Smrg mask = info.end.mask; 495706f2543Smrg info.end = info.altend; 496706f2543Smrg } 497706f2543Smrg MIARCSTEP(yoffset += dyoffset;, yoffset += bitsStride;); 498706f2543Smrg } 499706f2543Smrg } 500706f2543Smrg if ((x == info.start.x) || (y == info.start.y)) 501706f2543Smrg mask = info.start.mask; 502706f2543Smrg if (andBits == 0) 503706f2543Smrg { 504706f2543Smrg if (mask & 1) 505706f2543Smrg ARCCOPY(yorgp + yoffset + info.xorg + x * MUL); 506706f2543Smrg if (mask & 4) 507706f2543Smrg ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL); 508706f2543Smrg if (arc->height & 1) 509706f2543Smrg { 510706f2543Smrg if (mask & 2) 511706f2543Smrg ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL); 512706f2543Smrg if (mask & 8) 513706f2543Smrg ARCCOPY(yorgop - yoffset + info.xorg + x * MUL); 514706f2543Smrg } 515706f2543Smrg } 516706f2543Smrg else 517706f2543Smrg { 518706f2543Smrg if (mask & 1) 519706f2543Smrg ARCRROP(yorgp + yoffset + info.xorg + x * MUL); 520706f2543Smrg if (mask & 4) 521706f2543Smrg ARCRROP(yorgop - yoffset + info.xorgo - x * MUL); 522706f2543Smrg if (arc->height & 1) 523706f2543Smrg { 524706f2543Smrg if (mask & 2) 525706f2543Smrg ARCRROP(yorgp + yoffset + info.xorgo - x * MUL); 526706f2543Smrg if (mask & 8) 527706f2543Smrg ARCRROP(yorgop - yoffset + info.xorg + x * MUL); 528706f2543Smrg } 529706f2543Smrg } 530706f2543Smrg} 531706f2543Smrg#undef ARCCOPY 532706f2543Smrg#undef ARCRROP 533706f2543Smrg#endif 534706f2543Smrg 535706f2543Smrg#ifdef GLYPH 536706f2543Smrg#if BITMAP_BIT_ORDER == LSBFirst 537706f2543Smrg# define WRITE_ADDR1(n) (n) 538706f2543Smrg# define WRITE_ADDR2(n) (n) 539706f2543Smrg# define WRITE_ADDR4(n) (n) 540706f2543Smrg#else 541706f2543Smrg# define WRITE_ADDR1(n) ((n) ^ 3) 542706f2543Smrg# define WRITE_ADDR2(n) ((n) ^ 2) 543706f2543Smrg# define WRITE_ADDR4(n) ((n)) 544706f2543Smrg#endif 545706f2543Smrg 546706f2543Smrg#define WRITE1(d,n,fg) WRITE(d + WRITE_ADDR1(n), (BITS) (fg)) 547706f2543Smrg 548706f2543Smrg#ifdef BITS2 549706f2543Smrg# define WRITE2(d,n,fg) WRITE((BITS2 *) &((d)[WRITE_ADDR2(n)]), (BITS2) (fg)) 550706f2543Smrg#else 551706f2543Smrg# define WRITE2(d,n,fg) (WRITE1(d,n,fg), WRITE1(d,(n)+1,fg)) 552706f2543Smrg#endif 553706f2543Smrg 554706f2543Smrg#ifdef BITS4 555706f2543Smrg# define WRITE4(d,n,fg) WRITE((BITS4 *) &((d)[WRITE_ADDR4(n)]), (BITS4) (fg)) 556706f2543Smrg#else 557706f2543Smrg# define WRITE4(d,n,fg) (WRITE2(d,n,fg), WRITE2(d,(n)+2,fg)) 558706f2543Smrg#endif 559706f2543Smrg 560706f2543Smrgvoid 561706f2543SmrgGLYPH (FbBits *dstBits, 562706f2543Smrg FbStride dstStride, 563706f2543Smrg int dstBpp, 564706f2543Smrg FbStip *stipple, 565706f2543Smrg FbBits fg, 566706f2543Smrg int x, 567706f2543Smrg int height) 568706f2543Smrg{ 569706f2543Smrg int lshift; 570706f2543Smrg FbStip bits; 571706f2543Smrg BITS *dstLine; 572706f2543Smrg BITS *dst; 573706f2543Smrg int n; 574706f2543Smrg int shift; 575706f2543Smrg 576706f2543Smrg dstLine = (BITS *) dstBits; 577706f2543Smrg dstLine += x & ~3; 578706f2543Smrg dstStride *= (sizeof (FbBits) / sizeof (BITS)); 579706f2543Smrg shift = x & 3; 580706f2543Smrg lshift = 4 - shift; 581706f2543Smrg while (height--) 582706f2543Smrg { 583706f2543Smrg bits = *stipple++; 584706f2543Smrg dst = (BITS *) dstLine; 585706f2543Smrg n = lshift; 586706f2543Smrg while (bits) 587706f2543Smrg { 588706f2543Smrg switch (FbStipMoveLsb (FbLeftStipBits (bits, n), 4, n)) { 589706f2543Smrg case 0: 590706f2543Smrg break; 591706f2543Smrg case 1: 592706f2543Smrg WRITE1(dst,0,fg); 593706f2543Smrg break; 594706f2543Smrg case 2: 595706f2543Smrg WRITE1(dst,1,fg); 596706f2543Smrg break; 597706f2543Smrg case 3: 598706f2543Smrg WRITE2(dst,0,fg); 599706f2543Smrg break; 600706f2543Smrg case 4: 601706f2543Smrg WRITE1(dst,2,fg); 602706f2543Smrg break; 603706f2543Smrg case 5: 604706f2543Smrg WRITE1(dst,0,fg); 605706f2543Smrg WRITE1(dst,2,fg); 606706f2543Smrg break; 607706f2543Smrg case 6: 608706f2543Smrg WRITE1(dst,1,fg); 609706f2543Smrg WRITE1(dst,2,fg); 610706f2543Smrg break; 611706f2543Smrg case 7: 612706f2543Smrg WRITE2(dst,0,fg); 613706f2543Smrg WRITE1(dst,2,fg); 614706f2543Smrg break; 615706f2543Smrg case 8: 616706f2543Smrg WRITE1(dst,3,fg); 617706f2543Smrg break; 618706f2543Smrg case 9: 619706f2543Smrg WRITE1(dst,0,fg); 620706f2543Smrg WRITE1(dst,3,fg); 621706f2543Smrg break; 622706f2543Smrg case 10: 623706f2543Smrg WRITE1(dst,1,fg); 624706f2543Smrg WRITE1(dst,3,fg); 625706f2543Smrg break; 626706f2543Smrg case 11: 627706f2543Smrg WRITE2(dst,0,fg); 628706f2543Smrg WRITE1(dst,3,fg); 629706f2543Smrg break; 630706f2543Smrg case 12: 631706f2543Smrg WRITE2(dst,2,fg); 632706f2543Smrg break; 633706f2543Smrg case 13: 634706f2543Smrg WRITE1(dst,0,fg); 635706f2543Smrg WRITE2(dst,2,fg); 636706f2543Smrg break; 637706f2543Smrg case 14: 638706f2543Smrg WRITE1(dst,1,fg); 639706f2543Smrg WRITE2(dst,2,fg); 640706f2543Smrg break; 641706f2543Smrg case 15: 642706f2543Smrg WRITE4(dst,0,fg); 643706f2543Smrg break; 644706f2543Smrg } 645706f2543Smrg bits = FbStipLeft (bits, n); 646706f2543Smrg n = 4; 647706f2543Smrg dst += 4; 648706f2543Smrg } 649706f2543Smrg dstLine += dstStride; 650706f2543Smrg } 651706f2543Smrg} 652706f2543Smrg#undef WRITE_ADDR1 653706f2543Smrg#undef WRITE_ADDR2 654706f2543Smrg#undef WRITE_ADDR4 655706f2543Smrg#undef WRITE1 656706f2543Smrg#undef WRITE2 657706f2543Smrg#undef WRITE4 658706f2543Smrg 659706f2543Smrg#endif 660706f2543Smrg 661706f2543Smrg#ifdef POLYLINE 662706f2543Smrgvoid 663706f2543SmrgPOLYLINE (DrawablePtr pDrawable, 664706f2543Smrg GCPtr pGC, 665706f2543Smrg int mode, 666706f2543Smrg int npt, 667706f2543Smrg DDXPointPtr ptsOrig) 668706f2543Smrg{ 669706f2543Smrg INT32 *pts = (INT32 *) ptsOrig; 670706f2543Smrg int xoff = pDrawable->x; 671706f2543Smrg int yoff = pDrawable->y; 672706f2543Smrg unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); 673706f2543Smrg BoxPtr pBox = RegionExtents(fbGetCompositeClip (pGC)); 674706f2543Smrg 675706f2543Smrg FbBits *dst; 676706f2543Smrg int dstStride; 677706f2543Smrg int dstBpp; 678706f2543Smrg int dstXoff, dstYoff; 679706f2543Smrg 680706f2543Smrg UNIT *bits, *bitsBase; 681706f2543Smrg FbStride bitsStride; 682706f2543Smrg BITS xor = fbGetGCPrivate(pGC)->xor; 683706f2543Smrg BITS and = fbGetGCPrivate(pGC)->and; 684706f2543Smrg int dashoffset = 0; 685706f2543Smrg 686706f2543Smrg INT32 ul, lr; 687706f2543Smrg INT32 pt1, pt2; 688706f2543Smrg 689706f2543Smrg int e, e1, e3, len; 690706f2543Smrg int stepmajor, stepminor; 691706f2543Smrg int octant; 692706f2543Smrg 693706f2543Smrg if (mode == CoordModePrevious) 694706f2543Smrg fbFixCoordModePrevious (npt, ptsOrig); 695706f2543Smrg 696706f2543Smrg fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 697706f2543Smrg bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT)); 698706f2543Smrg bitsBase = ((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff) * MUL; 699706f2543Smrg ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff); 700706f2543Smrg lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1); 701706f2543Smrg 702706f2543Smrg pt1 = *pts++; 703706f2543Smrg npt--; 704706f2543Smrg pt2 = *pts++; 705706f2543Smrg npt--; 706706f2543Smrg for (;;) 707706f2543Smrg { 708706f2543Smrg if (isClipped (pt1, ul, lr) | isClipped (pt2, ul, lr)) 709706f2543Smrg { 710706f2543Smrg fbSegment (pDrawable, pGC, 711706f2543Smrg intToX(pt1) + xoff, intToY(pt1) + yoff, 712706f2543Smrg intToX(pt2) + xoff, intToY(pt2) + yoff, 713706f2543Smrg npt == 0 && pGC->capStyle != CapNotLast, 714706f2543Smrg &dashoffset); 715706f2543Smrg if (!npt) { 716706f2543Smrg fbFinishAccess (pDrawable); 717706f2543Smrg return; 718706f2543Smrg } 719706f2543Smrg pt1 = pt2; 720706f2543Smrg pt2 = *pts++; 721706f2543Smrg npt--; 722706f2543Smrg } 723706f2543Smrg else 724706f2543Smrg { 725706f2543Smrg bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1) * MUL; 726706f2543Smrg for (;;) 727706f2543Smrg { 728706f2543Smrg CalcLineDeltas (intToX(pt1), intToY(pt1), 729706f2543Smrg intToX(pt2), intToY(pt2), 730706f2543Smrg len, e1, stepmajor, stepminor, 1, bitsStride, 731706f2543Smrg octant); 732706f2543Smrg stepmajor *= MUL; 733706f2543Smrg if (len < e1) 734706f2543Smrg { 735706f2543Smrg e3 = len; 736706f2543Smrg len = e1; 737706f2543Smrg e1 = e3; 738706f2543Smrg 739706f2543Smrg e3 = stepminor; 740706f2543Smrg stepminor = stepmajor; 741706f2543Smrg stepmajor = e3; 742706f2543Smrg SetYMajorOctant(octant); 743706f2543Smrg } 744706f2543Smrg e = -len; 745706f2543Smrg e1 <<= 1; 746706f2543Smrg e3 = e << 1; 747706f2543Smrg FIXUP_ERROR (e, octant, bias); 748706f2543Smrg if (and == 0) 749706f2543Smrg { 750706f2543Smrg while (len--) 751706f2543Smrg { 752706f2543Smrg STORE(bits,xor); 753706f2543Smrg bits += stepmajor; 754706f2543Smrg e += e1; 755706f2543Smrg if (e >= 0) 756706f2543Smrg { 757706f2543Smrg bits += stepminor; 758706f2543Smrg e += e3; 759706f2543Smrg } 760706f2543Smrg } 761706f2543Smrg } 762706f2543Smrg else 763706f2543Smrg { 764706f2543Smrg while (len--) 765706f2543Smrg { 766706f2543Smrg RROP(bits,and,xor); 767706f2543Smrg bits += stepmajor; 768706f2543Smrg e += e1; 769706f2543Smrg if (e >= 0) 770706f2543Smrg { 771706f2543Smrg bits += stepminor; 772706f2543Smrg e += e3; 773706f2543Smrg } 774706f2543Smrg } 775706f2543Smrg } 776706f2543Smrg if (!npt) 777706f2543Smrg { 778706f2543Smrg if (pGC->capStyle != CapNotLast && 779706f2543Smrg pt2 != *((INT32 *) ptsOrig)) 780706f2543Smrg { 781706f2543Smrg RROP(bits,and,xor); 782706f2543Smrg } 783706f2543Smrg fbFinishAccess (pDrawable); 784706f2543Smrg return; 785706f2543Smrg } 786706f2543Smrg pt1 = pt2; 787706f2543Smrg pt2 = *pts++; 788706f2543Smrg --npt; 789706f2543Smrg if (isClipped (pt2, ul, lr)) 790706f2543Smrg break; 791706f2543Smrg } 792706f2543Smrg } 793706f2543Smrg } 794706f2543Smrg 795706f2543Smrg fbFinishAccess (pDrawable); 796706f2543Smrg} 797706f2543Smrg#endif 798706f2543Smrg 799706f2543Smrg#ifdef POLYSEGMENT 800706f2543Smrgvoid 801706f2543SmrgPOLYSEGMENT (DrawablePtr pDrawable, 802706f2543Smrg GCPtr pGC, 803706f2543Smrg int nseg, 804706f2543Smrg xSegment *pseg) 805706f2543Smrg{ 806706f2543Smrg INT32 *pts = (INT32 *) pseg; 807706f2543Smrg int xoff = pDrawable->x; 808706f2543Smrg int yoff = pDrawable->y; 809706f2543Smrg unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); 810706f2543Smrg BoxPtr pBox = RegionExtents(fbGetCompositeClip (pGC)); 811706f2543Smrg 812706f2543Smrg FbBits *dst; 813706f2543Smrg int dstStride; 814706f2543Smrg int dstBpp; 815706f2543Smrg int dstXoff, dstYoff; 816706f2543Smrg 817706f2543Smrg UNIT *bits, *bitsBase; 818706f2543Smrg FbStride bitsStride; 819706f2543Smrg FbBits xorBits = fbGetGCPrivate(pGC)->xor; 820706f2543Smrg FbBits andBits = fbGetGCPrivate(pGC)->and; 821706f2543Smrg BITS xor = xorBits; 822706f2543Smrg BITS and = andBits; 823706f2543Smrg int dashoffset = 0; 824706f2543Smrg 825706f2543Smrg INT32 ul, lr; 826706f2543Smrg INT32 pt1, pt2; 827706f2543Smrg 828706f2543Smrg int e, e1, e3, len; 829706f2543Smrg int stepmajor, stepminor; 830706f2543Smrg int octant; 831706f2543Smrg Bool capNotLast; 832706f2543Smrg 833706f2543Smrg fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 834706f2543Smrg bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT)); 835706f2543Smrg bitsBase = ((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff) * MUL; 836706f2543Smrg ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff); 837706f2543Smrg lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1); 838706f2543Smrg 839706f2543Smrg capNotLast = pGC->capStyle == CapNotLast; 840706f2543Smrg 841706f2543Smrg while (nseg--) 842706f2543Smrg { 843706f2543Smrg pt1 = *pts++; 844706f2543Smrg pt2 = *pts++; 845706f2543Smrg if (isClipped (pt1, ul, lr) | isClipped (pt2, ul, lr)) 846706f2543Smrg { 847706f2543Smrg fbSegment (pDrawable, pGC, 848706f2543Smrg intToX(pt1) + xoff, intToY(pt1) + yoff, 849706f2543Smrg intToX(pt2) + xoff, intToY(pt2) + yoff, 850706f2543Smrg !capNotLast, &dashoffset); 851706f2543Smrg } 852706f2543Smrg else 853706f2543Smrg { 854706f2543Smrg CalcLineDeltas (intToX(pt1), intToY(pt1), 855706f2543Smrg intToX(pt2), intToY(pt2), 856706f2543Smrg len, e1, stepmajor, stepminor, 1, bitsStride, 857706f2543Smrg octant); 858706f2543Smrg if (e1 == 0 && len > 3 859706f2543Smrg#if MUL != 1 860706f2543Smrg && FbCheck24Pix(and) && FbCheck24Pix(xor) 861706f2543Smrg#endif 862706f2543Smrg ) 863706f2543Smrg { 864706f2543Smrg int x1, x2; 865706f2543Smrg FbBits *dstLine; 866706f2543Smrg int dstX, width; 867706f2543Smrg FbBits startmask, endmask; 868706f2543Smrg int nmiddle; 869706f2543Smrg 870706f2543Smrg if (stepmajor < 0) 871706f2543Smrg { 872706f2543Smrg x1 = intToX(pt2); 873706f2543Smrg x2 = intToX(pt1) + 1; 874706f2543Smrg if (capNotLast) 875706f2543Smrg x1++; 876706f2543Smrg } 877706f2543Smrg else 878706f2543Smrg { 879706f2543Smrg x1 = intToX(pt1); 880706f2543Smrg x2 = intToX(pt2); 881706f2543Smrg if (!capNotLast) 882706f2543Smrg x2++; 883706f2543Smrg } 884706f2543Smrg dstX = (x1 + xoff + dstXoff) * (sizeof (UNIT) * 8 * MUL); 885706f2543Smrg width = (x2 - x1) * (sizeof (UNIT) * 8 * MUL); 886706f2543Smrg 887706f2543Smrg dstLine = dst + (intToY(pt1) + yoff + dstYoff) * dstStride; 888706f2543Smrg dstLine += dstX >> FB_SHIFT; 889706f2543Smrg dstX &= FB_MASK; 890706f2543Smrg FbMaskBits (dstX, width, startmask, nmiddle, endmask); 891706f2543Smrg if (startmask) 892706f2543Smrg { 893706f2543Smrg WRITE(dstLine, FbDoMaskRRop (READ(dstLine), andBits, xorBits, startmask)); 894706f2543Smrg dstLine++; 895706f2543Smrg } 896706f2543Smrg if (!andBits) 897706f2543Smrg while (nmiddle--) 898706f2543Smrg WRITE(dstLine++, xorBits); 899706f2543Smrg else 900706f2543Smrg while (nmiddle--) 901706f2543Smrg { 902706f2543Smrg WRITE(dstLine, FbDoRRop (READ(dstLine), andBits, xorBits)); 903706f2543Smrg dstLine++; 904706f2543Smrg } 905706f2543Smrg if (endmask) 906706f2543Smrg WRITE(dstLine, FbDoMaskRRop (READ(dstLine), andBits, xorBits, endmask)); 907706f2543Smrg } 908706f2543Smrg else 909706f2543Smrg { 910706f2543Smrg stepmajor *= MUL; 911706f2543Smrg bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1) * MUL; 912706f2543Smrg if (len < e1) 913706f2543Smrg { 914706f2543Smrg e3 = len; 915706f2543Smrg len = e1; 916706f2543Smrg e1 = e3; 917706f2543Smrg 918706f2543Smrg e3 = stepminor; 919706f2543Smrg stepminor = stepmajor; 920706f2543Smrg stepmajor = e3; 921706f2543Smrg SetYMajorOctant(octant); 922706f2543Smrg } 923706f2543Smrg e = -len; 924706f2543Smrg e1 <<= 1; 925706f2543Smrg e3 = e << 1; 926706f2543Smrg FIXUP_ERROR (e, octant, bias); 927706f2543Smrg if (!capNotLast) 928706f2543Smrg len++; 929706f2543Smrg if (and == 0) 930706f2543Smrg { 931706f2543Smrg while (len--) 932706f2543Smrg { 933706f2543Smrg STORE(bits,xor); 934706f2543Smrg bits += stepmajor; 935706f2543Smrg e += e1; 936706f2543Smrg if (e >= 0) 937706f2543Smrg { 938706f2543Smrg bits += stepminor; 939706f2543Smrg e += e3; 940706f2543Smrg } 941706f2543Smrg } 942706f2543Smrg } 943706f2543Smrg else 944706f2543Smrg { 945706f2543Smrg while (len--) 946706f2543Smrg { 947706f2543Smrg RROP(bits,and,xor); 948706f2543Smrg bits += stepmajor; 949706f2543Smrg e += e1; 950706f2543Smrg if (e >= 0) 951706f2543Smrg { 952706f2543Smrg bits += stepminor; 953706f2543Smrg e += e3; 954706f2543Smrg } 955706f2543Smrg } 956706f2543Smrg } 957706f2543Smrg } 958706f2543Smrg } 959706f2543Smrg } 960706f2543Smrg 961706f2543Smrg fbFinishAccess (pDrawable); 962706f2543Smrg} 963706f2543Smrg#endif 964706f2543Smrg 965706f2543Smrg#undef MUL 966706f2543Smrg#undef STORE 967706f2543Smrg#undef RROP 968706f2543Smrg#undef UNIT 969706f2543Smrg#undef USE_SOLID 970706f2543Smrg 971706f2543Smrg#undef isClipped 972