Home | History | Annotate | Line # | Download | only in rcons
raster_op.c revision 1.2
      1 /*	$NetBSD: raster_op.c,v 1.2 1995/11/24 23:50:54 cgd 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 8-bits
     53  *       8-bits to 8-bits
     54  *   no src required
     55  *       1-bit no-src
     56  *       8-bits no-src
     57  */
     58 
     59 #include <sys/types.h>
     60 #ifdef _KERNEL
     61 #include <dev/rcons/raster.h>
     62 #else
     63 #include "raster.h"
     64 #endif
     65 
     66 /* CONFIGURE: To save on executable size, you can configure out the seldom-used
     67 ** logical operations.  With this variable set, the only operations implemented
     68 ** are: RAS_SRC, RAS_CLEAR, RAS_SET, RAS_INVERT, RAS_XOR, RAS_INVERTSRC.
     69 */
     70 #ifdef _KERNEL
     71 #define PARTIAL_LOGICAL_OPS
     72 #endif
     73 
     74 /* CONFIGURE: bcopy() is supposed to be the ultimately fastest way to move
     75 ** bytes, overlapping or not, ignoring the startup cost.  Unfortunately
     76 ** this is not true on some systems.  For example, on a Sun 3 running
     77 ** SunOS 3.5, bcopy() is about five times slower than a simple for loop
     78 ** on overlapping copies.  And on a 4.1.1 SPARC, bcopy() is about 2/3rds
     79 ** as fast on backwards overlaps.  So, only define this if your bcopy is ok.
     80 */
     81 #undef BCOPY_FASTER
     82 
     83 /* End of configurable definitions. */
     84 
     85 
     86 /* Definitions. */
     87 
     88 /* Raster-op macros.  These encapsulate the switch statements and so make
     89 ** the source code 16 times smaller.  The pre and pst args are code
     90 ** fragments to put before and after the assignment in each case.  They
     91 ** can be the beginning and end of a loop.  If the pst fragment includes a
     92 ** masked assignment, for example to handle the left or right edge cases,
     93 ** a good optimizing compiler will simplify the boolean expressions very
     94 ** nicely - both cc and gcc on the SPARC will do this.
     95 */
     96 
     97 #ifndef PARTIAL_LOGICAL_OPS
     98 
     99 #define ROP_DST(op,pre,d,pst) \
    100     switch ( op ) \
    101 	{ \
    102 	case RAS_CLEAR: \
    103 	pre \
    104 	(d) = 0; \
    105 	pst \
    106 	break; \
    107 	case RAS_INVERT: \
    108 	pre \
    109 	(d) = ~(d); \
    110 	pst \
    111 	break; \
    112 	case RAS_DST: \
    113 	/* noop */ \
    114 	break; \
    115 	case RAS_SET: \
    116 	pre \
    117 	(d) = ~0; \
    118 	pst \
    119 	break; \
    120 	default: \
    121 	return -1; \
    122 	}
    123 
    124 #define ROP_DSTCOLOR(op,pre,d,c,pst) \
    125     switch ( op ) \
    126 	{ \
    127 	case RAS_CLEAR: \
    128 	pre \
    129 	(d) = 0; \
    130 	pst \
    131 	break; \
    132 	case RAS_INVERT: \
    133 	pre \
    134 	(d) = ~(d); \
    135 	pst \
    136 	break; \
    137 	case RAS_DST: \
    138 	/* noop */ \
    139 	break; \
    140 	case RAS_SET: \
    141 	pre \
    142 	(d) = (c); \
    143 	pst \
    144 	break; \
    145 	default: \
    146 	return -1; \
    147 	}
    148 
    149 #define ROP_SRCDST(op,pre,s,d,pst) \
    150     switch ( op ) \
    151 	{ \
    152 	case RAS_NOTOR: \
    153 	pre \
    154 	(d) = ~( (s) | (d) ); \
    155 	pst \
    156 	break; \
    157 	case RAS_NOTSRC_AND_DST: \
    158 	pre \
    159 	(d) = ~(s) & (d); \
    160 	pst \
    161 	break; \
    162 	case RAS_INVERTSRC: \
    163 	pre \
    164 	(d) = ~(s); \
    165 	pst \
    166 	break; \
    167 	case RAS_SRC_AND_NOTDST: \
    168 	pre \
    169 	(d) = (s) & ~(d); \
    170 	pst \
    171 	break; \
    172 	case RAS_XOR: \
    173 	pre \
    174 	(d) = (s) ^ (d); \
    175 	pst \
    176 	break; \
    177 	case RAS_NOTAND: \
    178 	pre \
    179 	(d) = ~( (s) & (d) ); \
    180 	pst \
    181 	break; \
    182 	case RAS_AND: \
    183 	pre \
    184 	(d) = (s) & (d); \
    185 	pst \
    186 	break; \
    187 	case RAS_NOTXOR: \
    188 	pre \
    189 	(d) = ~( (s) ^ (d) ); \
    190 	pst \
    191 	break; \
    192 	case RAS_NOTSRC_OR_DST: \
    193 	pre \
    194 	(d) = ~(s) | (d); \
    195 	pst \
    196 	break; \
    197 	case RAS_SRC: \
    198 	pre \
    199 	(d) = (s); \
    200 	pst \
    201 	break; \
    202 	case RAS_SRC_OR_NOTDST: \
    203 	pre \
    204 	(d) = (s) | ~(d); \
    205 	pst \
    206 	break; \
    207 	case RAS_OR: \
    208 	pre \
    209 	(d) = (s) | (d); \
    210 	pst \
    211 	break; \
    212 	default: \
    213 	return -1; \
    214 	}
    215 
    216 #define ROP_SRCDSTCOLOR(op,pre,s,d,c,pst) \
    217     switch ( op ) \
    218 	{ \
    219 	case RAS_NOTOR: \
    220 	pre \
    221 	if ( s ) \
    222 	    (d) = ~( (c) | (d) ); \
    223 	else \
    224 	    (d) = ~(d); \
    225 	pst \
    226 	break; \
    227 	case RAS_NOTSRC_AND_DST: \
    228 	pre \
    229 	if ( s ) \
    230 	    (d) = ~(c) & (d); \
    231 	pst \
    232 	break; \
    233 	case RAS_INVERTSRC: \
    234 	pre \
    235 	if ( s ) \
    236 	    (d) = ~(c); \
    237 	else \
    238 	    (d) = ~0; \
    239 	pst \
    240 	break; \
    241 	case RAS_SRC_AND_NOTDST: \
    242 	pre \
    243 	if ( s ) \
    244 	    (d) = (c) & ~(d); \
    245 	else \
    246 	    (d) = 0; \
    247 	pst \
    248 	break; \
    249 	case RAS_XOR: \
    250 	pre \
    251 	if ( s ) \
    252 	    (d) = (c) ^ (d); \
    253 	pst \
    254 	break; \
    255 	case RAS_NOTAND: \
    256 	pre \
    257 	if ( s ) \
    258 	    (d) = ~( (c) & (d) ); \
    259 	else \
    260 	    (d) = ~0; \
    261 	pst \
    262 	break; \
    263 	case RAS_AND: \
    264 	pre \
    265 	if ( s ) \
    266 	    (d) = (c) & (d); \
    267 	else \
    268 	    (d) = 0; \
    269 	pst \
    270 	break; \
    271 	case RAS_NOTXOR: \
    272 	pre \
    273 	if ( s ) \
    274 	    (d) = ~( (c) ^ (d) ); \
    275 	else \
    276 	    (d) = ~(d); \
    277 	pst \
    278 	break; \
    279 	case RAS_NOTSRC_OR_DST: \
    280 	pre \
    281 	if ( s ) \
    282 	    (d) = ~(c) | (d); \
    283 	else \
    284 	    (d) = ~0; \
    285 	pst \
    286 	break; \
    287 	case RAS_SRC: \
    288 	pre \
    289 	if ( s ) \
    290 	    (d) = (c); \
    291 	else \
    292 	    (d) = 0; \
    293 	pst \
    294 	break; \
    295 	case RAS_SRC_OR_NOTDST: \
    296 	pre \
    297 	if ( s ) \
    298 	    (d) = (c) | ~(d); \
    299 	else \
    300 	    (d) = ~(d); \
    301 	pst \
    302 	break; \
    303 	case RAS_OR: \
    304 	pre \
    305 	if ( s ) \
    306 	    (d) = (c) | (d); \
    307 	pst \
    308 	break; \
    309 	default: \
    310 	return -1; \
    311 	}
    312 
    313 #else /*PARTIAL_LOGICAL_OPS*/
    314 
    315 #define ROP_DST(op,pre,d,pst) \
    316     switch ( op ) \
    317 	{ \
    318 	case RAS_CLEAR: \
    319 	pre \
    320 	(d) = 0; \
    321 	pst \
    322 	break; \
    323 	case RAS_INVERT: \
    324 	pre \
    325 	(d) = ~(d); \
    326 	pst \
    327 	break; \
    328 	case RAS_SET: \
    329 	pre \
    330 	(d) = ~0; \
    331 	pst \
    332 	break; \
    333 	default: \
    334 	return -1; \
    335 	}
    336 
    337 #define ROP_DSTCOLOR(op,pre,d,c,pst) \
    338     switch ( op ) \
    339 	{ \
    340 	case RAS_CLEAR: \
    341 	pre \
    342 	(d) = 0; \
    343 	pst \
    344 	break; \
    345 	case RAS_INVERT: \
    346 	pre \
    347 	(d) = ~(d); \
    348 	pst \
    349 	break; \
    350 	case RAS_SET: \
    351 	pre \
    352 	(d) = (c); \
    353 	pst \
    354 	break; \
    355 	default: \
    356 	return -1; \
    357 	}
    358 
    359 #define ROP_SRCDST(op,pre,s,d,pst) \
    360     switch ( op ) \
    361 	{ \
    362 	case RAS_INVERTSRC: \
    363 	pre \
    364 	(d) = ~(s); \
    365 	pst \
    366 	break; \
    367 	case RAS_XOR: \
    368 	pre \
    369 	(d) = (s) ^ (d); \
    370 	pst \
    371 	break; \
    372 	case RAS_SRC: \
    373 	pre \
    374 	(d) = (s); \
    375 	pst \
    376 	break; \
    377 	default: \
    378 	return -1; \
    379 	}
    380 
    381 #define ROP_SRCDSTCOLOR(op,pre,s,d,c,pst) \
    382     switch ( op ) \
    383 	{ \
    384 	case RAS_INVERTSRC: \
    385 	pre \
    386 	if ( s ) \
    387 	    (d) = ~(c); \
    388 	else \
    389 	    (d) = ~0; \
    390 	pst \
    391 	break; \
    392 	case RAS_XOR: \
    393 	pre \
    394 	if ( s ) \
    395 	    (d) = (c) ^ (d); \
    396 	pst \
    397 	break; \
    398 	case RAS_SRC: \
    399 	pre \
    400 	if ( s ) \
    401 	    (d) = (c); \
    402 	else \
    403 	    (d) = 0; \
    404 	pst \
    405 	break; \
    406 	default: \
    407 	return -1; \
    408 	}
    409 
    410 #endif /*PARTIAL_LOGICAL_OPS*/
    411 
    412 
    413 /* Variables. */
    414 
    415 static int needsrc[16] = { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0 };
    416 /*                       CLEAR          INVERT          DST            SET */
    417 
    418 #ifdef MSBIT_FIRST
    419 
    420 u_int32_t raster_bitmask[32] = {
    421     0x80000000, 0x40000000, 0x20000000, 0x10000000,
    422     0x08000000, 0x04000000, 0x02000000, 0x01000000,
    423     0x00800000, 0x00400000, 0x00200000, 0x00100000,
    424     0x00080000, 0x00040000, 0x00020000, 0x00010000,
    425     0x00008000, 0x00004000, 0x00002000, 0x00001000,
    426     0x00000800, 0x00000400, 0x00000200, 0x00000100,
    427     0x00000080, 0x00000040, 0x00000020, 0x00000010,
    428     0x00000008, 0x00000004, 0x00000002, 0x00000001 };
    429 
    430 #ifdef MSBYTE_FIRST
    431 static u_int32_t leftmask[32] = {
    432     0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
    433     0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000,
    434     0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
    435     0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000,
    436     0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000,
    437     0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
    438     0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0,
    439     0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe };
    440 static u_int32_t rightmask[32] = {
    441     0x00000000, 0x00000001, 0x00000003, 0x00000007,
    442     0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
    443     0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
    444     0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
    445     0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
    446     0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
    447     0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
    448     0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff };
    449 #endif /*MSBYTE_FIRST*/
    450 
    451 #else /*MSBIT_FIRST*/
    452 
    453 u_int32_t raster_bitmask[32] = {
    454     0x00000001, 0x00000002, 0x00000004, 0x00000008,
    455     0x00000010, 0x00000020, 0x00000040, 0x00000080,
    456     0x00000100, 0x00000200, 0x00000400, 0x00000800,
    457     0x00001000, 0x00002000, 0x00004000, 0x00008000,
    458     0x00010000, 0x00020000, 0x00040000, 0x00080000,
    459     0x00100000, 0x00200000, 0x00400000, 0x00800000,
    460     0x01000000, 0x02000000, 0x04000000, 0x08000000,
    461     0x10000000, 0x20000000, 0x40000000, 0x80000000 };
    462 
    463 #ifndef MSBYTE_FIRST
    464 static u_int32_t leftmask[32] = {
    465     0x00000000, 0x00000001, 0x00000003, 0x00000007,
    466     0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
    467     0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
    468     0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
    469     0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
    470     0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
    471     0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
    472     0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff };
    473 static u_int32_t rightmask[32] = {
    474     0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
    475     0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000,
    476     0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
    477     0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000,
    478     0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000,
    479     0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
    480     0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0,
    481     0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe };
    482 #endif /*not MSBYTE_FIRST*/
    483 
    484 #endif /*MSBIT_FIRST*/
    485 
    486 /* (The odd combinations MSBIT+~MSBYTE and ~MSBIT+MSBYTE could be added.) */
    487 
    488 #ifdef MSBYTE_FIRST
    489 static u_int32_t bytemask[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
    490 #else /*MSBYTE_FIRST*/
    491 static u_int32_t bytemask[4] = { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
    492 #endif /*MSBYTE_FIRST*/
    493 
    494 
    495 /* Forward routines. */
    496 
    497 static int raster_blit();
    498 
    499 
    500 /* Raster operations.  */
    501 
    502 /* Performs a bitblit.  Returns 0 on success, -1 on failure. */
    503 int
    504 raster_op( dst, dx, dy, w, h, rop, src, sx, sy )
    505     struct raster* dst;
    506     int dx, dy, w, h, rop;
    507     struct raster* src;
    508     int sx, sy;
    509     {
    510     if ( dst == (struct raster*) 0 )
    511 	return -1;			/* no destination */
    512 
    513     if ( needsrc[RAS_GETOP( rop )] )
    514 	{
    515 	/* Two-operand blit. */
    516 	if ( src == (struct raster*) 0 )
    517 	    return -1;			/* no source */
    518 
    519 	/* Clip against source. */
    520 	if ( sx < 0 )
    521 	    {
    522 	    w += sx;
    523 	    sx = 0;
    524 	    }
    525 	if ( sy < 0 )
    526 	    {
    527 	    h += sy;
    528 	    sy = 0;
    529 	    }
    530 	if ( sx + w > src->width )
    531 	    w = src->width - sx;
    532 	if ( sy + h > src->height )
    533 	    h = src->height - sy;
    534 
    535 	/* Clip against dest. */
    536 	if ( dx < 0 )
    537 	    {
    538 	    w += dx;
    539 	    sx -= dx;
    540 	    dx = 0;
    541 	    }
    542 	if ( dy < 0 )
    543 	    {
    544 	    h += dy;
    545 	    sy -= dy;
    546 	    dy = 0;
    547 	    }
    548 	if ( dx + w > dst->width )
    549 	    w = dst->width - dx;
    550 	if ( dy + h > dst->height )
    551 	    h = dst->height - dy;
    552 
    553 	if ( w <= 0 || h <= 0 )
    554 	    return 0;			/* nothing to do */
    555 
    556 	return raster_op_noclip( dst, dx, dy, w, h, rop, src, sx, sy );
    557 	}
    558 
    559     /* No source necessary - one-operand blit. */
    560     if ( src != (struct raster*) 0 )
    561 	return -1;			/* unwanted source */
    562 
    563     /* Clip against dest. */
    564     if ( dx < 0 )
    565 	{
    566 	w += dx;
    567 	dx = 0;
    568 	}
    569     if ( dy < 0 )
    570 	{
    571 	h += dy;
    572 	dy = 0;
    573 	}
    574     if ( dx + w > dst->width )
    575 	w = dst->width - dx;
    576     if ( dy + h > dst->height )
    577 	h = dst->height - dy;
    578 
    579     if ( w <= 0 || h <= 0 )
    580 	return 0;			/* nothing to do */
    581 
    582     return raster_op_nosrc_noclip( dst, dx, dy, w, h, rop );
    583     }
    584 
    585 /* Semi-public routine to do a bitblit without clipping.  Returns 0 on
    586 ** success, -1 on failure.
    587 */
    588 int
    589 raster_op_noclip( dst, dx, dy, w, h, rop, src, sx, sy )
    590     struct raster* dst;
    591     int dx, dy, w, h, rop;
    592     struct raster* src;
    593     int sx, sy;
    594     {
    595     int op;
    596 
    597     op = RAS_GETOP( rop );
    598 
    599     if ( src->depth == 1 )
    600 	{
    601 	/* One-bit to ? blit. */
    602 	if ( dst->depth == 1 )
    603 	    {
    604 	    /* One to one blit. */
    605 	    u_int32_t* srclin1;
    606 	    u_int32_t* dstlin1;
    607 	    int srcleftignore, srcrightignore, srclongs;
    608 	    int dstleftignore, dstrightignore, dstlongs;
    609 
    610 	    srclin1 = RAS_ADDR( src, sx, sy );
    611 	    dstlin1 = RAS_ADDR( dst, dx, dy );
    612 
    613 #ifdef BCOPY_FASTER
    614 	    /* Special-case full-width to full-width copies. */
    615 	    if ( op == RAS_SRC && src->width == w && dst->width == w &&
    616 		 src->linelongs == dst->linelongs && src->linelongs == w >> 5 )
    617 		{
    618 		bcopy(
    619 		    (char*) srclin1, (char*) dstlin1,
    620 		    h * src->linelongs * sizeof(u_int32_t) );
    621 		return 0;
    622 		}
    623 #endif /*BCOPY_FASTER*/
    624 
    625 	    srcleftignore = ( sx & 31 );
    626 	    srclongs = ( srcleftignore + w + 31 ) >> 5;
    627 	    srcrightignore = ( srclongs * 32 - w - srcleftignore ) & 31;
    628 	    dstleftignore = ( dx & 31 );
    629 	    dstlongs = ( dstleftignore + w + 31 ) >> 5;
    630 	    dstrightignore = ( dstlongs * 32 - w - dstleftignore ) & 31;
    631 
    632 	    return raster_blit(
    633 		src, srclin1, srcleftignore, srcrightignore, srclongs,
    634 		dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
    635 	    }
    636 
    637 	else
    638 	    {
    639 	    /* One to eight, using the color in the rop.  This could
    640 	    ** probably be sped up by handling each four-bit source nybble
    641 	    ** as a group, indexing into a 16-element runtime-constructed
    642 	    ** table of longwords.
    643 	    */
    644 	    u_int32_t* srclin1;
    645 	    u_int32_t* dstlin1;
    646 	    u_int32_t* srclin2;
    647 	    u_int32_t* srclin;
    648 	    u_int32_t* dstlin;
    649 	    register u_int32_t* srclong;
    650 	    register u_int32_t* dstlong;
    651 	    register u_int32_t color, dl;
    652 	    register int srcbit, dstbyte, i;
    653 
    654 	    color = RAS_GETCOLOR( rop );
    655 	    if ( color == 0 )
    656 		color = 255;
    657 
    658 	    /* Make 32 bits of color so we can do the ROP without shifting. */
    659 	    color |= ( color << 24 ) | ( color << 16 ) | ( color << 8 );
    660 
    661 	    /* Don't have to worry about overlapping blits here. */
    662 	    srclin1 = RAS_ADDR( src, sx, sy );
    663 	    srclin2 = srclin1 + h * src->linelongs;
    664 	    dstlin1 = RAS_ADDR( dst, dx, dy );
    665 	    srclin = srclin1;
    666 	    dstlin = dstlin1;
    667 	    while ( srclin != srclin2 )
    668 		{
    669 		srclong = srclin;
    670 		srcbit = sx & 31;
    671 		dstlong = dstlin;
    672 		dstbyte = dx & 3;
    673 		i = w;
    674 
    675 		/* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */
    676 		ROP_SRCDSTCOLOR(
    677 		/*op*/  op,
    678 		/*pre*/ while ( i > 0 )
    679 			    {
    680 			    dl = *dstlong;,
    681 		/*s*/       *srclong & raster_bitmask[srcbit],
    682 		/*d*/       dl,
    683 		/*c*/       color,
    684 		/*pst*/     *dstlong = ( *dstlong & ~bytemask[dstbyte] ) |
    685 				       ( dl & bytemask[dstbyte] );
    686 			    if ( srcbit == 31 )
    687 				{
    688 				srcbit = 0;
    689 				++srclong;
    690 				}
    691 			    else
    692 				++srcbit;
    693 			    if ( dstbyte == 3 )
    694 				{
    695 				dstbyte = 0;
    696 				++dstlong;
    697 				}
    698 			    else
    699 				++dstbyte;
    700 			    --i;
    701 			    } )
    702 
    703 		srclin += src->linelongs;
    704 		dstlin += dst->linelongs;
    705 		}
    706 	    }
    707 	}
    708 
    709     else
    710 	{
    711 	/* Eight to eight blit. */
    712 	u_int32_t* srclin1;
    713 	u_int32_t* dstlin1;
    714 	int srcleftignore, srcrightignore, srclongs;
    715 	int dstleftignore, dstrightignore, dstlongs;
    716 
    717 	if ( dst->depth != 8 )
    718 	    return -1;		/* depth mismatch */
    719 
    720 	srclin1 = RAS_ADDR( src, sx, sy );
    721 	dstlin1 = RAS_ADDR( dst, dx, dy );
    722 
    723 #ifdef BCOPY_FASTER
    724 	/* Special-case full-width to full-width copies. */
    725 	if ( op == RAS_SRC && src->width == w && dst->width == w &&
    726 	     src->linelongs == dst->linelongs && src->linelongs == w >> 2 )
    727 	    {
    728 	    bcopy( (char*) srclin1, (char*) dstlin1,
    729 		   h * src->linelongs * sizeof(u_int32_t) );
    730 	    return 0;
    731 	    }
    732 #endif /*BCOPY_FASTER*/
    733 
    734 	srcleftignore = ( sx & 3 ) * 8;
    735 	srclongs = ( srcleftignore + w * 8 + 31 ) >> 5;
    736 	srcrightignore = ( srclongs * 32 - w * 8 - srcleftignore ) & 31;
    737 	dstleftignore = ( dx & 3 ) * 8;
    738 	dstlongs = ( dstleftignore + w * 8 + 31 ) >> 5;
    739 	dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31;
    740 
    741 	return raster_blit(
    742 	    src, srclin1, srcleftignore, srcrightignore, srclongs,
    743 	    dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
    744 	}
    745 
    746     return 0;
    747     }
    748 
    749 /* Semi-public routine to do a no-src bitblit without clipping.  Returns 0
    750 ** on success, -1 on failure.
    751 */
    752 int
    753 raster_op_nosrc_noclip( dst, dx, dy, w, h, rop )
    754     struct raster* dst;
    755     int dx, dy, w, h, rop;
    756     {
    757     int op;
    758 
    759     op = RAS_GETOP( rop );
    760 
    761     if ( dst->depth == 1 )
    762 	{
    763 	/* One-bit no-src blit. */
    764 	u_int32_t* dstlin1;
    765 	u_int32_t* dstlin2;
    766 	u_int32_t* dstlin;
    767 	int dstleftignore, dstrightignore, dstlongs;
    768 	u_int32_t dl, lm, nlm, rm, nrm;
    769 	register u_int32_t* dstlong2;
    770 	register u_int32_t* dstlong;
    771 
    772 	dstlin1 = RAS_ADDR( dst, dx, dy );
    773 
    774 #ifdef BCOPY_FASTER
    775 	/* Special-case full-width clears. */
    776 	if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 5 )
    777 	    {
    778 	    bzero( (char*) dstlin1, h * dst->linelongs * sizeof(u_int32_t) );
    779 	    return 0;
    780 	    }
    781 #endif /*BCOPY_FASTER*/
    782 
    783 	dstleftignore = ( dx & 31 );
    784 	dstlongs = ( dstleftignore + w + 31 ) >> 5;
    785 	dstrightignore = ( dstlongs * 32 - w - dstleftignore ) & 31;
    786 
    787 	dstlin2 = dstlin1 + h * dst->linelongs;
    788 	dstlin = dstlin1;
    789 
    790 	if ( dstlongs == 1 )
    791 	    {
    792 	    /* It fits into a single longword. */
    793 	    lm = leftmask[dstleftignore] | rightmask[dstrightignore];
    794 	    nlm = ~lm;
    795 	    while ( dstlin != dstlin2 )
    796 		{
    797 		ROP_DST(
    798 		/*op*/  op,
    799 		/*pre*/ dl = *dstlin;,
    800 		/*d*/   dl,
    801 		/*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
    802 
    803 		dstlin += dst->linelongs;
    804 		}
    805 	    }
    806 	else
    807 	    {
    808 	    lm = leftmask[dstleftignore];
    809 	    rm = rightmask[dstrightignore];
    810 	    nrm = ~rm;
    811 	    nlm = ~lm;
    812 
    813 	    while ( dstlin != dstlin2 )
    814 		{
    815 		dstlong = dstlin;
    816 		dstlong2 = dstlong + dstlongs;
    817 		if ( dstrightignore != 0 )
    818 		    --dstlong2;
    819 
    820 		/* Leading edge. */
    821 		if ( dstleftignore != 0 )
    822 		    {
    823 		    ROP_DST(
    824 		    /*op*/  op,
    825 		    /*pre*/ dl = *dstlong;,
    826 		    /*d*/   dl,
    827 		    /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
    828 		    ++dstlong;
    829 		    }
    830 
    831 		/* Main rop. */
    832 		ROP_DST(
    833 		/*op*/  op,
    834 		/*pre*/ while ( dstlong != dstlong2 )
    835 			    {,
    836 		/*d*/       *dstlong,
    837 		/*pst*/     ++dstlong;
    838 			    } )
    839 
    840 		/* Trailing edge. */
    841 		if ( dstrightignore != 0 )
    842 		    {
    843 		    ROP_DST(
    844 		    /*op*/  op,
    845 		    /*pre*/ dl = *dstlong;,
    846 		    /*d*/   dl,
    847 		    /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
    848 		    }
    849 
    850 		dstlin += dst->linelongs;
    851 		}
    852 	    }
    853 	}
    854 
    855     else
    856 	{
    857 	/* Eight-bit no-src blit. */
    858 	register u_int32_t color;
    859 	u_int32_t* dstlin1;
    860 	u_int32_t* dstlin2;
    861 	u_int32_t* dstlin;
    862 	int dstleftignore, dstrightignore, dstlongs;
    863 	u_int32_t dl, lm, nlm, rm, nrm;
    864 	register u_int32_t* dstlong2;
    865 	register u_int32_t* dstlong;
    866 
    867 	dstlin1 = RAS_ADDR( dst, dx, dy );
    868 
    869 #ifdef BCOPY_FASTER
    870 	/* Special-case full-width clears. */
    871 	if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 2 )
    872 	    {
    873 	    bzero( (char*) dstlin1, h * dst->linelongs * sizeof(u_int32_t) );
    874 	    return 0;
    875 	    }
    876 #endif /*BCOPY_FASTER*/
    877 
    878 	color = RAS_GETCOLOR( rop );
    879 	if ( color == 0 )
    880 	    color = 255;
    881 
    882 	/* Make 32 bits of color so we can do the ROP without shifting. */
    883 	color |= ( color << 24 ) | ( color << 16 ) | ( color << 8 );
    884 
    885 	dstleftignore = ( dx & 3 ) * 8;
    886 	dstlongs = ( dstleftignore + w * 8 + 31 ) >> 5;
    887 	dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31;
    888 
    889 	dstlin2 = dstlin1 + h * dst->linelongs;
    890 	dstlin = dstlin1;
    891 
    892 	if ( dstlongs == 1 )
    893 	    {
    894 	    /* It fits into a single longword. */
    895 	    lm = leftmask[dstleftignore] | rightmask[dstrightignore];
    896 	    nlm = ~lm;
    897 	    while ( dstlin != dstlin2 )
    898 		{
    899 		ROP_DSTCOLOR(
    900 		/*op*/  op,
    901 		/*pre*/ dl = *dstlin;,
    902 		/*d*/   dl,
    903 		/*c*/	color,
    904 		/*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
    905 
    906 		dstlin += dst->linelongs;
    907 		}
    908 	    }
    909 	else
    910 	    {
    911 	    lm = leftmask[dstleftignore];
    912 	    rm = rightmask[dstrightignore];
    913 	    nrm = ~rm;
    914 	    nlm = ~lm;
    915 	    while ( dstlin != dstlin2 )
    916 		{
    917 		dstlong = dstlin;
    918 		dstlong2 = dstlong + dstlongs;
    919 		if ( dstrightignore != 0 )
    920 		    --dstlong2;
    921 
    922 		/* Leading edge. */
    923 		if ( dstleftignore != 0 )
    924 		    {
    925 		    ROP_DSTCOLOR(
    926 		    /*op*/  op,
    927 		    /*pre*/ dl = *dstlong;,
    928 		    /*d*/   dl,
    929 		    /*c*/   color,
    930 		    /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
    931 		    ++dstlong;
    932 		    }
    933 
    934 		/* Main rop. */
    935 		ROP_DSTCOLOR(
    936 		/*op*/  op,
    937 		/*pre*/ while ( dstlong != dstlong2 )
    938 			    {,
    939 		/*d*/       *dstlong,
    940 		/*c*/       color,
    941 		/*pst*/     ++dstlong;
    942 			    } )
    943 
    944 		/* Trailing edge. */
    945 		if ( dstrightignore != 0 )
    946 		    {
    947 		    ROP_DSTCOLOR(
    948 		    /*op*/  op,
    949 		    /*pre*/ dl = *dstlong;,
    950 		    /*d*/   dl,
    951 		    /*c*/   color,
    952 		    /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
    953 		    }
    954 
    955 		dstlin += dst->linelongs;
    956 		}
    957 	    }
    958 	}
    959 
    960     return 0;
    961     }
    962 
    963 /* This is a general bitblit routine, handling overlapping source and
    964 ** destination.  It's used for both the 1-to-1 and 8-to-8 cases.
    965 */
    966 static int
    967 raster_blit( src, srclin1, srcleftignore, srcrightignore, srclongs, dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op )
    968     struct raster* src;
    969     u_int32_t* srclin1;
    970     int srcleftignore, srcrightignore, srclongs;
    971     struct raster* dst;
    972     u_int32_t* dstlin1;
    973     int dstleftignore, dstrightignore, dstlongs;
    974     int h, op;
    975     {
    976     u_int32_t* srclin2;
    977     u_int32_t* dstlin2;
    978     int srclininc, dstlininc;
    979     u_int32_t* srclin;
    980     u_int32_t* dstlin;
    981     register int prevleftshift, currrightshift;
    982     int longinc;
    983     register u_int32_t* srclong;
    984     register u_int32_t* dstlong;
    985     register u_int32_t* dstlong2;
    986     register u_int32_t dl, lm, nlm, rm, nrm;
    987 
    988     prevleftshift = ( srcleftignore - dstleftignore ) & 31;
    989 
    990     srclin2 = srclin1 + h * src->linelongs;
    991     dstlin2 = dstlin1 + h * dst->linelongs;
    992     srclininc = src->linelongs;
    993     dstlininc = dst->linelongs;
    994     longinc = 1;
    995 
    996     /* Check for overlaps. */
    997     if ( ( dstlin1 >= srclin1 && dstlin1 < srclin1 + srclongs ) ||
    998 	 ( srclin1 >= dstlin1 && srclin1 < dstlin1 + dstlongs ) )
    999 	{
   1000 	/* Horizontal overlap.  Should we reverse? */
   1001 	if ( srclin1 < dstlin1 )
   1002 	    {
   1003 	    longinc = -1;
   1004 	    srclin1 += srclongs - 1;
   1005 	    srclin2 += srclongs - 1;
   1006 	    dstlin1 += dstlongs - 1;
   1007 	    }
   1008 	}
   1009     else if ( ( dstlin1 >= srclin1 && dstlin1 < srclin2 ) ||
   1010 	      ( srclin1 >= dstlin1 && srclin1 < dstlin2 ) )
   1011 	{
   1012 	/* Vertical overlap.  Should we reverse? */
   1013 	if ( srclin1 < dstlin1 )
   1014 	    {
   1015 	    srclin2 = srclin1 - srclininc;
   1016 	    srclin1 += ( h - 1 ) * srclininc;
   1017 	    dstlin1 += ( h - 1 ) * dstlininc;
   1018 	    srclininc = -srclininc;
   1019 	    dstlininc = -dstlininc;
   1020 	    }
   1021 	}
   1022     srclin = srclin1;
   1023     dstlin = dstlin1;
   1024 
   1025     if ( prevleftshift == 0 )
   1026 	{
   1027 	/* The bits line up, no shifting necessary. */
   1028 	if ( dstlongs == 1 )
   1029 	    {
   1030 	    /* It all fits into a single longword. */
   1031 	    lm = leftmask[dstleftignore] | rightmask[dstrightignore];
   1032 	    nlm = ~lm;
   1033 	    while ( srclin != srclin2 )
   1034 		{
   1035 		ROP_SRCDST(
   1036 		/*op*/  op,
   1037 		/*pre*/ dl = *dstlin;,
   1038 		/*s*/   *srclin,
   1039 		/*d*/   dl,
   1040 		/*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
   1041 
   1042 		srclin += srclininc;
   1043 		dstlin += dstlininc;
   1044 		}
   1045 	    }
   1046 	else
   1047 	    {
   1048 	    /* Multiple longwords. */
   1049 	    lm = leftmask[dstleftignore];
   1050 	    rm = rightmask[dstrightignore];
   1051 	    nrm = ~rm;
   1052 	    nlm = ~lm;
   1053 	    if ( longinc == 1 )
   1054 		{
   1055 		/* Left to right. */
   1056 		while ( srclin != srclin2 )
   1057 		    {
   1058 		    srclong = srclin;
   1059 		    dstlong = dstlin;
   1060 		    dstlong2 = dstlong + dstlongs;
   1061 		    if ( dstrightignore != 0 )
   1062 			--dstlong2;
   1063 
   1064 		    /* Leading edge. */
   1065 		    if ( dstleftignore != 0 )
   1066 			{
   1067 			ROP_SRCDST(
   1068 			/*op*/  op,
   1069 			/*pre*/ dl = *dstlong;,
   1070 			/*s*/   *srclong,
   1071 			/*d*/   dl,
   1072 			/*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
   1073 			++srclong;
   1074 			++dstlong;
   1075 			}
   1076 
   1077 		    /* Main rop. */
   1078 		    ROP_SRCDST(
   1079 		    /*op*/  op,
   1080 		    /*pre*/ while ( dstlong != dstlong2 )
   1081 				{,
   1082 		    /*s*/       *srclong,
   1083 		    /*d*/       *dstlong,
   1084 		    /*pst*/     ++srclong;
   1085 				++dstlong;
   1086 				} )
   1087 
   1088 		    /* Trailing edge. */
   1089 		    if ( dstrightignore != 0 )
   1090 			{
   1091 			ROP_SRCDST(
   1092 			/*op*/  op,
   1093 			/*pre*/ dl = *dstlong;,
   1094 			/*s*/   *srclong,
   1095 			/*d*/   dl,
   1096 			/*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
   1097 			}
   1098 
   1099 		    srclin += srclininc;
   1100 		    dstlin += dstlininc;
   1101 		    }
   1102 		}
   1103 	    else
   1104 		{
   1105 		/* Right to left. */
   1106 		while ( srclin != srclin2 )
   1107 		    {
   1108 		    srclong = srclin;
   1109 		    dstlong = dstlin;
   1110 		    dstlong2 = dstlong - dstlongs;
   1111 		    if ( dstleftignore != 0 )
   1112 			++dstlong2;
   1113 
   1114 		    /* Leading edge. */
   1115 		    if ( dstrightignore != 0 )
   1116 			{
   1117 			ROP_SRCDST(
   1118 			/*op*/  op,
   1119 			/*pre*/ dl = *dstlong;,
   1120 			/*s*/   *srclong,
   1121 			/*d*/   dl,
   1122 			/*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
   1123 			--srclong;
   1124 			--dstlong;
   1125 			}
   1126 
   1127 		    /* Main rop. */
   1128 		    ROP_SRCDST(
   1129 		    /*op*/  op,
   1130 		    /*pre*/ while ( dstlong != dstlong2 )
   1131 				{,
   1132 		    /*s*/       *srclong,
   1133 		    /*d*/       *dstlong,
   1134 		    /*pst*/     --srclong;
   1135 				--dstlong;
   1136 				} )
   1137 
   1138 		    /* Trailing edge. */
   1139 		    if ( dstleftignore != 0 )
   1140 			{
   1141 			ROP_SRCDST(
   1142 			/*op*/  op,
   1143 			/*pre*/ dl = *dstlong;,
   1144 			/*s*/   *srclong,
   1145 			/*d*/   dl,
   1146 			/*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
   1147 			}
   1148 
   1149 		    srclin += srclininc;
   1150 		    dstlin += dstlininc;
   1151 		    }
   1152 		}
   1153 	    }
   1154 	}
   1155 
   1156     else
   1157 	{
   1158 	/* General case, with shifting and everything. */
   1159 	register u_int32_t sl, prevsl;
   1160 
   1161 	currrightshift = 32 - prevleftshift;
   1162 	if ( srclongs == 1 && dstlongs == 1 )
   1163 	    {
   1164 	    /* It fits into a single longword, with a shift. */
   1165 	    lm = leftmask[dstleftignore] | rightmask[dstrightignore];
   1166 	    nlm = ~lm;
   1167 	    if ( srcleftignore > dstleftignore )
   1168 		{
   1169 		while ( srclin != srclin2 )
   1170 		    {
   1171 		    ROP_SRCDST(
   1172 		    /*op*/  op,
   1173 		    /*pre*/ dl = *dstlin;,
   1174 		    /*s*/   *srclin << prevleftshift,
   1175 		    /*d*/   dl,
   1176 		    /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
   1177 
   1178 		    srclin += srclininc;
   1179 		    dstlin += dstlininc;
   1180 		    }
   1181 		}
   1182 	    else
   1183 		{
   1184 		while ( srclin != srclin2 )
   1185 		    {
   1186 		    ROP_SRCDST(
   1187 		    /*op*/  op,
   1188 		    /*pre*/ dl = *dstlin;,
   1189 		    /*s*/   *srclin >> currrightshift,
   1190 		    /*d*/   dl,
   1191 		    /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
   1192 
   1193 		    srclin += srclininc;
   1194 		    dstlin += dstlininc;
   1195 		    }
   1196 		}
   1197 	    }
   1198 	else
   1199 	    {
   1200 	    /* Multiple longwords. */
   1201 	    lm = leftmask[dstleftignore];
   1202 	    rm = rightmask[dstrightignore];
   1203 	    nrm = ~rm;
   1204 	    nlm = ~lm;
   1205 	    if ( longinc == 1 )
   1206 		{
   1207 		/* Left to right. */
   1208 		while ( srclin != srclin2 )
   1209 		    {
   1210 		    srclong = srclin;
   1211 		    dstlong = dstlin;
   1212 		    dstlong2 = dstlong + dstlongs;
   1213 		    if ( srcleftignore > dstleftignore )
   1214 			prevsl = *srclong++ << prevleftshift;
   1215 		    else
   1216 			prevsl = 0;
   1217 		    if ( dstrightignore != 0 )
   1218 			--dstlong2;
   1219 
   1220 		    /* Leading edge. */
   1221 		    if ( dstleftignore != 0 )
   1222 			{
   1223 			ROP_SRCDST(
   1224 			/*op*/  op,
   1225 			/*pre*/ sl = *srclong;
   1226 				dl = *dstlong;,
   1227 			/*s*/   prevsl | ( sl >> currrightshift ),
   1228 			/*d*/   dl,
   1229 			/*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
   1230 			prevsl = sl << prevleftshift;
   1231 			++srclong;
   1232 			++dstlong;
   1233 			}
   1234 
   1235 		    /* Main rop. */
   1236 		    ROP_SRCDST(
   1237 		    /*op*/  op,
   1238 		    /*pre*/ while ( dstlong != dstlong2 )
   1239 				{
   1240 				sl = *srclong;,
   1241 		    /*s*/       prevsl | ( sl >> currrightshift ),
   1242 		    /*d*/       *dstlong,
   1243 		    /*pst*/     prevsl = sl << prevleftshift;
   1244 				++srclong;
   1245 				++dstlong;
   1246 				} )
   1247 
   1248 		    /* Trailing edge. */
   1249 		    if ( dstrightignore != 0 )
   1250 			{
   1251 			ROP_SRCDST(
   1252 			/*op*/  op,
   1253 			/*pre*/ dl = *dstlong;,
   1254 			/*s*/   prevsl | ( *srclong >> currrightshift ),
   1255 			/*d*/   dl,
   1256 			/*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
   1257 			}
   1258 
   1259 		    srclin += srclininc;
   1260 		    dstlin += dstlininc;
   1261 		    }
   1262 		}
   1263 	    else
   1264 		{
   1265 		/* Right to left. */
   1266 		while ( srclin != srclin2 )
   1267 		    {
   1268 		    srclong = srclin;
   1269 		    dstlong = dstlin;
   1270 		    dstlong2 = dstlong - dstlongs;
   1271 		    if ( srcrightignore > dstrightignore )
   1272 			prevsl = *srclong-- >> currrightshift;
   1273 		    else
   1274 			prevsl = 0;
   1275 		    if ( dstleftignore != 0 )
   1276 			++dstlong2;
   1277 
   1278 		    /* Leading edge. */
   1279 		    if ( dstrightignore != 0 )
   1280 			{
   1281 			ROP_SRCDST(
   1282 			/*op*/  op,
   1283 			/*pre*/ sl = *srclong;
   1284 				dl = *dstlong;,
   1285 			/*s*/   prevsl | ( sl << prevleftshift ),
   1286 			/*d*/   dl,
   1287 			/*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
   1288 			prevsl = sl >> currrightshift;
   1289 			--srclong;
   1290 			--dstlong;
   1291 			}
   1292 
   1293 		    /* Main rop. */
   1294 		    ROP_SRCDST(
   1295 		    /*op*/  op,
   1296 		    /*pre*/ while ( dstlong != dstlong2 )
   1297 				{
   1298 				sl = *srclong;,
   1299 		    /*s*/       prevsl | ( sl << prevleftshift ),
   1300 		    /*d*/       *dstlong,
   1301 		    /*pst*/     prevsl = sl >> currrightshift;
   1302 				--srclong;
   1303 				--dstlong;
   1304 				} )
   1305 
   1306 		    /* Trailing edge. */
   1307 		    if ( dstleftignore != 0 )
   1308 			{
   1309 			ROP_SRCDST(
   1310 			/*op*/  op,
   1311 			/*pre*/ dl = *dstlong;,
   1312 			/*s*/   prevsl | ( *srclong << prevleftshift ),
   1313 			/*d*/   dl,
   1314 			/*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
   1315 			}
   1316 
   1317 		    srclin += srclininc;
   1318 		    dstlin += dstlininc;
   1319 		    }
   1320 		}
   1321 	    }
   1322 	}
   1323 
   1324     return 0;
   1325     }
   1326