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