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