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