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