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