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