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#ifdef HAVE_DIX_CONFIG_H 24706f2543Smrg#include <dix-config.h> 25706f2543Smrg#endif 26706f2543Smrg 27706f2543Smrg#include <stdlib.h> 28706f2543Smrg 29706f2543Smrg#include "fb.h" 30706f2543Smrg#include "miline.h" 31706f2543Smrg 32706f2543Smrg#define fbBresShiftMask(mask,dir,bpp) ((bpp == FB_STIP_UNIT) ? 0 : \ 33706f2543Smrg ((dir < 0) ? FbStipLeft(mask,bpp) : \ 34706f2543Smrg FbStipRight(mask,bpp))) 35706f2543Smrg 36706f2543Smrgvoid 37706f2543SmrgfbBresSolid (DrawablePtr pDrawable, 38706f2543Smrg GCPtr pGC, 39706f2543Smrg int dashOffset, 40706f2543Smrg int signdx, 41706f2543Smrg int signdy, 42706f2543Smrg int axis, 43706f2543Smrg int x1, 44706f2543Smrg int y1, 45706f2543Smrg int e, 46706f2543Smrg int e1, 47706f2543Smrg int e3, 48706f2543Smrg int len) 49706f2543Smrg{ 50706f2543Smrg FbStip *dst; 51706f2543Smrg FbStride dstStride; 52706f2543Smrg int dstBpp; 53706f2543Smrg int dstXoff, dstYoff; 54706f2543Smrg FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); 55706f2543Smrg FbStip and = (FbStip) pPriv->and; 56706f2543Smrg FbStip xor = (FbStip) pPriv->xor; 57706f2543Smrg FbStip mask, mask0; 58706f2543Smrg FbStip bits; 59706f2543Smrg 60706f2543Smrg fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 61706f2543Smrg dst += ((y1 + dstYoff) * dstStride); 62706f2543Smrg x1 = (x1 + dstXoff) * dstBpp; 63706f2543Smrg dst += x1 >> FB_STIP_SHIFT; 64706f2543Smrg x1 &= FB_STIP_MASK; 65706f2543Smrg mask0 = FbStipMask(0, dstBpp); 66706f2543Smrg mask = FbStipRight (mask0, x1); 67706f2543Smrg if (signdx < 0) 68706f2543Smrg mask0 = FbStipRight (mask0, FB_STIP_UNIT - dstBpp); 69706f2543Smrg if (signdy < 0) 70706f2543Smrg dstStride = -dstStride; 71706f2543Smrg if (axis == X_AXIS) 72706f2543Smrg { 73706f2543Smrg bits = 0; 74706f2543Smrg while (len--) 75706f2543Smrg { 76706f2543Smrg bits |= mask; 77706f2543Smrg mask = fbBresShiftMask(mask,signdx,dstBpp); 78706f2543Smrg if (!mask) 79706f2543Smrg { 80706f2543Smrg WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, bits)); 81706f2543Smrg bits = 0; 82706f2543Smrg dst += signdx; 83706f2543Smrg mask = mask0; 84706f2543Smrg } 85706f2543Smrg e += e1; 86706f2543Smrg if (e >= 0) 87706f2543Smrg { 88706f2543Smrg WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, bits)); 89706f2543Smrg bits = 0; 90706f2543Smrg dst += dstStride; 91706f2543Smrg e += e3; 92706f2543Smrg } 93706f2543Smrg } 94706f2543Smrg if (bits) 95706f2543Smrg WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, bits)); 96706f2543Smrg } 97706f2543Smrg else 98706f2543Smrg { 99706f2543Smrg while (len--) 100706f2543Smrg { 101706f2543Smrg WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, mask)); 102706f2543Smrg dst += dstStride; 103706f2543Smrg e += e1; 104706f2543Smrg if (e >= 0) 105706f2543Smrg { 106706f2543Smrg e += e3; 107706f2543Smrg mask = fbBresShiftMask(mask,signdx,dstBpp); 108706f2543Smrg if (!mask) 109706f2543Smrg { 110706f2543Smrg dst += signdx; 111706f2543Smrg mask = mask0; 112706f2543Smrg } 113706f2543Smrg } 114706f2543Smrg } 115706f2543Smrg } 116706f2543Smrg 117706f2543Smrg fbFinishAccess (pDrawable); 118706f2543Smrg} 119706f2543Smrg 120706f2543Smrgvoid 121706f2543SmrgfbBresDash (DrawablePtr pDrawable, 122706f2543Smrg GCPtr pGC, 123706f2543Smrg int dashOffset, 124706f2543Smrg int signdx, 125706f2543Smrg int signdy, 126706f2543Smrg int axis, 127706f2543Smrg int x1, 128706f2543Smrg int y1, 129706f2543Smrg int e, 130706f2543Smrg int e1, 131706f2543Smrg int e3, 132706f2543Smrg int len) 133706f2543Smrg{ 134706f2543Smrg FbStip *dst; 135706f2543Smrg FbStride dstStride; 136706f2543Smrg int dstBpp; 137706f2543Smrg int dstXoff, dstYoff; 138706f2543Smrg FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); 139706f2543Smrg FbStip and = (FbStip) pPriv->and; 140706f2543Smrg FbStip xor = (FbStip) pPriv->xor; 141706f2543Smrg FbStip bgand = (FbStip) pPriv->bgand; 142706f2543Smrg FbStip bgxor = (FbStip) pPriv->bgxor; 143706f2543Smrg FbStip mask, mask0; 144706f2543Smrg FbDashDeclare; 145706f2543Smrg int dashlen; 146706f2543Smrg Bool even; 147706f2543Smrg Bool doOdd; 148706f2543Smrg 149706f2543Smrg fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 150706f2543Smrg doOdd = pGC->lineStyle == LineDoubleDash; 151706f2543Smrg 152706f2543Smrg FbDashInit (pGC, pPriv, dashOffset, dashlen, even); 153706f2543Smrg 154706f2543Smrg dst += ((y1 + dstYoff) * dstStride); 155706f2543Smrg x1 = (x1 + dstXoff) * dstBpp; 156706f2543Smrg dst += x1 >> FB_STIP_SHIFT; 157706f2543Smrg x1 &= FB_STIP_MASK; 158706f2543Smrg mask0 = FbStipMask(0, dstBpp); 159706f2543Smrg mask = FbStipRight (mask0, x1); 160706f2543Smrg if (signdx < 0) 161706f2543Smrg mask0 = FbStipRight (mask0, FB_STIP_UNIT - dstBpp); 162706f2543Smrg if (signdy < 0) 163706f2543Smrg dstStride = -dstStride; 164706f2543Smrg while (len--) 165706f2543Smrg { 166706f2543Smrg if (even) 167706f2543Smrg WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, mask)); 168706f2543Smrg else if (doOdd) 169706f2543Smrg WRITE(dst, FbDoMaskRRop (READ(dst), bgand, bgxor, mask)); 170706f2543Smrg if (axis == X_AXIS) 171706f2543Smrg { 172706f2543Smrg mask = fbBresShiftMask(mask,signdx,dstBpp); 173706f2543Smrg if (!mask) 174706f2543Smrg { 175706f2543Smrg dst += signdx; 176706f2543Smrg mask = mask0; 177706f2543Smrg } 178706f2543Smrg e += e1; 179706f2543Smrg if (e >= 0) 180706f2543Smrg { 181706f2543Smrg dst += dstStride; 182706f2543Smrg e += e3; 183706f2543Smrg } 184706f2543Smrg } 185706f2543Smrg else 186706f2543Smrg { 187706f2543Smrg dst += dstStride; 188706f2543Smrg e += e1; 189706f2543Smrg if (e >= 0) 190706f2543Smrg { 191706f2543Smrg e += e3; 192706f2543Smrg mask = fbBresShiftMask(mask,signdx,dstBpp); 193706f2543Smrg if (!mask) 194706f2543Smrg { 195706f2543Smrg dst += signdx; 196706f2543Smrg mask = mask0; 197706f2543Smrg } 198706f2543Smrg } 199706f2543Smrg } 200706f2543Smrg FbDashStep (dashlen, even); 201706f2543Smrg } 202706f2543Smrg 203706f2543Smrg fbFinishAccess (pDrawable); 204706f2543Smrg} 205706f2543Smrg 206706f2543Smrgvoid 207706f2543SmrgfbBresFill (DrawablePtr pDrawable, 208706f2543Smrg GCPtr pGC, 209706f2543Smrg int dashOffset, 210706f2543Smrg int signdx, 211706f2543Smrg int signdy, 212706f2543Smrg int axis, 213706f2543Smrg int x1, 214706f2543Smrg int y1, 215706f2543Smrg int e, 216706f2543Smrg int e1, 217706f2543Smrg int e3, 218706f2543Smrg int len) 219706f2543Smrg{ 220706f2543Smrg while (len--) 221706f2543Smrg { 222706f2543Smrg fbFill (pDrawable, pGC, x1, y1, 1, 1); 223706f2543Smrg if (axis == X_AXIS) 224706f2543Smrg { 225706f2543Smrg x1 += signdx; 226706f2543Smrg e += e1; 227706f2543Smrg if (e >= 0) 228706f2543Smrg { 229706f2543Smrg e += e3; 230706f2543Smrg y1 += signdy; 231706f2543Smrg } 232706f2543Smrg } 233706f2543Smrg else 234706f2543Smrg { 235706f2543Smrg y1 += signdy; 236706f2543Smrg e += e1; 237706f2543Smrg if (e >= 0) 238706f2543Smrg { 239706f2543Smrg e += e3; 240706f2543Smrg x1 += signdx; 241706f2543Smrg } 242706f2543Smrg } 243706f2543Smrg } 244706f2543Smrg} 245706f2543Smrg 246706f2543Smrgstatic void 247706f2543SmrgfbSetFg (DrawablePtr pDrawable, 248706f2543Smrg GCPtr pGC, 249706f2543Smrg Pixel fg) 250706f2543Smrg{ 251706f2543Smrg if (fg != pGC->fgPixel) 252706f2543Smrg { 253706f2543Smrg ChangeGCVal val; 254706f2543Smrg val.val = fg; 255706f2543Smrg ChangeGC (NullClient, pGC, GCForeground, &val); 256706f2543Smrg ValidateGC (pDrawable, pGC); 257706f2543Smrg } 258706f2543Smrg} 259706f2543Smrg 260706f2543Smrgvoid 261706f2543SmrgfbBresFillDash (DrawablePtr pDrawable, 262706f2543Smrg GCPtr pGC, 263706f2543Smrg int dashOffset, 264706f2543Smrg int signdx, 265706f2543Smrg int signdy, 266706f2543Smrg int axis, 267706f2543Smrg int x1, 268706f2543Smrg int y1, 269706f2543Smrg int e, 270706f2543Smrg int e1, 271706f2543Smrg int e3, 272706f2543Smrg int len) 273706f2543Smrg{ 274706f2543Smrg FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); 275706f2543Smrg FbDashDeclare; 276706f2543Smrg int dashlen; 277706f2543Smrg Bool even; 278706f2543Smrg Bool doOdd; 279706f2543Smrg Bool doBg; 280706f2543Smrg Pixel fg, bg; 281706f2543Smrg 282706f2543Smrg fg = pGC->fgPixel; 283706f2543Smrg bg = pGC->bgPixel; 284706f2543Smrg 285706f2543Smrg /* whether to fill the odd dashes */ 286706f2543Smrg doOdd = pGC->lineStyle == LineDoubleDash; 287706f2543Smrg /* whether to switch fg to bg when filling odd dashes */ 288706f2543Smrg doBg = doOdd && (pGC->fillStyle == FillSolid || 289706f2543Smrg pGC->fillStyle == FillStippled); 290706f2543Smrg 291706f2543Smrg /* compute current dash position */ 292706f2543Smrg FbDashInit (pGC, pPriv, dashOffset, dashlen, even); 293706f2543Smrg 294706f2543Smrg while (len--) 295706f2543Smrg { 296706f2543Smrg if (even || doOdd) 297706f2543Smrg { 298706f2543Smrg if (doBg) 299706f2543Smrg { 300706f2543Smrg if (even) 301706f2543Smrg fbSetFg (pDrawable, pGC, fg); 302706f2543Smrg else 303706f2543Smrg fbSetFg (pDrawable, pGC, bg); 304706f2543Smrg } 305706f2543Smrg fbFill (pDrawable, pGC, x1, y1, 1, 1); 306706f2543Smrg } 307706f2543Smrg if (axis == X_AXIS) 308706f2543Smrg { 309706f2543Smrg x1 += signdx; 310706f2543Smrg e += e1; 311706f2543Smrg if (e >= 0) 312706f2543Smrg { 313706f2543Smrg e += e3; 314706f2543Smrg y1 += signdy; 315706f2543Smrg } 316706f2543Smrg } 317706f2543Smrg else 318706f2543Smrg { 319706f2543Smrg y1 += signdy; 320706f2543Smrg e += e1; 321706f2543Smrg if (e >= 0) 322706f2543Smrg { 323706f2543Smrg e += e3; 324706f2543Smrg x1 += signdx; 325706f2543Smrg } 326706f2543Smrg } 327706f2543Smrg FbDashStep (dashlen, even); 328706f2543Smrg } 329706f2543Smrg if (doBg) 330706f2543Smrg fbSetFg (pDrawable, pGC, fg); 331706f2543Smrg} 332706f2543Smrg 333706f2543Smrg#ifdef FB_24BIT 334706f2543Smrgstatic void 335706f2543SmrgfbBresSolid24RRop (DrawablePtr pDrawable, 336706f2543Smrg GCPtr pGC, 337706f2543Smrg int dashOffset, 338706f2543Smrg int signdx, 339706f2543Smrg int signdy, 340706f2543Smrg int axis, 341706f2543Smrg int x1, 342706f2543Smrg int y1, 343706f2543Smrg int e, 344706f2543Smrg int e1, 345706f2543Smrg int e3, 346706f2543Smrg int len) 347706f2543Smrg{ 348706f2543Smrg FbStip *dst; 349706f2543Smrg FbStride dstStride; 350706f2543Smrg int dstBpp; 351706f2543Smrg int dstXoff, dstYoff; 352706f2543Smrg FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); 353706f2543Smrg FbStip and = pPriv->and; 354706f2543Smrg FbStip xor = pPriv->xor; 355706f2543Smrg FbStip leftMask, rightMask; 356706f2543Smrg int nl; 357706f2543Smrg FbStip *d; 358706f2543Smrg int x; 359706f2543Smrg int rot; 360706f2543Smrg FbStip andT, xorT; 361706f2543Smrg 362706f2543Smrg fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 363706f2543Smrg dst += ((y1 + dstYoff) * dstStride); 364706f2543Smrg x1 = (x1 + dstXoff) * 24; 365706f2543Smrg if (signdy < 0) 366706f2543Smrg dstStride = -dstStride; 367706f2543Smrg signdx *= 24; 368706f2543Smrg while (len--) 369706f2543Smrg { 370706f2543Smrg d = dst + (x1 >> FB_STIP_SHIFT); 371706f2543Smrg x = x1 & FB_STIP_MASK; 372706f2543Smrg rot = FbFirst24Rot (x); 373706f2543Smrg andT = FbRot24Stip(and,rot); 374706f2543Smrg xorT = FbRot24Stip(xor,rot); 375706f2543Smrg FbMaskStip (x, 24, leftMask, nl, rightMask); 376706f2543Smrg if (leftMask) 377706f2543Smrg { 378706f2543Smrg WRITE(d, FbDoMaskRRop (READ(d), andT, xorT, leftMask)); 379706f2543Smrg d++; 380706f2543Smrg andT = FbNext24Stip (andT); 381706f2543Smrg xorT = FbNext24Stip (xorT); 382706f2543Smrg } 383706f2543Smrg if (rightMask) 384706f2543Smrg WRITE(d, FbDoMaskRRop (READ(d), andT, xorT, rightMask)); 385706f2543Smrg if (axis == X_AXIS) 386706f2543Smrg { 387706f2543Smrg x1 += signdx; 388706f2543Smrg e += e1; 389706f2543Smrg if (e >= 0) 390706f2543Smrg { 391706f2543Smrg e += e3; 392706f2543Smrg dst += dstStride; 393706f2543Smrg } 394706f2543Smrg } 395706f2543Smrg else 396706f2543Smrg { 397706f2543Smrg dst += dstStride; 398706f2543Smrg e += e1; 399706f2543Smrg if (e >= 0) 400706f2543Smrg { 401706f2543Smrg e += e3; 402706f2543Smrg x1 += signdx; 403706f2543Smrg } 404706f2543Smrg } 405706f2543Smrg } 406706f2543Smrg 407706f2543Smrg fbFinishAccess (pDrawable); 408706f2543Smrg} 409706f2543Smrg 410706f2543Smrgstatic void 411706f2543SmrgfbBresDash24RRop (DrawablePtr pDrawable, 412706f2543Smrg GCPtr pGC, 413706f2543Smrg int dashOffset, 414706f2543Smrg int signdx, 415706f2543Smrg int signdy, 416706f2543Smrg int axis, 417706f2543Smrg int x1, 418706f2543Smrg int y1, 419706f2543Smrg int e, 420706f2543Smrg int e1, 421706f2543Smrg int e3, 422706f2543Smrg int len) 423706f2543Smrg{ 424706f2543Smrg FbStip *dst; 425706f2543Smrg FbStride dstStride; 426706f2543Smrg int dstBpp; 427706f2543Smrg int dstXoff, dstYoff; 428706f2543Smrg FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); 429706f2543Smrg FbStip andT, xorT; 430706f2543Smrg FbStip fgand = pPriv->and; 431706f2543Smrg FbStip fgxor = pPriv->xor; 432706f2543Smrg FbStip bgand = pPriv->bgand; 433706f2543Smrg FbStip bgxor = pPriv->bgxor; 434706f2543Smrg FbStip leftMask, rightMask; 435706f2543Smrg int nl; 436706f2543Smrg FbStip *d; 437706f2543Smrg int x; 438706f2543Smrg int rot; 439706f2543Smrg FbDashDeclare; 440706f2543Smrg int dashlen; 441706f2543Smrg Bool even; 442706f2543Smrg Bool doOdd; 443706f2543Smrg 444706f2543Smrg fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 445706f2543Smrg doOdd = pGC->lineStyle == LineDoubleDash; 446706f2543Smrg 447706f2543Smrg /* compute current dash position */ 448706f2543Smrg FbDashInit(pGC, pPriv, dashOffset, dashlen, even); 449706f2543Smrg 450706f2543Smrg dst += ((y1 + dstYoff) * dstStride); 451706f2543Smrg x1 = (x1 + dstXoff) * 24; 452706f2543Smrg if (signdy < 0) 453706f2543Smrg dstStride = -dstStride; 454706f2543Smrg signdx *= 24; 455706f2543Smrg while (len--) 456706f2543Smrg { 457706f2543Smrg if (even || doOdd) 458706f2543Smrg { 459706f2543Smrg if (even) 460706f2543Smrg { 461706f2543Smrg andT = fgand; 462706f2543Smrg xorT = fgxor; 463706f2543Smrg } 464706f2543Smrg else 465706f2543Smrg { 466706f2543Smrg andT = bgand; 467706f2543Smrg xorT = bgxor; 468706f2543Smrg } 469706f2543Smrg d = dst + (x1 >> FB_STIP_SHIFT); 470706f2543Smrg x = x1 & FB_STIP_MASK; 471706f2543Smrg rot = FbFirst24Rot (x); 472706f2543Smrg andT = FbRot24Stip (andT, rot); 473706f2543Smrg xorT = FbRot24Stip (xorT, rot); 474706f2543Smrg FbMaskStip (x, 24, leftMask, nl, rightMask); 475706f2543Smrg if (leftMask) 476706f2543Smrg { 477706f2543Smrg WRITE(d, FbDoMaskRRop (READ(d), andT, xorT, leftMask)); 478706f2543Smrg d++; 479706f2543Smrg andT = FbNext24Stip (andT); 480706f2543Smrg xorT = FbNext24Stip (xorT); 481706f2543Smrg } 482706f2543Smrg if (rightMask) 483706f2543Smrg WRITE(d, FbDoMaskRRop (READ(d), andT, xorT, rightMask)); 484706f2543Smrg } 485706f2543Smrg if (axis == X_AXIS) 486706f2543Smrg { 487706f2543Smrg x1 += signdx; 488706f2543Smrg e += e1; 489706f2543Smrg if (e >= 0) 490706f2543Smrg { 491706f2543Smrg e += e3; 492706f2543Smrg dst += dstStride; 493706f2543Smrg } 494706f2543Smrg } 495706f2543Smrg else 496706f2543Smrg { 497706f2543Smrg dst += dstStride; 498706f2543Smrg e += e1; 499706f2543Smrg if (e >= 0) 500706f2543Smrg { 501706f2543Smrg e += e3; 502706f2543Smrg x1 += signdx; 503706f2543Smrg } 504706f2543Smrg } 505706f2543Smrg FbDashStep (dashlen, even); 506706f2543Smrg } 507706f2543Smrg 508706f2543Smrg fbFinishAccess (pDrawable); 509706f2543Smrg} 510706f2543Smrg#endif 511706f2543Smrg 512706f2543Smrg/* 513706f2543Smrg * For drivers that want to bail drawing some lines, this 514706f2543Smrg * function takes care of selecting the appropriate rasterizer 515706f2543Smrg * based on the contents of the specified GC. 516706f2543Smrg */ 517706f2543Smrg 518706f2543SmrgFbBres * 519706f2543SmrgfbSelectBres (DrawablePtr pDrawable, 520706f2543Smrg GCPtr pGC) 521706f2543Smrg{ 522706f2543Smrg FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); 523706f2543Smrg int dstBpp = pDrawable->bitsPerPixel; 524706f2543Smrg FbBres * bres; 525706f2543Smrg 526706f2543Smrg if (pGC->lineStyle == LineSolid) 527706f2543Smrg { 528706f2543Smrg bres = fbBresFill; 529706f2543Smrg if (pGC->fillStyle == FillSolid) 530706f2543Smrg { 531706f2543Smrg bres = fbBresSolid; 532706f2543Smrg#ifdef FB_24BIT 533706f2543Smrg if (dstBpp == 24) 534706f2543Smrg bres = fbBresSolid24RRop; 535706f2543Smrg#endif 536706f2543Smrg#ifndef FBNOPIXADDR 537706f2543Smrg if (pPriv->and == 0) 538706f2543Smrg { 539706f2543Smrg switch (dstBpp) { 540706f2543Smrg case 8: bres = fbBresSolid8; break; 541706f2543Smrg case 16: bres = fbBresSolid16; break; 542706f2543Smrg#ifdef FB_24BIT 543706f2543Smrg case 24: bres = fbBresSolid24; break; 544706f2543Smrg#endif 545706f2543Smrg case 32: bres = fbBresSolid32; break; 546706f2543Smrg } 547706f2543Smrg } 548706f2543Smrg#endif 549706f2543Smrg } 550706f2543Smrg } 551706f2543Smrg else 552706f2543Smrg { 553706f2543Smrg bres = fbBresFillDash; 554706f2543Smrg if (pGC->fillStyle == FillSolid) 555706f2543Smrg { 556706f2543Smrg bres = fbBresDash; 557706f2543Smrg#ifdef FB_24BIT 558706f2543Smrg if (dstBpp == 24) 559706f2543Smrg bres = fbBresDash24RRop; 560706f2543Smrg#endif 561706f2543Smrg#ifndef FBNOPIXADDR 562706f2543Smrg if (pPriv->and == 0 && 563706f2543Smrg (pGC->lineStyle == LineOnOffDash || pPriv->bgand == 0)) 564706f2543Smrg { 565706f2543Smrg switch (dstBpp) { 566706f2543Smrg case 8: bres = fbBresDash8; break; 567706f2543Smrg case 16: bres = fbBresDash16; break; 568706f2543Smrg#ifdef FB_24BIT 569706f2543Smrg case 24: bres = fbBresDash24; break; 570706f2543Smrg#endif 571706f2543Smrg case 32: bres = fbBresDash32; break; 572706f2543Smrg } 573706f2543Smrg } 574706f2543Smrg#endif 575706f2543Smrg } 576706f2543Smrg } 577706f2543Smrg return bres; 578706f2543Smrg} 579706f2543Smrg 580706f2543Smrgvoid 581706f2543SmrgfbBres (DrawablePtr pDrawable, 582706f2543Smrg GCPtr pGC, 583706f2543Smrg int dashOffset, 584706f2543Smrg int signdx, 585706f2543Smrg int signdy, 586706f2543Smrg int axis, 587706f2543Smrg int x1, 588706f2543Smrg int y1, 589706f2543Smrg int e, 590706f2543Smrg int e1, 591706f2543Smrg int e3, 592706f2543Smrg int len) 593706f2543Smrg{ 594706f2543Smrg (*fbSelectBres (pDrawable, pGC)) (pDrawable, pGC, dashOffset, 595706f2543Smrg signdx, signdy, axis, x1, y1, 596706f2543Smrg e, e1, e3, len); 597706f2543Smrg} 598706f2543Smrg 599706f2543Smrgvoid 600706f2543SmrgfbSegment (DrawablePtr pDrawable, 601706f2543Smrg GCPtr pGC, 602706f2543Smrg int x1, 603706f2543Smrg int y1, 604706f2543Smrg int x2, 605706f2543Smrg int y2, 606706f2543Smrg Bool drawLast, 607706f2543Smrg int *dashOffset) 608706f2543Smrg{ 609706f2543Smrg FbBres * bres; 610706f2543Smrg RegionPtr pClip = fbGetCompositeClip(pGC); 611706f2543Smrg BoxPtr pBox; 612706f2543Smrg int nBox; 613706f2543Smrg int adx; /* abs values of dx and dy */ 614706f2543Smrg int ady; 615706f2543Smrg int signdx; /* sign of dx and dy */ 616706f2543Smrg int signdy; 617706f2543Smrg int e, e1, e2, e3; /* bresenham error and increments */ 618706f2543Smrg int len; /* length of segment */ 619706f2543Smrg int axis; /* major axis */ 620706f2543Smrg int octant; 621706f2543Smrg int dashoff; 622706f2543Smrg int doff; 623706f2543Smrg unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); 624706f2543Smrg unsigned int oc1; /* outcode of point 1 */ 625706f2543Smrg unsigned int oc2; /* outcode of point 2 */ 626706f2543Smrg 627706f2543Smrg nBox = RegionNumRects (pClip); 628706f2543Smrg pBox = RegionRects (pClip); 629706f2543Smrg 630706f2543Smrg bres = fbSelectBres (pDrawable, pGC); 631706f2543Smrg 632706f2543Smrg CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 633706f2543Smrg 1, 1, octant); 634706f2543Smrg 635706f2543Smrg if (adx > ady) 636706f2543Smrg { 637706f2543Smrg axis = X_AXIS; 638706f2543Smrg e1 = ady << 1; 639706f2543Smrg e2 = e1 - (adx << 1); 640706f2543Smrg e = e1 - adx; 641706f2543Smrg len = adx; 642706f2543Smrg } 643706f2543Smrg else 644706f2543Smrg { 645706f2543Smrg axis = Y_AXIS; 646706f2543Smrg e1 = adx << 1; 647706f2543Smrg e2 = e1 - (ady << 1); 648706f2543Smrg e = e1 - ady; 649706f2543Smrg SetYMajorOctant(octant); 650706f2543Smrg len = ady; 651706f2543Smrg } 652706f2543Smrg 653706f2543Smrg FIXUP_ERROR (e, octant, bias); 654706f2543Smrg 655706f2543Smrg /* 656706f2543Smrg * Adjust error terms to compare against zero 657706f2543Smrg */ 658706f2543Smrg e3 = e2 - e1; 659706f2543Smrg e = e - e1; 660706f2543Smrg 661706f2543Smrg /* we have bresenham parameters and two points. 662706f2543Smrg all we have to do now is clip and draw. 663706f2543Smrg */ 664706f2543Smrg 665706f2543Smrg if (drawLast) 666706f2543Smrg len++; 667706f2543Smrg dashoff = *dashOffset; 668706f2543Smrg *dashOffset = dashoff + len; 669706f2543Smrg while(nBox--) 670706f2543Smrg { 671706f2543Smrg oc1 = 0; 672706f2543Smrg oc2 = 0; 673706f2543Smrg OUTCODES(oc1, x1, y1, pBox); 674706f2543Smrg OUTCODES(oc2, x2, y2, pBox); 675706f2543Smrg if ((oc1 | oc2) == 0) 676706f2543Smrg { 677706f2543Smrg (*bres) (pDrawable, pGC, dashoff, 678706f2543Smrg signdx, signdy, axis, x1, y1, 679706f2543Smrg e, e1, e3, len); 680706f2543Smrg break; 681706f2543Smrg } 682706f2543Smrg else if (oc1 & oc2) 683706f2543Smrg { 684706f2543Smrg pBox++; 685706f2543Smrg } 686706f2543Smrg else 687706f2543Smrg { 688706f2543Smrg int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2; 689706f2543Smrg int clip1 = 0, clip2 = 0; 690706f2543Smrg int clipdx, clipdy; 691706f2543Smrg int err; 692706f2543Smrg 693706f2543Smrg if (miZeroClipLine(pBox->x1, pBox->y1, pBox->x2-1, 694706f2543Smrg pBox->y2-1, 695706f2543Smrg &new_x1, &new_y1, &new_x2, &new_y2, 696706f2543Smrg adx, ady, &clip1, &clip2, 697706f2543Smrg octant, bias, oc1, oc2) == -1) 698706f2543Smrg { 699706f2543Smrg pBox++; 700706f2543Smrg continue; 701706f2543Smrg } 702706f2543Smrg 703706f2543Smrg if (axis == X_AXIS) 704706f2543Smrg len = abs(new_x2 - new_x1); 705706f2543Smrg else 706706f2543Smrg len = abs(new_y2 - new_y1); 707706f2543Smrg if (clip2 != 0 || drawLast) 708706f2543Smrg len++; 709706f2543Smrg if (len) 710706f2543Smrg { 711706f2543Smrg /* unwind bresenham error term to first point */ 712706f2543Smrg doff = dashoff; 713706f2543Smrg err = e; 714706f2543Smrg if (clip1) 715706f2543Smrg { 716706f2543Smrg clipdx = abs(new_x1 - x1); 717706f2543Smrg clipdy = abs(new_y1 - y1); 718706f2543Smrg if (axis == X_AXIS) 719706f2543Smrg { 720706f2543Smrg doff += clipdx; 721706f2543Smrg err += e3 * clipdy + e1 * clipdx; 722706f2543Smrg } 723706f2543Smrg else 724706f2543Smrg { 725706f2543Smrg doff += clipdy; 726706f2543Smrg err += e3 * clipdx + e1 * clipdy; 727706f2543Smrg } 728706f2543Smrg } 729706f2543Smrg (*bres) (pDrawable, pGC, doff, 730706f2543Smrg signdx, signdy, axis, new_x1, new_y1, 731706f2543Smrg err, e1, e3, len); 732706f2543Smrg } 733706f2543Smrg pBox++; 734706f2543Smrg } 735706f2543Smrg } /* while (nBox--) */ 736706f2543Smrg} 737