1 /* $NetBSD: raster_op.c,v 1.11 2001/11/13 06:58:44 lukem Exp $ */ 2 3 /*- 4 * Copyright (c) 1991, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to the Computer Systems 8 * Engineering Group at Lawrence Berkeley Laboratory and to the University 9 * of California at Berkeley by Jef Poskanzer. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)raster_op.c 8.1 (Berkeley) 6/11/93 40 */ 41 42 /* 43 * Bitblit routine for raster library. 44 * 45 * This raster-op is machined to exacting tolerances by skilled native 46 * craftsmen with pride in their work. 47 * 48 * The various cases are broken down like this: 49 * 50 * src required 51 * 1-bit to 1-bit 52 * 1-bit to 2-bits 53 * 1-bit to 4-bits 54 * 1-bit to 8-bits 55 * 1-bit to 16-bits 56 * 2-bits to 2-bits 57 * 2-bits to 4-bits (not implemented) 58 * 2-bits to 8-bits (not implemented) 59 * 2-bits to 16-bits (not implemented) 60 * 4-bits to 4-bits 61 * 4-bits to 8-bits (not implemented) 62 * 4-bits to 16-bits (not implemented) 63 * 8-bits to 8-bits 64 * 8-bits to 16-bits (not implemented) 65 * 16-bits to 16-bits 66 * no src required 67 * 1-bit no-src 68 * 2-bits no-src 69 * 8-bits no-src 70 * 16-bits no-src 71 */ 72 73 #include <sys/cdefs.h> 74 __KERNEL_RCSID(0, "$NetBSD: raster_op.c,v 1.11 2001/11/13 06:58:44 lukem Exp $"); 75 76 #include <sys/types.h> 77 #ifdef _KERNEL 78 #include "opt_rcons.h" 79 #include <dev/rcons/raster.h> 80 #else 81 #include "raster.h" 82 #endif 83 84 /* CONFIGURE: To save on executable size, you can configure out the seldom-used 85 ** logical operations. With this variable set, the only operations implemented 86 ** are: RAS_SRC, RAS_CLEAR, RAS_SET, RAS_INVERT, RAS_XOR, RAS_INVERTSRC. 87 */ 88 #ifdef _KERNEL 89 #define PARTIAL_LOGICAL_OPS 90 #endif 91 92 /* CONFIGURE: bcopy() is supposed to be the ultimately fastest way to move 93 ** bytes, overlapping or not, ignoring the startup cost. Unfortunately 94 ** this is not true on some systems. For example, on a Sun 3 running 95 ** SunOS 3.5, bcopy() is about five times slower than a simple for loop 96 ** on overlapping copies. And on a 4.1.1 SPARC, bcopy() is about 2/3rds 97 ** as fast on backwards overlaps. So, only define this if your bcopy is ok. 98 */ 99 #undef BCOPY_FASTER 100 101 /* End of configurable definitions. */ 102 103 104 /* Definitions. */ 105 106 /* Raster-op macros. These encapsulate the switch statements and so make 107 ** the source code 16 times smaller. The pre and pst args are code 108 ** fragments to put before and after the assignment in each case. They 109 ** can be the beginning and end of a loop. If the pst fragment includes a 110 ** masked assignment, for example to handle the left or right edge cases, 111 ** a good optimizing compiler will simplify the boolean expressions very 112 ** nicely - both cc and gcc on the SPARC will do this. 113 */ 114 115 #ifndef PARTIAL_LOGICAL_OPS 116 117 #define ROP_DST(op,pre,d,pst) \ 118 switch ( op ) \ 119 { \ 120 case RAS_CLEAR: \ 121 pre \ 122 (d) = 0; \ 123 pst \ 124 break; \ 125 case RAS_INVERT: \ 126 pre \ 127 (d) = ~(d); \ 128 pst \ 129 break; \ 130 case RAS_DST: \ 131 /* noop */ \ 132 break; \ 133 case RAS_SET: \ 134 pre \ 135 (d) = ~0; \ 136 pst \ 137 break; \ 138 default: \ 139 return -1; \ 140 } 141 142 #define ROP_DSTCOLOR(op,pre,d,c,pst) \ 143 switch ( op ) \ 144 { \ 145 case RAS_CLEAR: \ 146 pre \ 147 (d) = 0; \ 148 pst \ 149 break; \ 150 case RAS_INVERT: \ 151 pre \ 152 (d) = ~(d); \ 153 pst \ 154 break; \ 155 case RAS_DST: \ 156 /* noop */ \ 157 break; \ 158 case RAS_SET: \ 159 pre \ 160 (d) = (c); \ 161 pst \ 162 break; \ 163 default: \ 164 return -1; \ 165 } 166 167 #define ROP_SRCDST(op,pre,s,d,pst) \ 168 switch ( op ) \ 169 { \ 170 case RAS_NOTOR: \ 171 pre \ 172 (d) = ~( (s) | (d) ); \ 173 pst \ 174 break; \ 175 case RAS_NOTSRC_AND_DST: \ 176 pre \ 177 (d) = ~(s) & (d); \ 178 pst \ 179 break; \ 180 case RAS_INVERTSRC: \ 181 pre \ 182 (d) = ~(s); \ 183 pst \ 184 break; \ 185 case RAS_SRC_AND_NOTDST: \ 186 pre \ 187 (d) = (s) & ~(d); \ 188 pst \ 189 break; \ 190 case RAS_XOR: \ 191 pre \ 192 (d) = (s) ^ (d); \ 193 pst \ 194 break; \ 195 case RAS_NOTAND: \ 196 pre \ 197 (d) = ~( (s) & (d) ); \ 198 pst \ 199 break; \ 200 case RAS_AND: \ 201 pre \ 202 (d) = (s) & (d); \ 203 pst \ 204 break; \ 205 case RAS_NOTXOR: \ 206 pre \ 207 (d) = ~( (s) ^ (d) ); \ 208 pst \ 209 break; \ 210 case RAS_NOTSRC_OR_DST: \ 211 pre \ 212 (d) = ~(s) | (d); \ 213 pst \ 214 break; \ 215 case RAS_SRC: \ 216 pre \ 217 (d) = (s); \ 218 pst \ 219 break; \ 220 case RAS_SRC_OR_NOTDST: \ 221 pre \ 222 (d) = (s) | ~(d); \ 223 pst \ 224 break; \ 225 case RAS_OR: \ 226 pre \ 227 (d) = (s) | (d); \ 228 pst \ 229 break; \ 230 default: \ 231 return -1; \ 232 } 233 234 #define ROP_SRCDSTCOLOR(op,pre,s,d,c,pst) \ 235 switch ( op ) \ 236 { \ 237 case RAS_NOTOR: \ 238 pre \ 239 if ( s ) \ 240 (d) = ~( (c) | (d) ); \ 241 else \ 242 (d) = ~(d); \ 243 pst \ 244 break; \ 245 case RAS_NOTSRC_AND_DST: \ 246 pre \ 247 if ( s ) \ 248 (d) = ~(c) & (d); \ 249 pst \ 250 break; \ 251 case RAS_INVERTSRC: \ 252 pre \ 253 if ( s ) \ 254 (d) = ~(c); \ 255 else \ 256 (d) = ~0; \ 257 pst \ 258 break; \ 259 case RAS_SRC_AND_NOTDST: \ 260 pre \ 261 if ( s ) \ 262 (d) = (c) & ~(d); \ 263 else \ 264 (d) = 0; \ 265 pst \ 266 break; \ 267 case RAS_XOR: \ 268 pre \ 269 if ( s ) \ 270 (d) = (c) ^ (d); \ 271 pst \ 272 break; \ 273 case RAS_NOTAND: \ 274 pre \ 275 if ( s ) \ 276 (d) = ~( (c) & (d) ); \ 277 else \ 278 (d) = ~0; \ 279 pst \ 280 break; \ 281 case RAS_AND: \ 282 pre \ 283 if ( s ) \ 284 (d) = (c) & (d); \ 285 else \ 286 (d) = 0; \ 287 pst \ 288 break; \ 289 case RAS_NOTXOR: \ 290 pre \ 291 if ( s ) \ 292 (d) = ~( (c) ^ (d) ); \ 293 else \ 294 (d) = ~(d); \ 295 pst \ 296 break; \ 297 case RAS_NOTSRC_OR_DST: \ 298 pre \ 299 if ( s ) \ 300 (d) = ~(c) | (d); \ 301 else \ 302 (d) = ~0; \ 303 pst \ 304 break; \ 305 case RAS_SRC: \ 306 pre \ 307 if ( s ) \ 308 (d) = (c); \ 309 else \ 310 (d) = 0; \ 311 pst \ 312 break; \ 313 case RAS_SRC_OR_NOTDST: \ 314 pre \ 315 if ( s ) \ 316 (d) = (c) | ~(d); \ 317 else \ 318 (d) = ~(d); \ 319 pst \ 320 break; \ 321 case RAS_OR: \ 322 pre \ 323 if ( s ) \ 324 (d) = (c) | (d); \ 325 pst \ 326 break; \ 327 default: \ 328 return -1; \ 329 } 330 331 #else /*PARTIAL_LOGICAL_OPS*/ 332 333 #define ROP_DST(op,pre,d,pst) \ 334 switch ( op ) \ 335 { \ 336 case RAS_CLEAR: \ 337 pre \ 338 (d) = 0; \ 339 pst \ 340 break; \ 341 case RAS_INVERT: \ 342 pre \ 343 (d) = ~(d); \ 344 pst \ 345 break; \ 346 case RAS_SET: \ 347 pre \ 348 (d) = ~0; \ 349 pst \ 350 break; \ 351 default: \ 352 return -1; \ 353 } 354 355 #define ROP_DSTCOLOR(op,pre,d,c,pst) \ 356 switch ( op ) \ 357 { \ 358 case RAS_CLEAR: \ 359 pre \ 360 (d) = 0; \ 361 pst \ 362 break; \ 363 case RAS_INVERT: \ 364 pre \ 365 (d) = ~(d); \ 366 pst \ 367 break; \ 368 case RAS_SET: \ 369 pre \ 370 (d) = (c); \ 371 pst \ 372 break; \ 373 default: \ 374 return -1; \ 375 } 376 377 #define ROP_SRCDST(op,pre,s,d,pst) \ 378 switch ( op ) \ 379 { \ 380 case RAS_INVERTSRC: \ 381 pre \ 382 (d) = ~(s); \ 383 pst \ 384 break; \ 385 case RAS_XOR: \ 386 pre \ 387 (d) = (s) ^ (d); \ 388 pst \ 389 break; \ 390 case RAS_SRC: \ 391 pre \ 392 (d) = (s); \ 393 pst \ 394 break; \ 395 default: \ 396 return -1; \ 397 } 398 399 #define ROP_SRCDSTCOLOR(op,pre,s,d,c,pst) \ 400 switch ( op ) \ 401 { \ 402 case RAS_INVERTSRC: \ 403 pre \ 404 if ( s ) \ 405 (d) = ~(c); \ 406 else \ 407 (d) = ~0; \ 408 pst \ 409 break; \ 410 case RAS_XOR: \ 411 pre \ 412 if ( s ) \ 413 (d) = (c) ^ (d); \ 414 pst \ 415 break; \ 416 case RAS_SRC: \ 417 pre \ 418 if ( s ) \ 419 (d) = (c); \ 420 else \ 421 (d) = 0; \ 422 pst \ 423 break; \ 424 default: \ 425 return -1; \ 426 } 427 428 #endif /*PARTIAL_LOGICAL_OPS*/ 429 430 431 /* Variables. */ 432 433 static int needsrc[16] = { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0 }; 434 /* CLEAR INVERT DST SET */ 435 436 #ifdef MSBIT_FIRST 437 438 u_int32_t raster_bitmask[32] = { 439 0x80000000, 0x40000000, 0x20000000, 0x10000000, 440 0x08000000, 0x04000000, 0x02000000, 0x01000000, 441 0x00800000, 0x00400000, 0x00200000, 0x00100000, 442 0x00080000, 0x00040000, 0x00020000, 0x00010000, 443 0x00008000, 0x00004000, 0x00002000, 0x00001000, 444 0x00000800, 0x00000400, 0x00000200, 0x00000100, 445 0x00000080, 0x00000040, 0x00000020, 0x00000010, 446 0x00000008, 0x00000004, 0x00000002, 0x00000001 }; 447 448 #ifdef MSBYTE_FIRST 449 static u_int32_t leftmask[32] = { 450 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 451 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000, 452 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, 453 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 454 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000, 455 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, 456 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 457 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe }; 458 static u_int32_t rightmask[32] = { 459 0x00000000, 0x00000001, 0x00000003, 0x00000007, 460 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 461 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 462 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 463 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 464 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 465 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 466 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff }; 467 468 #define LSOP << 469 #define RSOP >> 470 #endif /*MSBYTE_FIRST*/ 471 472 #else /*MSBIT_FIRST*/ 473 474 u_int32_t raster_bitmask[32] = { 475 0x00000001, 0x00000002, 0x00000004, 0x00000008, 476 0x00000010, 0x00000020, 0x00000040, 0x00000080, 477 0x00000100, 0x00000200, 0x00000400, 0x00000800, 478 0x00001000, 0x00002000, 0x00004000, 0x00008000, 479 0x00010000, 0x00020000, 0x00040000, 0x00080000, 480 0x00100000, 0x00200000, 0x00400000, 0x00800000, 481 0x01000000, 0x02000000, 0x04000000, 0x08000000, 482 0x10000000, 0x20000000, 0x40000000, 0x80000000 }; 483 484 #ifndef MSBYTE_FIRST 485 static u_int32_t leftmask[32] = { 486 0x00000000, 0x00000001, 0x00000003, 0x00000007, 487 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 488 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 489 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 490 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 491 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 492 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 493 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff }; 494 static u_int32_t rightmask[32] = { 495 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 496 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000, 497 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, 498 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 499 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000, 500 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, 501 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 502 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe }; 503 #define LSOP >> 504 #define RSOP << 505 #endif /*not MSBYTE_FIRST*/ 506 507 #endif /*MSBIT_FIRST*/ 508 509 /* (The odd combinations MSBIT+~MSBYTE and ~MSBIT+MSBYTE could be added.) */ 510 511 #ifdef MSBYTE_FIRST 512 static u_int32_t bytemask[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff }; 513 #ifdef RCONS_2BPP 514 static u_int32_t twobitmask[16] = { 515 0xc0000000, 0x30000000, 0x0c000000, 0x03000000, 516 0x00c00000, 0x00300000, 0x000c0000, 0x00030000, 517 0x0000c000, 0x00003000, 0x00000c00, 0x00000300, 518 0x000000c0, 0x00000030, 0x0000000c, 0x00000003 }; 519 #endif /* RCONS_2BPP */ 520 #ifdef RCONS_4BPP 521 static u_int32_t fourbitmask[8] = { 522 0xf0000000, 0x0f000000, 523 0x00f00000, 0x000f0000, 524 0x0000f000, 0x00000f00, 525 0x000000f0, 0x0000000f }; 526 #endif /* RCONS_4BPP */ 527 #ifdef RCONS_16BPP 528 static u_int32_t twobytemask[2] = { 0xffff0000, 0x0000ffff }; 529 #endif /* RCONS_16BPP */ 530 #else /*MSBYTE_FIRST*/ 531 static u_int32_t bytemask[4] = { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }; 532 #ifdef RCONS_2BPP 533 static u_int32_t twobitmask[16] = { 534 0x00000003, 0x0000000c, 0x00000030, 0x000000c0, 535 0x00000300, 0x00000c00, 0x00003000, 0x0000c000, 536 0x00030000, 0x000c0000, 0x00300000, 0x00c00000, 537 0x03000000, 0x0c000000, 0x30000000, 0xc0000000 }; 538 #endif /* RCONS_2BPP */ 539 #ifdef RCONS_4BPP 540 static u_int32_t fourbitmask[16] = { 541 0x0000000f, 0x000000f0, 542 0x00000f00, 0x0000f000, 543 0x000f0000, 0x00f00000, 544 0x0f000000, 0xf0000000 }; 545 #endif /* RCONS_4BPP */ 546 #ifdef RCONS_16BPP 547 static u_int32_t twobytemask[2] = { 0x0000ffff, 0xffff0000 }; 548 #endif /* RCONS_16BPP */ 549 #endif /*MSBYTE_FIRST*/ 550 551 552 /* Forward routines. */ 553 554 static int raster_blit __P((struct raster *, u_int32_t *, int, int, int, 555 struct raster *, u_int32_t *, int, int, int, 556 int, int)); 557 558 /* Raster operations. */ 559 560 /* Performs a bitblit. Returns 0 on success, -1 on failure. */ 561 int 562 raster_op( dst, dx, dy, w, h, rop, src, sx, sy ) 563 struct raster* dst; 564 int dx, dy, w, h, rop; 565 struct raster* src; 566 int sx, sy; 567 { 568 if ( dst == (struct raster*) 0 ) 569 return -1; /* no destination */ 570 571 if ( needsrc[RAS_GETOP( rop )] ) 572 { 573 /* Two-operand blit. */ 574 if ( src == (struct raster*) 0 ) 575 return -1; /* no source */ 576 577 /* Clip against source. */ 578 if ( sx < 0 ) 579 { 580 w += sx; 581 sx = 0; 582 } 583 if ( sy < 0 ) 584 { 585 h += sy; 586 sy = 0; 587 } 588 if ( sx + w > src->width ) 589 w = src->width - sx; 590 if ( sy + h > src->height ) 591 h = src->height - sy; 592 593 /* Clip against dest. */ 594 if ( dx < 0 ) 595 { 596 w += dx; 597 sx -= dx; 598 dx = 0; 599 } 600 if ( dy < 0 ) 601 { 602 h += dy; 603 sy -= dy; 604 dy = 0; 605 } 606 if ( dx + w > dst->width ) 607 w = dst->width - dx; 608 if ( dy + h > dst->height ) 609 h = dst->height - dy; 610 611 if ( w <= 0 || h <= 0 ) 612 return 0; /* nothing to do */ 613 614 return raster_op_noclip( dst, dx, dy, w, h, rop, src, sx, sy ); 615 } 616 617 /* No source necessary - one-operand blit. */ 618 if ( src != (struct raster*) 0 ) 619 return -1; /* unwanted source */ 620 621 /* Clip against dest. */ 622 if ( dx < 0 ) 623 { 624 w += dx; 625 dx = 0; 626 } 627 if ( dy < 0 ) 628 { 629 h += dy; 630 dy = 0; 631 } 632 if ( dx + w > dst->width ) 633 w = dst->width - dx; 634 if ( dy + h > dst->height ) 635 h = dst->height - dy; 636 637 if ( w <= 0 || h <= 0 ) 638 return 0; /* nothing to do */ 639 640 return raster_op_nosrc_noclip( dst, dx, dy, w, h, rop ); 641 } 642 643 /* Semi-public routine to do a bitblit without clipping. Returns 0 on 644 ** success, -1 on failure. 645 */ 646 int 647 raster_op_noclip( dst, dx, dy, w, h, rop, src, sx, sy ) 648 struct raster* dst; 649 int dx, dy, w, h, rop; 650 struct raster* src; 651 int sx, sy; 652 { 653 int op; 654 655 op = RAS_GETOP( rop ); 656 657 if ( src->depth == 1 ) 658 { 659 /* One-bit to ? blit. */ 660 if ( dst->depth == 1 ) 661 { 662 /* One to one blit. */ 663 u_int32_t* srclin1; 664 u_int32_t* dstlin1; 665 int srcleftignore, srcrightignore, srclongs; 666 int dstleftignore, dstrightignore, dstlongs; 667 668 srclin1 = RAS_ADDR( src, sx, sy ); 669 dstlin1 = RAS_ADDR( dst, dx, dy ); 670 671 #ifdef BCOPY_FASTER 672 /* Special-case full-width to full-width copies. */ 673 if ( op == RAS_SRC && src->width == w && dst->width == w && 674 src->linelongs == dst->linelongs && src->linelongs == w >> 5 ) 675 { 676 bcopy( 677 (char*) srclin1, (char*) dstlin1, 678 h * src->linelongs * sizeof(u_int32_t) ); 679 return 0; 680 } 681 #endif /*BCOPY_FASTER*/ 682 683 srcleftignore = ( sx & 31 ); 684 srclongs = ( srcleftignore + w + 31 ) >> 5; 685 srcrightignore = ( srclongs * 32 - w - srcleftignore ) & 31; 686 dstleftignore = ( dx & 31 ); 687 dstlongs = ( dstleftignore + w + 31 ) >> 5; 688 dstrightignore = ( dstlongs * 32 - w - dstleftignore ) & 31; 689 690 return raster_blit( 691 src, srclin1, srcleftignore, srcrightignore, srclongs, 692 dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op ); 693 } 694 695 #ifdef RCONS_2BPP 696 else if ( dst->depth == 2 ) 697 { 698 /* One to two, using the color in the rop. */ 699 u_int32_t* srclin1; 700 u_int32_t* dstlin1; 701 u_int32_t* srclin2; 702 u_int32_t* srclin; 703 u_int32_t* dstlin; 704 u_int32_t* srclong; 705 u_int32_t* dstlong; 706 u_int32_t color, dl; 707 int srcbit, dstbyte, i; 708 709 color = RAS_GETCOLOR( rop ); 710 if ( color == 0 ) 711 color = 3; 712 713 /* Make 32 bits of color so we can do the ROP without shifting. */ 714 color |= (( color << 30 ) | ( color << 28 ) | ( color << 26 ) 715 | ( color << 24 ) | ( color << 22 ) | ( color << 20 ) 716 | ( color << 18 ) | ( color << 16 ) | ( color << 14 ) 717 | ( color << 12 ) | ( color << 10 ) | ( color << 8 ) 718 | ( color << 6 ) | ( color << 4 ) | ( color << 2 )); 719 720 /* Don't have to worry about overlapping blits here. */ 721 srclin1 = RAS_ADDR( src, sx, sy ); 722 srclin2 = srclin1 + h * src->linelongs; 723 dstlin1 = RAS_ADDR( dst, dx, dy ); 724 srclin = srclin1; 725 dstlin = dstlin1; 726 727 while ( srclin != srclin2 ) 728 { 729 srclong = srclin; 730 srcbit = sx & 31; 731 dstlong = dstlin; 732 dstbyte = dx & 15; 733 i = w; 734 735 /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */ 736 ROP_SRCDSTCOLOR( 737 /*op*/ op, 738 /*pre*/ while ( i > 0 ) 739 { 740 dl = *dstlong;, 741 /*s*/ *srclong & raster_bitmask[srcbit], 742 /*d*/ dl, 743 /*c*/ color, 744 /*pst*/ *dstlong = ( *dstlong & ~twobitmask[dstbyte] ) | 745 ( dl & twobitmask[dstbyte] ); 746 if ( srcbit == 31 ) 747 { 748 srcbit = 0; 749 ++srclong; 750 } 751 else 752 ++srcbit; 753 if ( dstbyte == 15 ) 754 { 755 dstbyte = 0; 756 ++dstlong; 757 } 758 else 759 ++dstbyte; 760 --i; 761 } ) 762 763 srclin += src->linelongs; 764 dstlin += dst->linelongs; 765 } 766 } 767 #endif /* RCONS_2BPP */ 768 #ifdef RCONS_4BPP 769 else if ( dst->depth == 4 ) 770 { 771 /* One to four, using the color in the rop. */ 772 u_int32_t* srclin1; 773 u_int32_t* dstlin1; 774 u_int32_t* srclin2; 775 u_int32_t* srclin; 776 u_int32_t* dstlin; 777 u_int32_t* srclong; 778 u_int32_t* dstlong; 779 u_int32_t color, dl; 780 int srcbit, dstbyte, i; 781 782 color = RAS_GETCOLOR( rop ); 783 if ( color == 0 ) 784 color = 15; 785 786 /* Make 32 bits of color so we can do the ROP without shifting. */ 787 color |= (( color << 28 ) | ( color << 24 ) 788 | ( color << 20 ) | ( color << 16 ) 789 | ( color << 12 ) | ( color << 8 ) 790 | ( color << 4 )); 791 792 /* Don't have to worry about overlapping blits here. */ 793 srclin1 = RAS_ADDR( src, sx, sy ); 794 srclin2 = srclin1 + h * src->linelongs; 795 dstlin1 = RAS_ADDR( dst, dx, dy ); 796 srclin = srclin1; 797 dstlin = dstlin1; 798 799 while ( srclin != srclin2 ) 800 { 801 srclong = srclin; 802 srcbit = sx & 31; 803 dstlong = dstlin; 804 dstbyte = dx & 7; 805 i = w; 806 807 /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */ 808 ROP_SRCDSTCOLOR( 809 /*op*/ op, 810 /*pre*/ while ( i > 0 ) 811 { 812 dl = *dstlong;, 813 /*s*/ *srclong & raster_bitmask[srcbit], 814 /*d*/ dl, 815 /*c*/ color, 816 /*pst*/ *dstlong = ( *dstlong & ~fourbitmask[dstbyte] ) | 817 ( dl & fourbitmask[dstbyte] ); 818 if ( srcbit == 31 ) 819 { 820 srcbit = 0; 821 ++srclong; 822 } 823 else 824 ++srcbit; 825 if ( dstbyte == 7 ) 826 { 827 dstbyte = 0; 828 ++dstlong; 829 } 830 else 831 ++dstbyte; 832 --i; 833 } ) 834 835 srclin += src->linelongs; 836 dstlin += dst->linelongs; 837 } 838 } 839 #endif /* RCONS_4BPP */ 840 else if ( dst->depth == 8 ) 841 { 842 /* One to eight, using the color in the rop. This could 843 ** probably be sped up by handling each four-bit source nybble 844 ** as a group, indexing into a 16-element runtime-constructed 845 ** table of longwords. 846 */ 847 u_int32_t* srclin1; 848 u_int32_t* dstlin1; 849 u_int32_t* srclin2; 850 u_int32_t* srclin; 851 u_int32_t* dstlin; 852 u_int32_t* srclong; 853 u_int32_t* dstlong; 854 u_int32_t color, dl; 855 int srcbit, dstbyte, i; 856 857 color = RAS_GETCOLOR( rop ); 858 if ( color == 0 ) 859 color = 255; 860 861 /* Make 32 bits of color so we can do the ROP without shifting. */ 862 color |= ( color << 24 ) | ( color << 16 ) | ( color << 8 ); 863 864 /* Don't have to worry about overlapping blits here. */ 865 srclin1 = RAS_ADDR( src, sx, sy ); 866 srclin2 = srclin1 + h * src->linelongs; 867 dstlin1 = RAS_ADDR( dst, dx, dy ); 868 srclin = srclin1; 869 dstlin = dstlin1; 870 while ( srclin != srclin2 ) 871 { 872 srclong = srclin; 873 srcbit = sx & 31; 874 dstlong = dstlin; 875 dstbyte = dx & 3; 876 i = w; 877 878 /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */ 879 ROP_SRCDSTCOLOR( 880 /*op*/ op, 881 /*pre*/ while ( i > 0 ) 882 { 883 dl = *dstlong;, 884 /*s*/ *srclong & raster_bitmask[srcbit], 885 /*d*/ dl, 886 /*c*/ color, 887 /*pst*/ *dstlong = ( *dstlong & ~bytemask[dstbyte] ) | 888 ( dl & bytemask[dstbyte] ); 889 if ( srcbit == 31 ) 890 { 891 srcbit = 0; 892 ++srclong; 893 } 894 else 895 ++srcbit; 896 if ( dstbyte == 3 ) 897 { 898 dstbyte = 0; 899 ++dstlong; 900 } 901 else 902 ++dstbyte; 903 --i; 904 } ) 905 906 srclin += src->linelongs; 907 dstlin += dst->linelongs; 908 } 909 } 910 #ifdef RCONS_16BPP 911 else 912 { 913 /* One to sixteen, using the color in the rop. This could 914 ** probably be sped up by handling each four-bit source nybble 915 ** as a group, indexing into a 16-element runtime-constructed 916 ** table of longwords. 917 */ 918 u_int32_t* srclin1; 919 u_int32_t* dstlin1; 920 u_int32_t* srclin2; 921 u_int32_t* srclin; 922 u_int32_t* dstlin; 923 u_int32_t* srclong; 924 u_int32_t* dstlong; 925 u_int32_t color, dl; 926 int srcbit, dstbyte, i; 927 928 color = RAS_GETCOLOR( rop ); 929 if ( color == 0 ) 930 color = 0xffff; 931 932 /* Make 32 bits of color so we can do the ROP without shifting. */ 933 color |= ( color << 16 ); 934 935 /* Don't have to worry about overlapping blits here. */ 936 srclin1 = RAS_ADDR( src, sx, sy ); 937 srclin2 = srclin1 + h * src->linelongs; 938 dstlin1 = RAS_ADDR( dst, dx, dy ); 939 srclin = srclin1; 940 dstlin = dstlin1; 941 while ( srclin != srclin2 ) 942 { 943 srclong = srclin; 944 srcbit = sx & 31; 945 dstlong = dstlin; 946 dstbyte = dx & 1; 947 i = w; 948 949 /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */ 950 ROP_SRCDSTCOLOR( 951 /*op*/ op, 952 /*pre*/ while ( i > 0 ) 953 { 954 dl = *dstlong;, 955 /*s*/ *srclong & raster_bitmask[srcbit], 956 /*d*/ dl, 957 /*c*/ color, 958 /*pst*/ *dstlong = ( *dstlong & ~twobytemask[dstbyte] ) | 959 ( dl & twobytemask[dstbyte] ); 960 if ( srcbit == 31 ) 961 { 962 srcbit = 0; 963 ++srclong; 964 } 965 else 966 ++srcbit; 967 if ( dstbyte == 1 ) 968 { 969 dstbyte = 0; 970 ++dstlong; 971 } 972 else 973 ++dstbyte; 974 --i; 975 } ) 976 977 srclin += src->linelongs; 978 dstlin += dst->linelongs; 979 } 980 } 981 #endif /* RCONS_16BPP */ 982 } 983 #ifdef RCONS_2BPP 984 else if ( src->depth == 2 ) 985 { 986 /* Two to two blit. */ 987 u_int32_t* srclin1; 988 u_int32_t* dstlin1; 989 int srcleftignore, srcrightignore, srclongs; 990 int dstleftignore, dstrightignore, dstlongs; 991 992 srclin1 = RAS_ADDR( src, sx, sy ); 993 dstlin1 = RAS_ADDR( dst, dx, dy ); 994 995 srcleftignore = ( sx & 15 ) * 2; 996 srclongs = ( srcleftignore + w * 2 + 31 ) >> 5; 997 srcrightignore = ( srclongs * 32 - w * 2 - srcleftignore ) & 31; 998 dstleftignore = ( dx & 15 ) * 2; 999 dstlongs = ( dstleftignore + w * 2 + 31 ) >> 5; 1000 dstrightignore = ( dstlongs * 32 - w * 2 - dstleftignore ) & 31; 1001 1002 return raster_blit( 1003 src, srclin1, srcleftignore, srcrightignore, srclongs, 1004 dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op ); 1005 } 1006 #endif /* RCONS_2BPP */ 1007 #ifdef RCONS_4BPP 1008 else if ( src->depth == 4 ) 1009 { 1010 /* Four to four blit. */ 1011 u_int32_t* srclin1; 1012 u_int32_t* dstlin1; 1013 int srcleftignore, srcrightignore, srclongs; 1014 int dstleftignore, dstrightignore, dstlongs; 1015 1016 srclin1 = RAS_ADDR( src, sx, sy ); 1017 dstlin1 = RAS_ADDR( dst, dx, dy ); 1018 1019 srcleftignore = ( sx & 7 ) * 4; 1020 srclongs = ( srcleftignore + w * 4 + 31 ) >> 5; 1021 srcrightignore = ( srclongs * 32 - w * 4 - srcleftignore ) & 31; 1022 dstleftignore = ( dx & 7 ) * 4; 1023 dstlongs = ( dstleftignore + w * 4 + 31 ) >> 5; 1024 dstrightignore = ( dstlongs * 32 - w * 4 - dstleftignore ) & 31; 1025 1026 return raster_blit( 1027 src, srclin1, srcleftignore, srcrightignore, srclongs, 1028 dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op ); 1029 } 1030 #endif /* RCONS_4BPP */ 1031 1032 else if ( src->depth == 8 ) 1033 { 1034 /* Eight to eight blit. */ 1035 u_int32_t* srclin1; 1036 u_int32_t* dstlin1; 1037 int srcleftignore, srcrightignore, srclongs; 1038 int dstleftignore, dstrightignore, dstlongs; 1039 1040 if ( dst->depth != 8 ) 1041 return -1; /* depth mismatch */ 1042 1043 srclin1 = RAS_ADDR( src, sx, sy ); 1044 dstlin1 = RAS_ADDR( dst, dx, dy ); 1045 1046 #ifdef BCOPY_FASTER 1047 /* Special-case full-width to full-width copies. */ 1048 if ( op == RAS_SRC && src->width == w && dst->width == w && 1049 src->linelongs == dst->linelongs && src->linelongs == w >> 2 ) 1050 { 1051 bcopy( (char*) srclin1, (char*) dstlin1, 1052 h * src->linelongs * sizeof(u_int32_t) ); 1053 return 0; 1054 } 1055 #endif /*BCOPY_FASTER*/ 1056 1057 srcleftignore = ( sx & 3 ) * 8; 1058 srclongs = ( srcleftignore + w * 8 + 31 ) >> 5; 1059 srcrightignore = ( srclongs * 32 - w * 8 - srcleftignore ) & 31; 1060 dstleftignore = ( dx & 3 ) * 8; 1061 dstlongs = ( dstleftignore + w * 8 + 31 ) >> 5; 1062 dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31; 1063 1064 return raster_blit( 1065 src, srclin1, srcleftignore, srcrightignore, srclongs, 1066 dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op ); 1067 } 1068 #ifdef RCONS_16BPP 1069 else 1070 { 1071 /* Sixteen to sixteen blit. */ 1072 u_int32_t* srclin1; 1073 u_int32_t* dstlin1; 1074 int srcleftignore, srcrightignore, srclongs; 1075 int dstleftignore, dstrightignore, dstlongs; 1076 1077 srclin1 = RAS_ADDR( src, sx, sy ); 1078 dstlin1 = RAS_ADDR( dst, dx, dy ); 1079 1080 srcleftignore = ( sx & 1 ) * 16; 1081 srclongs = ( srcleftignore + w * 16 + 31 ) >> 5; 1082 srcrightignore = ( srclongs * 32 - w * 16 - srcleftignore ) & 31; 1083 dstleftignore = ( dx & 1 ) * 16; 1084 dstlongs = ( dstleftignore + w * 16 + 31 ) >> 5; 1085 dstrightignore = ( dstlongs * 32 - w * 16 - dstleftignore ) & 31; 1086 1087 return raster_blit( 1088 src, srclin1, srcleftignore, srcrightignore, srclongs, 1089 dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op ); 1090 } 1091 #endif /* RCONS_16BPP */ 1092 return 0; 1093 } 1094 1095 /* Semi-public routine to do a no-src bitblit without clipping. Returns 0 1096 ** on success, -1 on failure. 1097 */ 1098 int 1099 raster_op_nosrc_noclip( dst, dx, dy, w, h, rop ) 1100 struct raster* dst; 1101 int dx, dy, w, h, rop; 1102 { 1103 int op; 1104 1105 op = RAS_GETOP( rop ); 1106 1107 if ( dst->depth == 1 ) 1108 { 1109 /* One-bit no-src blit. */ 1110 u_int32_t* dstlin1; 1111 u_int32_t* dstlin2; 1112 u_int32_t* dstlin; 1113 int dstleftignore, dstrightignore, dstlongs; 1114 u_int32_t dl, lm, nlm, rm, nrm; 1115 u_int32_t* dstlong2; 1116 u_int32_t* dstlong; 1117 1118 dstlin1 = RAS_ADDR( dst, dx, dy ); 1119 1120 #ifdef BCOPY_FASTER 1121 /* Special-case full-width clears. */ 1122 if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 5 ) 1123 { 1124 bzero( (char*) dstlin1, h * dst->linelongs * sizeof(u_int32_t) ); 1125 return 0; 1126 } 1127 #endif /*BCOPY_FASTER*/ 1128 1129 dstleftignore = ( dx & 31 ); 1130 dstlongs = ( dstleftignore + w + 31 ) >> 5; 1131 dstrightignore = ( dstlongs * 32 - w - dstleftignore ) & 31; 1132 1133 dstlin2 = dstlin1 + h * dst->linelongs; 1134 dstlin = dstlin1; 1135 1136 if ( dstlongs == 1 ) 1137 { 1138 /* It fits into a single longword. */ 1139 lm = leftmask[dstleftignore] | rightmask[dstrightignore]; 1140 nlm = ~lm; 1141 while ( dstlin != dstlin2 ) 1142 { 1143 ROP_DST( 1144 /*op*/ op, 1145 /*pre*/ dl = *dstlin;, 1146 /*d*/ dl, 1147 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) 1148 1149 dstlin += dst->linelongs; 1150 } 1151 } 1152 else 1153 { 1154 lm = leftmask[dstleftignore]; 1155 rm = rightmask[dstrightignore]; 1156 nrm = ~rm; 1157 nlm = ~lm; 1158 1159 while ( dstlin != dstlin2 ) 1160 { 1161 dstlong = dstlin; 1162 dstlong2 = dstlong + dstlongs; 1163 if ( dstrightignore != 0 ) 1164 --dstlong2; 1165 1166 /* Leading edge. */ 1167 if ( dstleftignore != 0 ) 1168 { 1169 ROP_DST( 1170 /*op*/ op, 1171 /*pre*/ dl = *dstlong;, 1172 /*d*/ dl, 1173 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1174 ++dstlong; 1175 } 1176 1177 /* Main rop. */ 1178 ROP_DST( 1179 /*op*/ op, 1180 /*pre*/ while ( dstlong != dstlong2 ) 1181 {, 1182 /*d*/ *dstlong, 1183 /*pst*/ ++dstlong; 1184 } ) 1185 1186 /* Trailing edge. */ 1187 if ( dstrightignore != 0 ) 1188 { 1189 ROP_DST( 1190 /*op*/ op, 1191 /*pre*/ dl = *dstlong;, 1192 /*d*/ dl, 1193 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1194 } 1195 1196 dstlin += dst->linelongs; 1197 } 1198 } 1199 } 1200 1201 #ifdef RCONS_2BPP 1202 else if ( dst->depth == 2 ) 1203 { 1204 /* Two-bit no-src blit. */ 1205 u_int32_t color; 1206 u_int32_t* dstlin1; 1207 u_int32_t* dstlin2; 1208 u_int32_t* dstlin; 1209 int dstleftignore, dstrightignore, dstlongs; 1210 u_int32_t dl, lm, nlm, rm, nrm; 1211 u_int32_t* dstlong2; 1212 u_int32_t* dstlong; 1213 1214 dstlin1 = RAS_ADDR( dst, dx, dy ); 1215 1216 #ifdef BCOPY_FASTER 1217 /* Special-case full-width clears. */ 1218 if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 4 ) 1219 { 1220 bzero( (char*) dstlin1, h * dst->linelongs * sizeof(u_int32_t) ); 1221 return 0; 1222 } 1223 #endif /*BCOPY_FASTER*/ 1224 1225 color = RAS_GETCOLOR( rop ); 1226 if ( color == 0 ) 1227 color = 3; 1228 1229 /* Make 32 bits of color so we can do the ROP without shifting. */ 1230 color |= (( color << 30 ) | ( color << 28 ) | ( color << 26 ) 1231 | ( color << 24 ) | ( color << 22 ) | ( color << 20 ) 1232 | ( color << 18 ) | ( color << 16 ) | ( color << 14 ) 1233 | ( color << 12 ) | ( color << 10 ) | ( color << 8 ) 1234 | ( color << 6 ) | ( color << 4 ) | ( color << 2 )); 1235 1236 dstleftignore = ( dx & 15 ) * 2; 1237 dstlongs = ( dstleftignore + w * 2 + 31 ) >> 5; 1238 dstrightignore = ( dstlongs * 32 - w * 2 - dstleftignore ) & 31; 1239 1240 dstlin2 = dstlin1 + h * dst->linelongs; 1241 dstlin = dstlin1; 1242 1243 if ( dstlongs == 1 ) 1244 { 1245 /* It fits into a single longword. */ 1246 lm = leftmask[dstleftignore] | rightmask[dstrightignore]; 1247 nlm = ~lm; 1248 while ( dstlin != dstlin2 ) 1249 { 1250 ROP_DST( 1251 /*op*/ op, 1252 /*pre*/ dl = *dstlin;, 1253 /*d*/ dl, 1254 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) 1255 1256 dstlin += dst->linelongs; 1257 } 1258 } 1259 else 1260 { 1261 lm = leftmask[dstleftignore]; 1262 rm = rightmask[dstrightignore]; 1263 nrm = ~rm; 1264 nlm = ~lm; 1265 1266 while ( dstlin != dstlin2 ) 1267 { 1268 dstlong = dstlin; 1269 dstlong2 = dstlong + dstlongs; 1270 if ( dstrightignore != 0 ) 1271 --dstlong2; 1272 1273 /* Leading edge. */ 1274 if ( dstleftignore != 0 ) 1275 { 1276 ROP_DST( 1277 /*op*/ op, 1278 /*pre*/ dl = *dstlong;, 1279 /*d*/ dl, 1280 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1281 ++dstlong; 1282 } 1283 1284 /* Main rop. */ 1285 ROP_DST( 1286 /*op*/ op, 1287 /*pre*/ while ( dstlong != dstlong2 ) 1288 {, 1289 /*d*/ *dstlong, 1290 /*pst*/ ++dstlong; 1291 } ) 1292 1293 /* Trailing edge. */ 1294 if ( dstrightignore != 0 ) 1295 { 1296 ROP_DST( 1297 /*op*/ op, 1298 /*pre*/ dl = *dstlong;, 1299 /*d*/ dl, 1300 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1301 } 1302 1303 dstlin += dst->linelongs; 1304 } 1305 } 1306 } 1307 #endif /* RCONS_2BPP */ 1308 #ifdef RCONS_4BPP 1309 else if ( dst->depth == 4 ) 1310 { 1311 /* Two-bit no-src blit. */ 1312 u_int32_t color; 1313 u_int32_t* dstlin1; 1314 u_int32_t* dstlin2; 1315 u_int32_t* dstlin; 1316 int dstleftignore, dstrightignore, dstlongs; 1317 u_int32_t dl, lm, nlm, rm, nrm; 1318 u_int32_t* dstlong2; 1319 u_int32_t* dstlong; 1320 1321 dstlin1 = RAS_ADDR( dst, dx, dy ); 1322 1323 #ifdef BCOPY_FASTER 1324 /* Special-case full-width clears. */ 1325 if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 3 ) 1326 { 1327 bzero( (char*) dstlin1, h * dst->linelongs * sizeof(u_int32_t) ); 1328 return 0; 1329 } 1330 #endif /*BCOPY_FASTER*/ 1331 1332 color = RAS_GETCOLOR( rop ); 1333 if ( color == 0 ) 1334 color = 15; 1335 1336 /* Make 32 bits of color so we can do the ROP without shifting. */ 1337 color |= (( color << 28 ) | ( color << 24 ) 1338 | ( color << 20 ) | ( color << 16 ) 1339 | ( color << 12 ) | ( color << 8 ) 1340 | ( color << 4 )); 1341 1342 dstleftignore = ( dx & 7 ) * 4; 1343 dstlongs = ( dstleftignore + w * 4 + 31 ) >> 5; 1344 dstrightignore = ( dstlongs * 32 - w * 4 - dstleftignore ) & 31; 1345 1346 dstlin2 = dstlin1 + h * dst->linelongs; 1347 dstlin = dstlin1; 1348 1349 if ( dstlongs == 1 ) 1350 { 1351 /* It fits into a single longword. */ 1352 lm = leftmask[dstleftignore] | rightmask[dstrightignore]; 1353 nlm = ~lm; 1354 while ( dstlin != dstlin2 ) 1355 { 1356 ROP_DST( 1357 /*op*/ op, 1358 /*pre*/ dl = *dstlin;, 1359 /*d*/ dl, 1360 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) 1361 1362 dstlin += dst->linelongs; 1363 } 1364 } 1365 else 1366 { 1367 lm = leftmask[dstleftignore]; 1368 rm = rightmask[dstrightignore]; 1369 nrm = ~rm; 1370 nlm = ~lm; 1371 1372 while ( dstlin != dstlin2 ) 1373 { 1374 dstlong = dstlin; 1375 dstlong2 = dstlong + dstlongs; 1376 if ( dstrightignore != 0 ) 1377 --dstlong2; 1378 1379 /* Leading edge. */ 1380 if ( dstleftignore != 0 ) 1381 { 1382 ROP_DST( 1383 /*op*/ op, 1384 /*pre*/ dl = *dstlong;, 1385 /*d*/ dl, 1386 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1387 ++dstlong; 1388 } 1389 1390 /* Main rop. */ 1391 ROP_DST( 1392 /*op*/ op, 1393 /*pre*/ while ( dstlong != dstlong2 ) 1394 {, 1395 /*d*/ *dstlong, 1396 /*pst*/ ++dstlong; 1397 } ) 1398 1399 /* Trailing edge. */ 1400 if ( dstrightignore != 0 ) 1401 { 1402 ROP_DST( 1403 /*op*/ op, 1404 /*pre*/ dl = *dstlong;, 1405 /*d*/ dl, 1406 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1407 } 1408 1409 dstlin += dst->linelongs; 1410 } 1411 } 1412 } 1413 #endif /* RCONS_4BPP */ 1414 else if ( dst->depth == 8) 1415 { 1416 /* Eight-bit no-src blit. */ 1417 u_int32_t color; 1418 u_int32_t* dstlin1; 1419 u_int32_t* dstlin2; 1420 u_int32_t* dstlin; 1421 int dstleftignore, dstrightignore, dstlongs; 1422 u_int32_t dl, lm, nlm, rm, nrm; 1423 u_int32_t* dstlong2; 1424 u_int32_t* dstlong; 1425 1426 dstlin1 = RAS_ADDR( dst, dx, dy ); 1427 1428 #ifdef BCOPY_FASTER 1429 /* Special-case full-width clears. */ 1430 if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 2 ) 1431 { 1432 bzero( (char*) dstlin1, h * dst->linelongs * sizeof(u_int32_t) ); 1433 return 0; 1434 } 1435 #endif /*BCOPY_FASTER*/ 1436 1437 color = RAS_GETCOLOR( rop ); 1438 if ( color == 0 ) 1439 color = 255; 1440 1441 /* Make 32 bits of color so we can do the ROP without shifting. */ 1442 color |= ( color << 24 ) | ( color << 16 ) | ( color << 8 ); 1443 1444 dstleftignore = ( dx & 3 ) * 8; 1445 dstlongs = ( dstleftignore + w * 8 + 31 ) >> 5; 1446 dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31; 1447 1448 dstlin2 = dstlin1 + h * dst->linelongs; 1449 dstlin = dstlin1; 1450 1451 if ( dstlongs == 1 ) 1452 { 1453 /* It fits into a single longword. */ 1454 lm = leftmask[dstleftignore] | rightmask[dstrightignore]; 1455 nlm = ~lm; 1456 while ( dstlin != dstlin2 ) 1457 { 1458 ROP_DSTCOLOR( 1459 /*op*/ op, 1460 /*pre*/ dl = *dstlin;, 1461 /*d*/ dl, 1462 /*c*/ color, 1463 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) 1464 1465 dstlin += dst->linelongs; 1466 } 1467 } 1468 else 1469 { 1470 lm = leftmask[dstleftignore]; 1471 rm = rightmask[dstrightignore]; 1472 nrm = ~rm; 1473 nlm = ~lm; 1474 while ( dstlin != dstlin2 ) 1475 { 1476 dstlong = dstlin; 1477 dstlong2 = dstlong + dstlongs; 1478 if ( dstrightignore != 0 ) 1479 --dstlong2; 1480 1481 /* Leading edge. */ 1482 if ( dstleftignore != 0 ) 1483 { 1484 ROP_DSTCOLOR( 1485 /*op*/ op, 1486 /*pre*/ dl = *dstlong;, 1487 /*d*/ dl, 1488 /*c*/ color, 1489 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1490 ++dstlong; 1491 } 1492 1493 /* Main rop. */ 1494 ROP_DSTCOLOR( 1495 /*op*/ op, 1496 /*pre*/ while ( dstlong != dstlong2 ) 1497 {, 1498 /*d*/ *dstlong, 1499 /*c*/ color, 1500 /*pst*/ ++dstlong; 1501 } ) 1502 1503 /* Trailing edge. */ 1504 if ( dstrightignore != 0 ) 1505 { 1506 ROP_DSTCOLOR( 1507 /*op*/ op, 1508 /*pre*/ dl = *dstlong;, 1509 /*d*/ dl, 1510 /*c*/ color, 1511 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1512 } 1513 1514 dstlin += dst->linelongs; 1515 } 1516 } 1517 } 1518 #ifdef RCONS_16BPP 1519 else 1520 { 1521 /* Sixteen-bit no-src blit. */ 1522 u_int32_t color; 1523 u_int32_t* dstlin1; 1524 u_int32_t* dstlin2; 1525 u_int32_t* dstlin; 1526 int dstleftignore, dstrightignore, dstlongs; 1527 u_int32_t dl, lm, nlm, rm, nrm; 1528 u_int32_t* dstlong2; 1529 u_int32_t* dstlong; 1530 1531 dstlin1 = RAS_ADDR( dst, dx, dy ); 1532 1533 #ifdef BCOPY_FASTER 1534 /* Special-case full-width clears. */ 1535 if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 1 ) 1536 { 1537 bzero( (char*) dstlin1, h * dst->linelongs * sizeof(u_int32_t) ); 1538 return 0; 1539 } 1540 #endif /*BCOPY_FASTER*/ 1541 1542 color = RAS_GETCOLOR( rop ); 1543 if ( color == 0 ) 1544 color = 0xffff; /* XXX */ 1545 1546 /* Make 32 bits of color so we can do the ROP without shifting. */ 1547 color |= ( color << 16 ); 1548 1549 dstleftignore = ( dx & 1 ) * 16; 1550 dstlongs = ( dstleftignore + w * 16 + 31 ) >> 5; 1551 dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31; 1552 1553 dstlin2 = dstlin1 + h * dst->linelongs; 1554 dstlin = dstlin1; 1555 1556 if ( dstlongs == 1 ) 1557 { 1558 /* It fits into a single longword. */ 1559 lm = leftmask[dstleftignore] | rightmask[dstrightignore]; 1560 nlm = ~lm; 1561 while ( dstlin != dstlin2 ) 1562 { 1563 ROP_DSTCOLOR( 1564 /*op*/ op, 1565 /*pre*/ dl = *dstlin;, 1566 /*d*/ dl, 1567 /*c*/ color, 1568 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) 1569 1570 dstlin += dst->linelongs; 1571 } 1572 } 1573 else 1574 { 1575 lm = leftmask[dstleftignore]; 1576 rm = rightmask[dstrightignore]; 1577 nrm = ~rm; 1578 nlm = ~lm; 1579 while ( dstlin != dstlin2 ) 1580 { 1581 dstlong = dstlin; 1582 dstlong2 = dstlong + dstlongs; 1583 if ( dstrightignore != 0 ) 1584 --dstlong2; 1585 1586 /* Leading edge. */ 1587 if ( dstleftignore != 0 ) 1588 { 1589 ROP_DSTCOLOR( 1590 /*op*/ op, 1591 /*pre*/ dl = *dstlong;, 1592 /*d*/ dl, 1593 /*c*/ color, 1594 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1595 ++dstlong; 1596 } 1597 1598 /* Main rop. */ 1599 ROP_DSTCOLOR( 1600 /*op*/ op, 1601 /*pre*/ while ( dstlong != dstlong2 ) 1602 {, 1603 /*d*/ *dstlong, 1604 /*c*/ color, 1605 /*pst*/ ++dstlong; 1606 } ) 1607 1608 /* Trailing edge. */ 1609 if ( dstrightignore != 0 ) 1610 { 1611 ROP_DSTCOLOR( 1612 /*op*/ op, 1613 /*pre*/ dl = *dstlong;, 1614 /*d*/ dl, 1615 /*c*/ color, 1616 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1617 } 1618 1619 dstlin += dst->linelongs; 1620 } 1621 } 1622 } 1623 #endif /* RCONS_16BPP */ 1624 1625 return 0; 1626 } 1627 1628 /* This is a general bitblit routine, handling overlapping source and 1629 ** destination. It's used for both the 1-to-1 and 8-to-8 cases. 1630 */ 1631 static int 1632 raster_blit( src, srclin1, srcleftignore, srcrightignore, srclongs, dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op ) 1633 struct raster* src; 1634 u_int32_t* srclin1; 1635 int srcleftignore, srcrightignore, srclongs; 1636 struct raster* dst; 1637 u_int32_t* dstlin1; 1638 int dstleftignore, dstrightignore, dstlongs; 1639 int h, op; 1640 { 1641 u_int32_t* srclin2; 1642 u_int32_t* dstlin2; 1643 int srclininc, dstlininc; 1644 u_int32_t* srclin; 1645 u_int32_t* dstlin; 1646 int prevleftshift, currrightshift; 1647 int longinc; 1648 u_int32_t* srclong; 1649 u_int32_t* dstlong; 1650 u_int32_t* dstlong2; 1651 u_int32_t dl, lm, nlm, rm, nrm; 1652 1653 prevleftshift = ( srcleftignore - dstleftignore ) & 31; 1654 1655 srclin2 = srclin1 + h * src->linelongs; 1656 dstlin2 = dstlin1 + h * dst->linelongs; 1657 srclininc = src->linelongs; 1658 dstlininc = dst->linelongs; 1659 longinc = 1; 1660 1661 /* Check for overlaps. */ 1662 if ( ( dstlin1 >= srclin1 && dstlin1 < srclin1 + srclongs ) || 1663 ( srclin1 >= dstlin1 && srclin1 < dstlin1 + dstlongs ) ) 1664 { 1665 /* Horizontal overlap. Should we reverse? */ 1666 if ( srclin1 < dstlin1 ) 1667 { 1668 longinc = -1; 1669 srclin1 += srclongs - 1; 1670 srclin2 += srclongs - 1; 1671 dstlin1 += dstlongs - 1; 1672 } 1673 } 1674 else if ( ( dstlin1 >= srclin1 && dstlin1 < srclin2 ) || 1675 ( srclin1 >= dstlin1 && srclin1 < dstlin2 ) ) 1676 { 1677 /* Vertical overlap. Should we reverse? */ 1678 if ( srclin1 < dstlin1 ) 1679 { 1680 srclin2 = srclin1 - srclininc; 1681 srclin1 += ( h - 1 ) * srclininc; 1682 dstlin1 += ( h - 1 ) * dstlininc; 1683 srclininc = -srclininc; 1684 dstlininc = -dstlininc; 1685 } 1686 } 1687 srclin = srclin1; 1688 dstlin = dstlin1; 1689 1690 if ( prevleftshift == 0 ) 1691 { 1692 /* The bits line up, no shifting necessary. */ 1693 if ( dstlongs == 1 ) 1694 { 1695 /* It all fits into a single longword. */ 1696 lm = leftmask[dstleftignore] | rightmask[dstrightignore]; 1697 nlm = ~lm; 1698 while ( srclin != srclin2 ) 1699 { 1700 ROP_SRCDST( 1701 /*op*/ op, 1702 /*pre*/ dl = *dstlin;, 1703 /*s*/ *srclin, 1704 /*d*/ dl, 1705 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) 1706 1707 srclin += srclininc; 1708 dstlin += dstlininc; 1709 } 1710 } 1711 else 1712 { 1713 /* Multiple longwords. */ 1714 lm = leftmask[dstleftignore]; 1715 rm = rightmask[dstrightignore]; 1716 nrm = ~rm; 1717 nlm = ~lm; 1718 if ( longinc == 1 ) 1719 { 1720 /* Left to right. */ 1721 while ( srclin != srclin2 ) 1722 { 1723 srclong = srclin; 1724 dstlong = dstlin; 1725 dstlong2 = dstlong + dstlongs; 1726 if ( dstrightignore != 0 ) 1727 --dstlong2; 1728 1729 /* Leading edge. */ 1730 if ( dstleftignore != 0 ) 1731 { 1732 ROP_SRCDST( 1733 /*op*/ op, 1734 /*pre*/ dl = *dstlong;, 1735 /*s*/ *srclong, 1736 /*d*/ dl, 1737 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1738 ++srclong; 1739 ++dstlong; 1740 } 1741 1742 /* Main rop. */ 1743 ROP_SRCDST( 1744 /*op*/ op, 1745 /*pre*/ while ( dstlong != dstlong2 ) 1746 {, 1747 /*s*/ *srclong, 1748 /*d*/ *dstlong, 1749 /*pst*/ ++srclong; 1750 ++dstlong; 1751 } ) 1752 1753 /* Trailing edge. */ 1754 if ( dstrightignore != 0 ) 1755 { 1756 ROP_SRCDST( 1757 /*op*/ op, 1758 /*pre*/ dl = *dstlong;, 1759 /*s*/ *srclong, 1760 /*d*/ dl, 1761 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1762 } 1763 1764 srclin += srclininc; 1765 dstlin += dstlininc; 1766 } 1767 } 1768 else 1769 { 1770 /* Right to left. */ 1771 while ( srclin != srclin2 ) 1772 { 1773 srclong = srclin; 1774 dstlong = dstlin; 1775 dstlong2 = dstlong - dstlongs; 1776 if ( dstleftignore != 0 ) 1777 ++dstlong2; 1778 1779 /* Leading edge. */ 1780 if ( dstrightignore != 0 ) 1781 { 1782 ROP_SRCDST( 1783 /*op*/ op, 1784 /*pre*/ dl = *dstlong;, 1785 /*s*/ *srclong, 1786 /*d*/ dl, 1787 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1788 --srclong; 1789 --dstlong; 1790 } 1791 1792 /* Main rop. */ 1793 ROP_SRCDST( 1794 /*op*/ op, 1795 /*pre*/ while ( dstlong != dstlong2 ) 1796 {, 1797 /*s*/ *srclong, 1798 /*d*/ *dstlong, 1799 /*pst*/ --srclong; 1800 --dstlong; 1801 } ) 1802 1803 /* Trailing edge. */ 1804 if ( dstleftignore != 0 ) 1805 { 1806 ROP_SRCDST( 1807 /*op*/ op, 1808 /*pre*/ dl = *dstlong;, 1809 /*s*/ *srclong, 1810 /*d*/ dl, 1811 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1812 } 1813 1814 srclin += srclininc; 1815 dstlin += dstlininc; 1816 } 1817 } 1818 } 1819 } 1820 1821 else 1822 { 1823 /* General case, with shifting and everything. */ 1824 u_int32_t sl, prevsl; 1825 1826 currrightshift = 32 - prevleftshift; 1827 if ( srclongs == 1 && dstlongs == 1 ) 1828 { 1829 /* It fits into a single longword, with a shift. */ 1830 lm = leftmask[dstleftignore] | rightmask[dstrightignore]; 1831 nlm = ~lm; 1832 if ( srcleftignore > dstleftignore ) 1833 { 1834 while ( srclin != srclin2 ) 1835 { 1836 ROP_SRCDST( 1837 /*op*/ op, 1838 /*pre*/ dl = *dstlin;, 1839 /*s*/ *srclin LSOP prevleftshift, 1840 /*d*/ dl, 1841 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) 1842 1843 srclin += srclininc; 1844 dstlin += dstlininc; 1845 } 1846 } 1847 else 1848 { 1849 while ( srclin != srclin2 ) 1850 { 1851 ROP_SRCDST( 1852 /*op*/ op, 1853 /*pre*/ dl = *dstlin;, 1854 /*s*/ *srclin RSOP currrightshift, 1855 /*d*/ dl, 1856 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) 1857 1858 srclin += srclininc; 1859 dstlin += dstlininc; 1860 } 1861 } 1862 } 1863 else 1864 { 1865 /* Multiple longwords. */ 1866 lm = leftmask[dstleftignore]; 1867 rm = rightmask[dstrightignore]; 1868 nrm = ~rm; 1869 nlm = ~lm; 1870 if ( longinc == 1 ) 1871 { 1872 /* Left to right. */ 1873 while ( srclin != srclin2 ) 1874 { 1875 srclong = srclin; 1876 dstlong = dstlin; 1877 dstlong2 = dstlong + dstlongs; 1878 if ( srcleftignore > dstleftignore ) 1879 prevsl = *srclong++ LSOP prevleftshift; 1880 else 1881 prevsl = 0; 1882 if ( dstrightignore != 0 ) 1883 --dstlong2; 1884 1885 /* Leading edge. */ 1886 if ( dstleftignore != 0 ) 1887 { 1888 ROP_SRCDST( 1889 /*op*/ op, 1890 /*pre*/ sl = *srclong; 1891 dl = *dstlong;, 1892 /*s*/ prevsl | ( sl RSOP currrightshift ), 1893 /*d*/ dl, 1894 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1895 prevsl = sl LSOP prevleftshift; 1896 ++srclong; 1897 ++dstlong; 1898 } 1899 1900 /* Main rop. */ 1901 ROP_SRCDST( 1902 /*op*/ op, 1903 /*pre*/ while ( dstlong != dstlong2 ) 1904 { 1905 sl = *srclong;, 1906 /*s*/ prevsl | ( sl RSOP currrightshift ), 1907 /*d*/ *dstlong, 1908 /*pst*/ prevsl = sl LSOP prevleftshift; 1909 ++srclong; 1910 ++dstlong; 1911 } ) 1912 1913 /* Trailing edge. */ 1914 if ( dstrightignore != 0 ) 1915 { 1916 ROP_SRCDST( 1917 /*op*/ op, 1918 /*pre*/ dl = *dstlong;, 1919 /*s*/ prevsl | ( *srclong RSOP currrightshift ), 1920 /*d*/ dl, 1921 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1922 } 1923 1924 srclin += srclininc; 1925 dstlin += dstlininc; 1926 } 1927 } 1928 else 1929 { 1930 /* Right to left. */ 1931 while ( srclin != srclin2 ) 1932 { 1933 srclong = srclin; 1934 dstlong = dstlin; 1935 dstlong2 = dstlong - dstlongs; 1936 if ( srcrightignore > dstrightignore ) 1937 prevsl = *srclong-- RSOP currrightshift; 1938 else 1939 prevsl = 0; 1940 if ( dstleftignore != 0 ) 1941 ++dstlong2; 1942 1943 /* Leading edge. */ 1944 if ( dstrightignore != 0 ) 1945 { 1946 ROP_SRCDST( 1947 /*op*/ op, 1948 /*pre*/ sl = *srclong; 1949 dl = *dstlong;, 1950 /*s*/ prevsl | ( sl LSOP prevleftshift ), 1951 /*d*/ dl, 1952 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1953 prevsl = sl RSOP currrightshift; 1954 --srclong; 1955 --dstlong; 1956 } 1957 1958 /* Main rop. */ 1959 ROP_SRCDST( 1960 /*op*/ op, 1961 /*pre*/ while ( dstlong != dstlong2 ) 1962 { 1963 sl = *srclong;, 1964 /*s*/ prevsl | ( sl LSOP prevleftshift ), 1965 /*d*/ *dstlong, 1966 /*pst*/ prevsl = sl RSOP currrightshift; 1967 --srclong; 1968 --dstlong; 1969 } ) 1970 1971 /* Trailing edge. */ 1972 if ( dstleftignore != 0 ) 1973 { 1974 ROP_SRCDST( 1975 /*op*/ op, 1976 /*pre*/ dl = *dstlong;, 1977 /*s*/ prevsl | ( *srclong LSOP prevleftshift ), 1978 /*d*/ dl, 1979 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1980 } 1981 1982 srclin += srclininc; 1983 dstlin += dstlininc; 1984 } 1985 } 1986 } 1987 } 1988 1989 return 0; 1990 } 1991