Home | History | Annotate | Line # | Download | only in rcons
raster_op.c revision 1.18.16.1
      1  1.18.16.1       mrg /*	$NetBSD: raster_op.c,v 1.18.16.1 2012/02/18 07:34:57 mrg 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.12       agc  * 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.18.16.1       mrg __KERNEL_RCSID(0, "$NetBSD: raster_op.c,v 1.18.16.1 2012/02/18 07:34:57 mrg 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.13     perry static int raster_blit(struct raster *, u_int32_t *, int, int, int,
    551       1.13     perry 			struct raster *, u_int32_t *, int, int, int,
    552       1.13     perry 			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.18.16.1       mrg raster_op(struct raster* dst, int dx, int dy, int w, int h, int rop,
    559  1.18.16.1       mrg     struct raster* src, int sx, int sy)
    560        1.1        pk     {
    561        1.1        pk     if ( dst == (struct raster*) 0 )
    562        1.1        pk 	return -1;			/* no destination */
    563        1.1        pk 
    564        1.1        pk     if ( needsrc[RAS_GETOP( rop )] )
    565        1.1        pk 	{
    566        1.1        pk 	/* Two-operand blit. */
    567        1.1        pk 	if ( src == (struct raster*) 0 )
    568        1.1        pk 	    return -1;			/* no source */
    569        1.1        pk 
    570        1.1        pk 	/* Clip against source. */
    571        1.1        pk 	if ( sx < 0 )
    572        1.1        pk 	    {
    573        1.1        pk 	    w += sx;
    574        1.1        pk 	    sx = 0;
    575        1.1        pk 	    }
    576        1.1        pk 	if ( sy < 0 )
    577        1.1        pk 	    {
    578        1.1        pk 	    h += sy;
    579        1.1        pk 	    sy = 0;
    580        1.1        pk 	    }
    581        1.1        pk 	if ( sx + w > src->width )
    582        1.1        pk 	    w = src->width - sx;
    583        1.1        pk 	if ( sy + h > src->height )
    584        1.1        pk 	    h = src->height - sy;
    585        1.1        pk 
    586        1.1        pk 	/* Clip against dest. */
    587        1.1        pk 	if ( dx < 0 )
    588        1.1        pk 	    {
    589        1.1        pk 	    w += dx;
    590        1.1        pk 	    sx -= dx;
    591        1.1        pk 	    dx = 0;
    592        1.1        pk 	    }
    593        1.1        pk 	if ( dy < 0 )
    594        1.1        pk 	    {
    595        1.1        pk 	    h += dy;
    596        1.1        pk 	    sy -= dy;
    597        1.1        pk 	    dy = 0;
    598        1.1        pk 	    }
    599        1.1        pk 	if ( dx + w > dst->width )
    600        1.1        pk 	    w = dst->width - dx;
    601        1.1        pk 	if ( dy + h > dst->height )
    602        1.1        pk 	    h = dst->height - dy;
    603        1.1        pk 
    604        1.1        pk 	if ( w <= 0 || h <= 0 )
    605        1.1        pk 	    return 0;			/* nothing to do */
    606        1.1        pk 
    607        1.1        pk 	return raster_op_noclip( dst, dx, dy, w, h, rop, src, sx, sy );
    608        1.1        pk 	}
    609        1.1        pk 
    610        1.1        pk     /* No source necessary - one-operand blit. */
    611        1.1        pk     if ( src != (struct raster*) 0 )
    612        1.1        pk 	return -1;			/* unwanted source */
    613        1.1        pk 
    614        1.1        pk     /* Clip against dest. */
    615        1.1        pk     if ( dx < 0 )
    616        1.1        pk 	{
    617        1.1        pk 	w += dx;
    618        1.1        pk 	dx = 0;
    619        1.1        pk 	}
    620        1.1        pk     if ( dy < 0 )
    621        1.1        pk 	{
    622        1.1        pk 	h += dy;
    623        1.1        pk 	dy = 0;
    624        1.1        pk 	}
    625        1.1        pk     if ( dx + w > dst->width )
    626        1.1        pk 	w = dst->width - dx;
    627        1.1        pk     if ( dy + h > dst->height )
    628        1.1        pk 	h = dst->height - dy;
    629        1.1        pk 
    630        1.1        pk     if ( w <= 0 || h <= 0 )
    631        1.1        pk 	return 0;			/* nothing to do */
    632        1.1        pk 
    633        1.1        pk     return raster_op_nosrc_noclip( dst, dx, dy, w, h, rop );
    634        1.1        pk     }
    635        1.1        pk 
    636        1.1        pk /* Semi-public routine to do a bitblit without clipping.  Returns 0 on
    637        1.1        pk ** success, -1 on failure.
    638        1.1        pk */
    639        1.1        pk int
    640  1.18.16.1       mrg raster_op_noclip(struct raster* dst, int dx, int dy, int w, int h, int rop,
    641  1.18.16.1       mrg     struct raster* src, int sx, int sy)
    642        1.1        pk     {
    643        1.1        pk     int op;
    644        1.1        pk 
    645        1.1        pk     op = RAS_GETOP( rop );
    646        1.1        pk 
    647        1.1        pk     if ( src->depth == 1 )
    648        1.1        pk 	{
    649        1.1        pk 	/* One-bit to ? blit. */
    650        1.1        pk 	if ( dst->depth == 1 )
    651        1.1        pk 	    {
    652        1.1        pk 	    /* One to one blit. */
    653        1.2       cgd 	    u_int32_t* srclin1;
    654        1.2       cgd 	    u_int32_t* dstlin1;
    655        1.1        pk 	    int srcleftignore, srcrightignore, srclongs;
    656        1.1        pk 	    int dstleftignore, dstrightignore, dstlongs;
    657        1.1        pk 
    658        1.1        pk 	    srclin1 = RAS_ADDR( src, sx, sy );
    659        1.1        pk 	    dstlin1 = RAS_ADDR( dst, dx, dy );
    660        1.1        pk 
    661        1.1        pk #ifdef BCOPY_FASTER
    662        1.1        pk 	    /* Special-case full-width to full-width copies. */
    663        1.1        pk 	    if ( op == RAS_SRC && src->width == w && dst->width == w &&
    664        1.1        pk 		 src->linelongs == dst->linelongs && src->linelongs == w >> 5 )
    665        1.1        pk 		{
    666        1.1        pk 		bcopy(
    667        1.1        pk 		    (char*) srclin1, (char*) dstlin1,
    668        1.2       cgd 		    h * src->linelongs * sizeof(u_int32_t) );
    669        1.1        pk 		return 0;
    670        1.1        pk 		}
    671        1.1        pk #endif /*BCOPY_FASTER*/
    672        1.1        pk 
    673        1.1        pk 	    srcleftignore = ( sx & 31 );
    674        1.1        pk 	    srclongs = ( srcleftignore + w + 31 ) >> 5;
    675        1.1        pk 	    srcrightignore = ( srclongs * 32 - w - srcleftignore ) & 31;
    676        1.1        pk 	    dstleftignore = ( dx & 31 );
    677        1.1        pk 	    dstlongs = ( dstleftignore + w + 31 ) >> 5;
    678        1.1        pk 	    dstrightignore = ( dstlongs * 32 - w - dstleftignore ) & 31;
    679        1.1        pk 
    680        1.1        pk 	    return raster_blit(
    681        1.1        pk 		src, srclin1, srcleftignore, srcrightignore, srclongs,
    682        1.1        pk 		dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
    683        1.1        pk 	    }
    684        1.1        pk 
    685        1.6  drochner #ifdef RCONS_2BPP
    686        1.6  drochner 	else if ( dst->depth == 2 )
    687        1.6  drochner           {
    688        1.6  drochner             /* One to two, using the color in the rop.  */
    689        1.6  drochner 	    u_int32_t* srclin1;
    690        1.6  drochner 	    u_int32_t* dstlin1;
    691        1.6  drochner 	    u_int32_t* srclin2;
    692        1.6  drochner 	    u_int32_t* srclin;
    693        1.6  drochner 	    u_int32_t* dstlin;
    694        1.9  augustss 	    u_int32_t* srclong;
    695        1.9  augustss 	    u_int32_t* dstlong;
    696        1.9  augustss 	    u_int32_t color, dl;
    697        1.9  augustss 	    int srcbit, dstbyte, i;
    698        1.6  drochner 
    699        1.6  drochner 	    color = RAS_GETCOLOR( rop );
    700        1.6  drochner 	    if ( color == 0 )
    701        1.6  drochner               color = 3;
    702        1.6  drochner 
    703        1.6  drochner 	    /* Make 32 bits of color so we can do the ROP without shifting. */
    704        1.6  drochner 	    color |= (( color << 30 ) | ( color << 28 ) | ( color << 26 )
    705        1.6  drochner                       | ( color << 24 ) | ( color << 22 ) | ( color << 20 )
    706        1.6  drochner                       | ( color << 18 ) | ( color << 16 ) | ( color << 14 )
    707        1.6  drochner                       | ( color << 12 ) | ( color << 10 ) | ( color << 8 )
    708        1.6  drochner                       | ( color << 6 ) | ( color << 4 ) | ( color << 2 ));
    709        1.6  drochner 
    710        1.6  drochner 	    /* Don't have to worry about overlapping blits here. */
    711        1.6  drochner 	    srclin1 = RAS_ADDR( src, sx, sy );
    712        1.6  drochner 	    srclin2 = srclin1 + h * src->linelongs;
    713        1.6  drochner 	    dstlin1 = RAS_ADDR( dst, dx, dy );
    714        1.6  drochner 	    srclin = srclin1;
    715        1.6  drochner 	    dstlin = dstlin1;
    716       1.14     perry 
    717        1.6  drochner 	    while ( srclin != srclin2 )
    718        1.6  drochner 		{
    719        1.6  drochner 		srclong = srclin;
    720        1.6  drochner 		srcbit = sx & 31;
    721        1.6  drochner 		dstlong = dstlin;
    722        1.6  drochner 		dstbyte = dx & 15;
    723        1.6  drochner 		i = w;
    724        1.6  drochner 
    725        1.6  drochner 		/* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */
    726        1.6  drochner 		ROP_SRCDSTCOLOR(
    727        1.6  drochner 		/*op*/  op,
    728        1.6  drochner 		/*pre*/ while ( i > 0 )
    729        1.6  drochner 			    {
    730        1.6  drochner 			    dl = *dstlong;,
    731        1.6  drochner 		/*s*/       *srclong & raster_bitmask[srcbit],
    732        1.6  drochner 		/*d*/       dl,
    733        1.6  drochner 		/*c*/       color,
    734        1.6  drochner 		/*pst*/     *dstlong = ( *dstlong & ~twobitmask[dstbyte] ) |
    735        1.6  drochner 				       ( dl & twobitmask[dstbyte] );
    736        1.6  drochner 			    if ( srcbit == 31 )
    737        1.6  drochner 				{
    738        1.6  drochner 				srcbit = 0;
    739        1.6  drochner 				++srclong;
    740        1.6  drochner 				}
    741        1.6  drochner 			    else
    742        1.6  drochner 				++srcbit;
    743        1.6  drochner 			    if ( dstbyte == 15 )
    744        1.6  drochner 				{
    745        1.6  drochner 				dstbyte = 0;
    746        1.6  drochner 				++dstlong;
    747        1.6  drochner 				}
    748        1.6  drochner 			    else
    749        1.6  drochner 				++dstbyte;
    750        1.6  drochner 			    --i;
    751        1.6  drochner 			    } )
    752        1.6  drochner 
    753        1.6  drochner 		srclin += src->linelongs;
    754        1.6  drochner 		dstlin += dst->linelongs;
    755        1.6  drochner 		}
    756        1.6  drochner           }
    757        1.6  drochner #endif /* RCONS_2BPP */
    758        1.8    scottr #ifdef RCONS_4BPP
    759        1.8    scottr 	else if ( dst->depth == 4 )
    760        1.8    scottr           {
    761        1.8    scottr             /* One to four, using the color in the rop.  */
    762        1.8    scottr 	    u_int32_t* srclin1;
    763        1.8    scottr 	    u_int32_t* dstlin1;
    764        1.8    scottr 	    u_int32_t* srclin2;
    765        1.8    scottr 	    u_int32_t* srclin;
    766        1.8    scottr 	    u_int32_t* dstlin;
    767        1.9  augustss 	    u_int32_t* srclong;
    768        1.9  augustss 	    u_int32_t* dstlong;
    769        1.9  augustss 	    u_int32_t color, dl;
    770        1.9  augustss 	    int srcbit, dstbyte, i;
    771        1.8    scottr 
    772        1.8    scottr 	    color = RAS_GETCOLOR( rop );
    773        1.8    scottr 	    if ( color == 0 )
    774        1.8    scottr               color = 15;
    775        1.8    scottr 
    776        1.8    scottr 	    /* Make 32 bits of color so we can do the ROP without shifting. */
    777        1.8    scottr 	    color |= (( color << 28 ) | ( color << 24 )
    778        1.8    scottr                       | ( color << 20 ) | ( color << 16 )
    779        1.8    scottr                       | ( color << 12 ) | ( color << 8 )
    780        1.8    scottr                       | ( color << 4 ));
    781        1.8    scottr 
    782        1.8    scottr 	    /* Don't have to worry about overlapping blits here. */
    783        1.8    scottr 	    srclin1 = RAS_ADDR( src, sx, sy );
    784        1.8    scottr 	    srclin2 = srclin1 + h * src->linelongs;
    785        1.8    scottr 	    dstlin1 = RAS_ADDR( dst, dx, dy );
    786        1.8    scottr 	    srclin = srclin1;
    787        1.8    scottr 	    dstlin = dstlin1;
    788       1.14     perry 
    789        1.8    scottr 	    while ( srclin != srclin2 )
    790        1.8    scottr 		{
    791        1.8    scottr 		srclong = srclin;
    792        1.8    scottr 		srcbit = sx & 31;
    793        1.8    scottr 		dstlong = dstlin;
    794        1.8    scottr 		dstbyte = dx & 7;
    795        1.8    scottr 		i = w;
    796        1.8    scottr 
    797        1.8    scottr 		/* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */
    798        1.8    scottr 		ROP_SRCDSTCOLOR(
    799        1.8    scottr 		/*op*/  op,
    800        1.8    scottr 		/*pre*/ while ( i > 0 )
    801        1.8    scottr 			    {
    802        1.8    scottr 			    dl = *dstlong;,
    803        1.8    scottr 		/*s*/       *srclong & raster_bitmask[srcbit],
    804        1.8    scottr 		/*d*/       dl,
    805        1.8    scottr 		/*c*/       color,
    806        1.8    scottr 		/*pst*/     *dstlong = ( *dstlong & ~fourbitmask[dstbyte] ) |
    807        1.8    scottr 				       ( dl & fourbitmask[dstbyte] );
    808        1.8    scottr 			    if ( srcbit == 31 )
    809        1.8    scottr 				{
    810        1.8    scottr 				srcbit = 0;
    811        1.8    scottr 				++srclong;
    812        1.8    scottr 				}
    813        1.8    scottr 			    else
    814        1.8    scottr 				++srcbit;
    815        1.8    scottr 			    if ( dstbyte == 7 )
    816        1.8    scottr 				{
    817        1.8    scottr 				dstbyte = 0;
    818        1.8    scottr 				++dstlong;
    819        1.8    scottr 				}
    820        1.8    scottr 			    else
    821        1.8    scottr 				++dstbyte;
    822        1.8    scottr 			    --i;
    823        1.8    scottr 			    } )
    824        1.8    scottr 
    825        1.8    scottr 		srclin += src->linelongs;
    826        1.8    scottr 		dstlin += dst->linelongs;
    827        1.8    scottr 		}
    828        1.8    scottr           }
    829        1.8    scottr #endif /* RCONS_4BPP */
    830        1.7       dbj 	else if ( dst->depth == 8 )
    831        1.1        pk 	    {
    832        1.1        pk 	    /* One to eight, using the color in the rop.  This could
    833        1.1        pk 	    ** probably be sped up by handling each four-bit source nybble
    834        1.1        pk 	    ** as a group, indexing into a 16-element runtime-constructed
    835        1.1        pk 	    ** table of longwords.
    836        1.1        pk 	    */
    837        1.2       cgd 	    u_int32_t* srclin1;
    838        1.2       cgd 	    u_int32_t* dstlin1;
    839        1.2       cgd 	    u_int32_t* srclin2;
    840        1.2       cgd 	    u_int32_t* srclin;
    841        1.2       cgd 	    u_int32_t* dstlin;
    842        1.9  augustss 	    u_int32_t* srclong;
    843        1.9  augustss 	    u_int32_t* dstlong;
    844        1.9  augustss 	    u_int32_t color, dl;
    845        1.9  augustss 	    int srcbit, dstbyte, i;
    846        1.1        pk 
    847        1.1        pk 	    color = RAS_GETCOLOR( rop );
    848        1.1        pk 	    if ( color == 0 )
    849        1.1        pk 		color = 255;
    850        1.1        pk 
    851        1.1        pk 	    /* Make 32 bits of color so we can do the ROP without shifting. */
    852        1.1        pk 	    color |= ( color << 24 ) | ( color << 16 ) | ( color << 8 );
    853        1.1        pk 
    854        1.1        pk 	    /* Don't have to worry about overlapping blits here. */
    855        1.1        pk 	    srclin1 = RAS_ADDR( src, sx, sy );
    856        1.1        pk 	    srclin2 = srclin1 + h * src->linelongs;
    857        1.1        pk 	    dstlin1 = RAS_ADDR( dst, dx, dy );
    858        1.1        pk 	    srclin = srclin1;
    859        1.1        pk 	    dstlin = dstlin1;
    860        1.1        pk 	    while ( srclin != srclin2 )
    861        1.1        pk 		{
    862        1.1        pk 		srclong = srclin;
    863        1.1        pk 		srcbit = sx & 31;
    864        1.1        pk 		dstlong = dstlin;
    865        1.1        pk 		dstbyte = dx & 3;
    866        1.1        pk 		i = w;
    867        1.1        pk 
    868        1.1        pk 		/* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */
    869        1.1        pk 		ROP_SRCDSTCOLOR(
    870        1.1        pk 		/*op*/  op,
    871        1.1        pk 		/*pre*/ while ( i > 0 )
    872        1.1        pk 			    {
    873        1.1        pk 			    dl = *dstlong;,
    874        1.1        pk 		/*s*/       *srclong & raster_bitmask[srcbit],
    875        1.1        pk 		/*d*/       dl,
    876        1.1        pk 		/*c*/       color,
    877        1.1        pk 		/*pst*/     *dstlong = ( *dstlong & ~bytemask[dstbyte] ) |
    878        1.1        pk 				       ( dl & bytemask[dstbyte] );
    879        1.1        pk 			    if ( srcbit == 31 )
    880        1.1        pk 				{
    881        1.1        pk 				srcbit = 0;
    882        1.1        pk 				++srclong;
    883        1.1        pk 				}
    884        1.1        pk 			    else
    885        1.1        pk 				++srcbit;
    886        1.1        pk 			    if ( dstbyte == 3 )
    887        1.1        pk 				{
    888        1.1        pk 				dstbyte = 0;
    889        1.1        pk 				++dstlong;
    890        1.1        pk 				}
    891        1.1        pk 			    else
    892        1.1        pk 				++dstbyte;
    893        1.1        pk 			    --i;
    894        1.1        pk 			    } )
    895        1.1        pk 
    896        1.1        pk 		srclin += src->linelongs;
    897        1.1        pk 		dstlin += dst->linelongs;
    898        1.1        pk 		}
    899        1.1        pk 	    }
    900        1.7       dbj #ifdef RCONS_16BPP
    901        1.7       dbj 	else
    902        1.7       dbj 	    {
    903        1.7       dbj 	    /* One to sixteen, using the color in the rop.  This could
    904        1.7       dbj 	    ** probably be sped up by handling each four-bit source nybble
    905        1.7       dbj 	    ** as a group, indexing into a 16-element runtime-constructed
    906        1.7       dbj 	    ** table of longwords.
    907        1.7       dbj 	    */
    908        1.7       dbj 	    u_int32_t* srclin1;
    909        1.7       dbj 	    u_int32_t* dstlin1;
    910        1.7       dbj 	    u_int32_t* srclin2;
    911        1.7       dbj 	    u_int32_t* srclin;
    912        1.7       dbj 	    u_int32_t* dstlin;
    913        1.9  augustss 	    u_int32_t* srclong;
    914        1.9  augustss 	    u_int32_t* dstlong;
    915        1.9  augustss 	    u_int32_t color, dl;
    916        1.9  augustss 	    int srcbit, dstbyte, i;
    917        1.7       dbj 
    918        1.7       dbj 	    color = RAS_GETCOLOR( rop );
    919        1.7       dbj 	    if ( color == 0 )
    920       1.10    deberg 		color = 0xffff;
    921        1.7       dbj 
    922        1.7       dbj 	    /* Make 32 bits of color so we can do the ROP without shifting. */
    923        1.7       dbj 	    color |= ( color << 16 );
    924        1.7       dbj 
    925        1.7       dbj 	    /* Don't have to worry about overlapping blits here. */
    926        1.7       dbj 	    srclin1 = RAS_ADDR( src, sx, sy );
    927        1.7       dbj 	    srclin2 = srclin1 + h * src->linelongs;
    928        1.7       dbj 	    dstlin1 = RAS_ADDR( dst, dx, dy );
    929        1.7       dbj 	    srclin = srclin1;
    930        1.7       dbj 	    dstlin = dstlin1;
    931        1.7       dbj 	    while ( srclin != srclin2 )
    932        1.7       dbj 		{
    933        1.7       dbj 		srclong = srclin;
    934        1.7       dbj 		srcbit = sx & 31;
    935        1.7       dbj 		dstlong = dstlin;
    936        1.7       dbj 		dstbyte = dx & 1;
    937        1.7       dbj 		i = w;
    938        1.7       dbj 
    939        1.7       dbj 		/* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */
    940        1.7       dbj 		ROP_SRCDSTCOLOR(
    941        1.7       dbj 		/*op*/  op,
    942        1.7       dbj 		/*pre*/ while ( i > 0 )
    943        1.7       dbj 			    {
    944        1.7       dbj 			    dl = *dstlong;,
    945        1.7       dbj 		/*s*/       *srclong & raster_bitmask[srcbit],
    946        1.7       dbj 		/*d*/       dl,
    947        1.7       dbj 		/*c*/       color,
    948        1.7       dbj 		/*pst*/     *dstlong = ( *dstlong & ~twobytemask[dstbyte] ) |
    949        1.7       dbj 				       ( dl & twobytemask[dstbyte] );
    950        1.7       dbj 			    if ( srcbit == 31 )
    951        1.7       dbj 				{
    952        1.7       dbj 				srcbit = 0;
    953        1.7       dbj 				++srclong;
    954        1.7       dbj 				}
    955        1.7       dbj 			    else
    956        1.7       dbj 				++srcbit;
    957        1.7       dbj 			    if ( dstbyte == 1 )
    958        1.7       dbj 				{
    959        1.7       dbj 				dstbyte = 0;
    960        1.7       dbj 				++dstlong;
    961        1.7       dbj 				}
    962        1.7       dbj 			    else
    963        1.7       dbj 				++dstbyte;
    964        1.7       dbj 			    --i;
    965        1.7       dbj 			    } )
    966        1.7       dbj 
    967        1.7       dbj 		srclin += src->linelongs;
    968        1.7       dbj 		dstlin += dst->linelongs;
    969        1.7       dbj 		}
    970        1.7       dbj 	    }
    971        1.7       dbj #endif /* RCONS_16BPP */
    972        1.1        pk 	}
    973        1.6  drochner #ifdef RCONS_2BPP
    974       1.14     perry     else if ( src->depth == 2 )
    975        1.6  drochner       {
    976        1.6  drochner         /* Two to two blit. */
    977        1.6  drochner 	    u_int32_t* srclin1;
    978        1.6  drochner 	    u_int32_t* dstlin1;
    979        1.6  drochner 	    int srcleftignore, srcrightignore, srclongs;
    980        1.6  drochner 	    int dstleftignore, dstrightignore, dstlongs;
    981        1.6  drochner 
    982        1.6  drochner 	    srclin1 = RAS_ADDR( src, sx, sy );
    983        1.6  drochner 	    dstlin1 = RAS_ADDR( dst, dx, dy );
    984        1.6  drochner 
    985        1.6  drochner 	    srcleftignore = ( sx & 15 ) * 2;
    986        1.6  drochner 	    srclongs = ( srcleftignore + w * 2 + 31 ) >> 5;
    987        1.6  drochner 	    srcrightignore = ( srclongs * 32 - w * 2 - srcleftignore ) & 31;
    988        1.6  drochner 	    dstleftignore = ( dx & 15 ) * 2;
    989        1.6  drochner 	    dstlongs = ( dstleftignore + w * 2 + 31 ) >> 5;
    990        1.6  drochner 	    dstrightignore = ( dstlongs * 32 - w * 2 - dstleftignore ) & 31;
    991        1.6  drochner 
    992        1.6  drochner 	    return raster_blit(
    993        1.6  drochner 		src, srclin1, srcleftignore, srcrightignore, srclongs,
    994        1.6  drochner 		dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
    995        1.6  drochner 	    }
    996        1.6  drochner #endif /* RCONS_2BPP */
    997        1.8    scottr #ifdef RCONS_4BPP
    998       1.14     perry     else if ( src->depth == 4 )
    999        1.8    scottr       {
   1000        1.8    scottr         /* Four to four blit. */
   1001        1.8    scottr 	    u_int32_t* srclin1;
   1002        1.8    scottr 	    u_int32_t* dstlin1;
   1003        1.8    scottr 	    int srcleftignore, srcrightignore, srclongs;
   1004        1.8    scottr 	    int dstleftignore, dstrightignore, dstlongs;
   1005        1.8    scottr 
   1006        1.8    scottr 	    srclin1 = RAS_ADDR( src, sx, sy );
   1007        1.8    scottr 	    dstlin1 = RAS_ADDR( dst, dx, dy );
   1008        1.8    scottr 
   1009        1.8    scottr 	    srcleftignore = ( sx & 7 ) * 4;
   1010        1.8    scottr 	    srclongs = ( srcleftignore + w * 4 + 31 ) >> 5;
   1011        1.8    scottr 	    srcrightignore = ( srclongs * 32 - w * 4 - srcleftignore ) & 31;
   1012        1.8    scottr 	    dstleftignore = ( dx & 7 ) * 4;
   1013        1.8    scottr 	    dstlongs = ( dstleftignore + w * 4 + 31 ) >> 5;
   1014        1.8    scottr 	    dstrightignore = ( dstlongs * 32 - w * 4 - dstleftignore ) & 31;
   1015        1.8    scottr 
   1016        1.8    scottr 	    return raster_blit(
   1017        1.8    scottr 		src, srclin1, srcleftignore, srcrightignore, srclongs,
   1018        1.8    scottr 		dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
   1019        1.8    scottr 	    }
   1020        1.8    scottr #endif /* RCONS_4BPP */
   1021        1.1        pk 
   1022        1.7       dbj     else if ( src->depth == 8 )
   1023        1.1        pk 	{
   1024        1.1        pk 	/* Eight to eight blit. */
   1025        1.2       cgd 	u_int32_t* srclin1;
   1026        1.2       cgd 	u_int32_t* dstlin1;
   1027        1.1        pk 	int srcleftignore, srcrightignore, srclongs;
   1028        1.1        pk 	int dstleftignore, dstrightignore, dstlongs;
   1029        1.1        pk 
   1030        1.1        pk 	if ( dst->depth != 8 )
   1031        1.1        pk 	    return -1;		/* depth mismatch */
   1032        1.1        pk 
   1033        1.1        pk 	srclin1 = RAS_ADDR( src, sx, sy );
   1034        1.1        pk 	dstlin1 = RAS_ADDR( dst, dx, dy );
   1035        1.1        pk 
   1036        1.1        pk #ifdef BCOPY_FASTER
   1037        1.1        pk 	/* Special-case full-width to full-width copies. */
   1038        1.1        pk 	if ( op == RAS_SRC && src->width == w && dst->width == w &&
   1039        1.1        pk 	     src->linelongs == dst->linelongs && src->linelongs == w >> 2 )
   1040        1.1        pk 	    {
   1041       1.18   tsutsui 	    bcopy( (char*) srclin1, (char*) dstlin1,
   1042        1.2       cgd 		   h * src->linelongs * sizeof(u_int32_t) );
   1043        1.1        pk 	    return 0;
   1044        1.1        pk 	    }
   1045        1.1        pk #endif /*BCOPY_FASTER*/
   1046        1.1        pk 
   1047        1.1        pk 	srcleftignore = ( sx & 3 ) * 8;
   1048        1.1        pk 	srclongs = ( srcleftignore + w * 8 + 31 ) >> 5;
   1049        1.1        pk 	srcrightignore = ( srclongs * 32 - w * 8 - srcleftignore ) & 31;
   1050        1.1        pk 	dstleftignore = ( dx & 3 ) * 8;
   1051        1.1        pk 	dstlongs = ( dstleftignore + w * 8 + 31 ) >> 5;
   1052        1.1        pk 	dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31;
   1053        1.1        pk 
   1054        1.1        pk 	return raster_blit(
   1055        1.1        pk 	    src, srclin1, srcleftignore, srcrightignore, srclongs,
   1056        1.1        pk 	    dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
   1057        1.1        pk 	}
   1058        1.7       dbj #ifdef RCONS_16BPP
   1059        1.7       dbj     else
   1060        1.7       dbj         {
   1061        1.7       dbj 	/* Sixteen to sixteen blit. */
   1062        1.7       dbj 	    u_int32_t* srclin1;
   1063        1.7       dbj 	    u_int32_t* dstlin1;
   1064        1.7       dbj 	    int srcleftignore, srcrightignore, srclongs;
   1065        1.7       dbj 	    int dstleftignore, dstrightignore, dstlongs;
   1066        1.1        pk 
   1067        1.7       dbj 	    srclin1 = RAS_ADDR( src, sx, sy );
   1068        1.7       dbj 	    dstlin1 = RAS_ADDR( dst, dx, dy );
   1069        1.7       dbj 
   1070        1.7       dbj 	    srcleftignore = ( sx & 1 ) * 16;
   1071        1.7       dbj 	    srclongs = ( srcleftignore + w * 16 + 31 ) >> 5;
   1072        1.7       dbj 	    srcrightignore = ( srclongs * 32 - w * 16 - srcleftignore ) & 31;
   1073        1.7       dbj 	    dstleftignore = ( dx & 1 ) * 16;
   1074        1.7       dbj 	    dstlongs = ( dstleftignore + w * 16 + 31 ) >> 5;
   1075        1.7       dbj 	    dstrightignore = ( dstlongs * 32 - w * 16 - dstleftignore ) & 31;
   1076        1.7       dbj 
   1077        1.7       dbj 	    return raster_blit(
   1078        1.7       dbj 		src, srclin1, srcleftignore, srcrightignore, srclongs,
   1079        1.7       dbj 		dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
   1080        1.7       dbj 	}
   1081        1.7       dbj #endif /* RCONS_16BPP */
   1082        1.1        pk     return 0;
   1083        1.1        pk     }
   1084        1.1        pk 
   1085        1.1        pk /* Semi-public routine to do a no-src bitblit without clipping.  Returns 0
   1086        1.1        pk ** on success, -1 on failure.
   1087        1.1        pk */
   1088        1.1        pk int
   1089  1.18.16.1       mrg raster_op_nosrc_noclip(struct raster* dst,
   1090  1.18.16.1       mrg     int dx, int dy, int w, int h, int rop)
   1091        1.1        pk     {
   1092        1.1        pk     int op;
   1093        1.1        pk 
   1094        1.1        pk     op = RAS_GETOP( rop );
   1095        1.1        pk 
   1096        1.1        pk     if ( dst->depth == 1 )
   1097        1.1        pk 	{
   1098        1.1        pk 	/* One-bit no-src blit. */
   1099        1.2       cgd 	u_int32_t* dstlin1;
   1100        1.2       cgd 	u_int32_t* dstlin2;
   1101        1.2       cgd 	u_int32_t* dstlin;
   1102        1.1        pk 	int dstleftignore, dstrightignore, dstlongs;
   1103        1.2       cgd 	u_int32_t dl, lm, nlm, rm, nrm;
   1104        1.9  augustss 	u_int32_t* dstlong2;
   1105        1.9  augustss 	u_int32_t* dstlong;
   1106        1.1        pk 
   1107        1.1        pk 	dstlin1 = RAS_ADDR( dst, dx, dy );
   1108        1.1        pk 
   1109        1.1        pk #ifdef BCOPY_FASTER
   1110        1.1        pk 	/* Special-case full-width clears. */
   1111        1.1        pk 	if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 5 )
   1112        1.1        pk 	    {
   1113       1.16    cegger 	    memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) );
   1114        1.1        pk 	    return 0;
   1115        1.1        pk 	    }
   1116        1.1        pk #endif /*BCOPY_FASTER*/
   1117        1.1        pk 
   1118        1.1        pk 	dstleftignore = ( dx & 31 );
   1119        1.1        pk 	dstlongs = ( dstleftignore + w + 31 ) >> 5;
   1120        1.1        pk 	dstrightignore = ( dstlongs * 32 - w - dstleftignore ) & 31;
   1121        1.1        pk 
   1122        1.1        pk 	dstlin2 = dstlin1 + h * dst->linelongs;
   1123        1.1        pk 	dstlin = dstlin1;
   1124        1.1        pk 
   1125        1.1        pk 	if ( dstlongs == 1 )
   1126        1.1        pk 	    {
   1127        1.1        pk 	    /* It fits into a single longword. */
   1128        1.1        pk 	    lm = leftmask[dstleftignore] | rightmask[dstrightignore];
   1129        1.1        pk 	    nlm = ~lm;
   1130        1.1        pk 	    while ( dstlin != dstlin2 )
   1131        1.1        pk 		{
   1132        1.1        pk 		ROP_DST(
   1133        1.1        pk 		/*op*/  op,
   1134        1.1        pk 		/*pre*/ dl = *dstlin;,
   1135        1.1        pk 		/*d*/   dl,
   1136        1.1        pk 		/*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
   1137        1.1        pk 
   1138        1.1        pk 		dstlin += dst->linelongs;
   1139        1.1        pk 		}
   1140        1.1        pk 	    }
   1141        1.1        pk 	else
   1142        1.1        pk 	    {
   1143        1.1        pk 	    lm = leftmask[dstleftignore];
   1144        1.1        pk 	    rm = rightmask[dstrightignore];
   1145        1.1        pk 	    nrm = ~rm;
   1146        1.1        pk 	    nlm = ~lm;
   1147        1.1        pk 
   1148        1.1        pk 	    while ( dstlin != dstlin2 )
   1149        1.1        pk 		{
   1150        1.1        pk 		dstlong = dstlin;
   1151        1.1        pk 		dstlong2 = dstlong + dstlongs;
   1152        1.1        pk 		if ( dstrightignore != 0 )
   1153        1.1        pk 		    --dstlong2;
   1154        1.1        pk 
   1155        1.1        pk 		/* Leading edge. */
   1156        1.1        pk 		if ( dstleftignore != 0 )
   1157        1.1        pk 		    {
   1158        1.1        pk 		    ROP_DST(
   1159        1.1        pk 		    /*op*/  op,
   1160        1.1        pk 		    /*pre*/ dl = *dstlong;,
   1161        1.1        pk 		    /*d*/   dl,
   1162        1.1        pk 		    /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
   1163        1.1        pk 		    ++dstlong;
   1164        1.1        pk 		    }
   1165        1.1        pk 
   1166        1.1        pk 		/* Main rop. */
   1167        1.1        pk 		ROP_DST(
   1168        1.1        pk 		/*op*/  op,
   1169        1.1        pk 		/*pre*/ while ( dstlong != dstlong2 )
   1170        1.1        pk 			    {,
   1171        1.1        pk 		/*d*/       *dstlong,
   1172        1.1        pk 		/*pst*/     ++dstlong;
   1173        1.1        pk 			    } )
   1174        1.1        pk 
   1175        1.1        pk 		/* Trailing edge. */
   1176        1.1        pk 		if ( dstrightignore != 0 )
   1177        1.1        pk 		    {
   1178        1.1        pk 		    ROP_DST(
   1179        1.1        pk 		    /*op*/  op,
   1180        1.1        pk 		    /*pre*/ dl = *dstlong;,
   1181        1.1        pk 		    /*d*/   dl,
   1182        1.1        pk 		    /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
   1183        1.1        pk 		    }
   1184        1.1        pk 
   1185        1.1        pk 		dstlin += dst->linelongs;
   1186        1.1        pk 		}
   1187        1.1        pk 	    }
   1188        1.1        pk 	}
   1189        1.1        pk 
   1190        1.6  drochner #ifdef RCONS_2BPP
   1191       1.14     perry     else if ( dst->depth == 2 )
   1192        1.6  drochner 	{
   1193        1.6  drochner 	/* Two-bit no-src blit. */
   1194        1.9  augustss 	u_int32_t color;
   1195        1.6  drochner 	u_int32_t* dstlin1;
   1196        1.6  drochner 	u_int32_t* dstlin2;
   1197        1.6  drochner 	u_int32_t* dstlin;
   1198        1.6  drochner 	int dstleftignore, dstrightignore, dstlongs;
   1199        1.6  drochner 	u_int32_t dl, lm, nlm, rm, nrm;
   1200        1.9  augustss 	u_int32_t* dstlong2;
   1201        1.9  augustss 	u_int32_t* dstlong;
   1202        1.6  drochner 
   1203        1.6  drochner 	dstlin1 = RAS_ADDR( dst, dx, dy );
   1204        1.6  drochner 
   1205        1.6  drochner #ifdef BCOPY_FASTER
   1206        1.6  drochner 	/* Special-case full-width clears. */
   1207        1.7       dbj 	if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 4 )
   1208        1.6  drochner 	    {
   1209       1.16    cegger 	    memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) );
   1210        1.6  drochner 	    return 0;
   1211        1.6  drochner 	    }
   1212        1.6  drochner #endif /*BCOPY_FASTER*/
   1213        1.6  drochner 
   1214        1.6  drochner 	color = RAS_GETCOLOR( rop );
   1215        1.6  drochner 	if ( color == 0 )
   1216        1.6  drochner 	    color = 3;
   1217        1.6  drochner 
   1218        1.6  drochner         /* Make 32 bits of color so we can do the ROP without shifting. */
   1219        1.6  drochner         color |= (( color << 30 ) | ( color << 28 ) | ( color << 26 )
   1220        1.6  drochner                   | ( color << 24 ) | ( color << 22 ) | ( color << 20 )
   1221        1.6  drochner                   | ( color << 18 ) | ( color << 16 ) | ( color << 14 )
   1222        1.6  drochner                   | ( color << 12 ) | ( color << 10 ) | ( color << 8 )
   1223        1.6  drochner                   | ( color << 6 ) | ( color << 4 ) | ( color << 2 ));
   1224       1.14     perry 
   1225        1.6  drochner 	dstleftignore = ( dx & 15 ) * 2;
   1226        1.6  drochner 	dstlongs = ( dstleftignore + w * 2 + 31 ) >> 5;
   1227        1.6  drochner 	dstrightignore = ( dstlongs * 32 - w * 2 - dstleftignore ) & 31;
   1228        1.6  drochner 
   1229        1.6  drochner 	dstlin2 = dstlin1 + h * dst->linelongs;
   1230        1.6  drochner 	dstlin = dstlin1;
   1231        1.6  drochner 
   1232        1.6  drochner 	if ( dstlongs == 1 )
   1233        1.6  drochner 	    {
   1234        1.6  drochner 	    /* It fits into a single longword. */
   1235        1.6  drochner 	    lm = leftmask[dstleftignore] | rightmask[dstrightignore];
   1236        1.6  drochner 	    nlm = ~lm;
   1237        1.6  drochner 	    while ( dstlin != dstlin2 )
   1238        1.6  drochner 		{
   1239        1.6  drochner 		ROP_DST(
   1240        1.6  drochner 		/*op*/  op,
   1241        1.6  drochner 		/*pre*/ dl = *dstlin;,
   1242        1.6  drochner 		/*d*/   dl,
   1243        1.6  drochner 		/*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
   1244        1.6  drochner 
   1245        1.6  drochner 		dstlin += dst->linelongs;
   1246        1.6  drochner 		}
   1247        1.6  drochner 	    }
   1248        1.6  drochner 	else
   1249        1.6  drochner 	    {
   1250        1.6  drochner 	    lm = leftmask[dstleftignore];
   1251        1.6  drochner 	    rm = rightmask[dstrightignore];
   1252        1.6  drochner 	    nrm = ~rm;
   1253        1.6  drochner 	    nlm = ~lm;
   1254        1.6  drochner 
   1255        1.6  drochner 	    while ( dstlin != dstlin2 )
   1256        1.6  drochner 		{
   1257        1.6  drochner 		dstlong = dstlin;
   1258        1.6  drochner 		dstlong2 = dstlong + dstlongs;
   1259        1.6  drochner 		if ( dstrightignore != 0 )
   1260        1.6  drochner 		    --dstlong2;
   1261        1.6  drochner 
   1262        1.6  drochner 		/* Leading edge. */
   1263        1.6  drochner 		if ( dstleftignore != 0 )
   1264        1.6  drochner 		    {
   1265        1.6  drochner 		    ROP_DST(
   1266        1.6  drochner 		    /*op*/  op,
   1267        1.6  drochner 		    /*pre*/ dl = *dstlong;,
   1268        1.6  drochner 		    /*d*/   dl,
   1269        1.6  drochner 		    /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
   1270        1.6  drochner 		    ++dstlong;
   1271        1.6  drochner 		    }
   1272        1.6  drochner 
   1273        1.6  drochner 		/* Main rop. */
   1274        1.6  drochner 		ROP_DST(
   1275        1.6  drochner 		/*op*/  op,
   1276        1.6  drochner 		/*pre*/ while ( dstlong != dstlong2 )
   1277        1.6  drochner 			    {,
   1278        1.6  drochner 		/*d*/       *dstlong,
   1279        1.6  drochner 		/*pst*/     ++dstlong;
   1280        1.6  drochner 			    } )
   1281        1.6  drochner 
   1282        1.6  drochner 		/* Trailing edge. */
   1283        1.6  drochner 		if ( dstrightignore != 0 )
   1284        1.6  drochner 		    {
   1285        1.6  drochner 		    ROP_DST(
   1286        1.6  drochner 		    /*op*/  op,
   1287        1.6  drochner 		    /*pre*/ dl = *dstlong;,
   1288        1.6  drochner 		    /*d*/   dl,
   1289        1.6  drochner 		    /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
   1290        1.6  drochner 		    }
   1291        1.6  drochner 
   1292        1.6  drochner 		dstlin += dst->linelongs;
   1293        1.6  drochner 		}
   1294        1.6  drochner 	    }
   1295        1.6  drochner 	}
   1296        1.6  drochner #endif /* RCONS_2BPP */
   1297        1.8    scottr #ifdef RCONS_4BPP
   1298       1.14     perry     else if ( dst->depth == 4 )
   1299        1.8    scottr 	{
   1300        1.8    scottr 	/* Two-bit no-src blit. */
   1301        1.9  augustss 	u_int32_t color;
   1302        1.8    scottr 	u_int32_t* dstlin1;
   1303        1.8    scottr 	u_int32_t* dstlin2;
   1304        1.8    scottr 	u_int32_t* dstlin;
   1305        1.8    scottr 	int dstleftignore, dstrightignore, dstlongs;
   1306        1.8    scottr 	u_int32_t dl, lm, nlm, rm, nrm;
   1307        1.9  augustss 	u_int32_t* dstlong2;
   1308        1.9  augustss 	u_int32_t* dstlong;
   1309        1.8    scottr 
   1310        1.8    scottr 	dstlin1 = RAS_ADDR( dst, dx, dy );
   1311        1.8    scottr 
   1312        1.8    scottr #ifdef BCOPY_FASTER
   1313        1.8    scottr 	/* Special-case full-width clears. */
   1314        1.8    scottr 	if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 3 )
   1315        1.8    scottr 	    {
   1316       1.16    cegger 	    memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) );
   1317        1.8    scottr 	    return 0;
   1318        1.8    scottr 	    }
   1319        1.8    scottr #endif /*BCOPY_FASTER*/
   1320        1.8    scottr 
   1321        1.8    scottr 	color = RAS_GETCOLOR( rop );
   1322        1.8    scottr 	if ( color == 0 )
   1323        1.8    scottr 	    color = 15;
   1324        1.8    scottr 
   1325        1.8    scottr 	/* Make 32 bits of color so we can do the ROP without shifting. */
   1326        1.8    scottr 	color |= (( color << 28 ) | ( color << 24 )
   1327        1.8    scottr 		  | ( color << 20 ) | ( color << 16 )
   1328        1.8    scottr 		  | ( color << 12 ) | ( color << 8 )
   1329        1.8    scottr 		  | ( color << 4 ));
   1330       1.14     perry 
   1331        1.8    scottr 	dstleftignore = ( dx & 7 ) * 4;
   1332        1.8    scottr 	dstlongs = ( dstleftignore + w * 4 + 31 ) >> 5;
   1333        1.8    scottr 	dstrightignore = ( dstlongs * 32 - w * 4 - dstleftignore ) & 31;
   1334        1.8    scottr 
   1335        1.8    scottr 	dstlin2 = dstlin1 + h * dst->linelongs;
   1336        1.8    scottr 	dstlin = dstlin1;
   1337        1.8    scottr 
   1338        1.8    scottr 	if ( dstlongs == 1 )
   1339        1.8    scottr 	    {
   1340        1.8    scottr 	    /* It fits into a single longword. */
   1341        1.8    scottr 	    lm = leftmask[dstleftignore] | rightmask[dstrightignore];
   1342        1.8    scottr 	    nlm = ~lm;
   1343        1.8    scottr 	    while ( dstlin != dstlin2 )
   1344        1.8    scottr 		{
   1345        1.8    scottr 		ROP_DST(
   1346        1.8    scottr 		/*op*/  op,
   1347        1.8    scottr 		/*pre*/ dl = *dstlin;,
   1348        1.8    scottr 		/*d*/   dl,
   1349        1.8    scottr 		/*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
   1350        1.8    scottr 
   1351        1.8    scottr 		dstlin += dst->linelongs;
   1352        1.8    scottr 		}
   1353        1.8    scottr 	    }
   1354        1.8    scottr 	else
   1355        1.8    scottr 	    {
   1356        1.8    scottr 	    lm = leftmask[dstleftignore];
   1357        1.8    scottr 	    rm = rightmask[dstrightignore];
   1358        1.8    scottr 	    nrm = ~rm;
   1359        1.8    scottr 	    nlm = ~lm;
   1360        1.8    scottr 
   1361        1.8    scottr 	    while ( dstlin != dstlin2 )
   1362        1.8    scottr 		{
   1363        1.8    scottr 		dstlong = dstlin;
   1364        1.8    scottr 		dstlong2 = dstlong + dstlongs;
   1365        1.8    scottr 		if ( dstrightignore != 0 )
   1366        1.8    scottr 		    --dstlong2;
   1367        1.8    scottr 
   1368        1.8    scottr 		/* Leading edge. */
   1369        1.8    scottr 		if ( dstleftignore != 0 )
   1370        1.8    scottr 		    {
   1371        1.8    scottr 		    ROP_DST(
   1372        1.8    scottr 		    /*op*/  op,
   1373        1.8    scottr 		    /*pre*/ dl = *dstlong;,
   1374        1.8    scottr 		    /*d*/   dl,
   1375        1.8    scottr 		    /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
   1376        1.8    scottr 		    ++dstlong;
   1377        1.8    scottr 		    }
   1378        1.8    scottr 
   1379        1.8    scottr 		/* Main rop. */
   1380        1.8    scottr 		ROP_DST(
   1381        1.8    scottr 		/*op*/  op,
   1382        1.8    scottr 		/*pre*/ while ( dstlong != dstlong2 )
   1383        1.8    scottr 			    {,
   1384        1.8    scottr 		/*d*/       *dstlong,
   1385        1.8    scottr 		/*pst*/     ++dstlong;
   1386        1.8    scottr 			    } )
   1387        1.8    scottr 
   1388        1.8    scottr 		/* Trailing edge. */
   1389        1.8    scottr 		if ( dstrightignore != 0 )
   1390        1.8    scottr 		    {
   1391        1.8    scottr 		    ROP_DST(
   1392        1.8    scottr 		    /*op*/  op,
   1393        1.8    scottr 		    /*pre*/ dl = *dstlong;,
   1394        1.8    scottr 		    /*d*/   dl,
   1395        1.8    scottr 		    /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
   1396        1.8    scottr 		    }
   1397        1.8    scottr 
   1398        1.8    scottr 		dstlin += dst->linelongs;
   1399        1.8    scottr 		}
   1400        1.8    scottr 	    }
   1401        1.8    scottr 	}
   1402        1.8    scottr #endif /* RCONS_4BPP */
   1403        1.7       dbj     else if ( dst->depth == 8)
   1404        1.1        pk 	{
   1405        1.1        pk 	/* Eight-bit no-src blit. */
   1406        1.9  augustss 	u_int32_t color;
   1407        1.2       cgd 	u_int32_t* dstlin1;
   1408        1.2       cgd 	u_int32_t* dstlin2;
   1409        1.2       cgd 	u_int32_t* dstlin;
   1410        1.1        pk 	int dstleftignore, dstrightignore, dstlongs;
   1411        1.2       cgd 	u_int32_t dl, lm, nlm, rm, nrm;
   1412        1.9  augustss 	u_int32_t* dstlong2;
   1413        1.9  augustss 	u_int32_t* dstlong;
   1414        1.1        pk 
   1415        1.1        pk 	dstlin1 = RAS_ADDR( dst, dx, dy );
   1416        1.1        pk 
   1417        1.1        pk #ifdef BCOPY_FASTER
   1418        1.1        pk 	/* Special-case full-width clears. */
   1419        1.1        pk 	if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 2 )
   1420        1.1        pk 	    {
   1421       1.16    cegger 	    memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) );
   1422        1.1        pk 	    return 0;
   1423        1.1        pk 	    }
   1424        1.1        pk #endif /*BCOPY_FASTER*/
   1425        1.1        pk 
   1426        1.1        pk 	color = RAS_GETCOLOR( rop );
   1427        1.1        pk 	if ( color == 0 )
   1428        1.1        pk 	    color = 255;
   1429        1.1        pk 
   1430        1.1        pk 	/* Make 32 bits of color so we can do the ROP without shifting. */
   1431        1.1        pk 	color |= ( color << 24 ) | ( color << 16 ) | ( color << 8 );
   1432        1.1        pk 
   1433        1.1        pk 	dstleftignore = ( dx & 3 ) * 8;
   1434        1.1        pk 	dstlongs = ( dstleftignore + w * 8 + 31 ) >> 5;
   1435        1.1        pk 	dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31;
   1436        1.1        pk 
   1437        1.1        pk 	dstlin2 = dstlin1 + h * dst->linelongs;
   1438        1.1        pk 	dstlin = dstlin1;
   1439        1.1        pk 
   1440        1.1        pk 	if ( dstlongs == 1 )
   1441        1.1        pk 	    {
   1442        1.1        pk 	    /* It fits into a single longword. */
   1443        1.1        pk 	    lm = leftmask[dstleftignore] | rightmask[dstrightignore];
   1444        1.1        pk 	    nlm = ~lm;
   1445        1.1        pk 	    while ( dstlin != dstlin2 )
   1446        1.1        pk 		{
   1447        1.1        pk 		ROP_DSTCOLOR(
   1448        1.1        pk 		/*op*/  op,
   1449        1.1        pk 		/*pre*/ dl = *dstlin;,
   1450        1.1        pk 		/*d*/   dl,
   1451        1.1        pk 		/*c*/	color,
   1452        1.1        pk 		/*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
   1453        1.1        pk 
   1454        1.1        pk 		dstlin += dst->linelongs;
   1455        1.1        pk 		}
   1456        1.1        pk 	    }
   1457        1.1        pk 	else
   1458        1.1        pk 	    {
   1459        1.1        pk 	    lm = leftmask[dstleftignore];
   1460        1.1        pk 	    rm = rightmask[dstrightignore];
   1461        1.1        pk 	    nrm = ~rm;
   1462        1.1        pk 	    nlm = ~lm;
   1463        1.1        pk 	    while ( dstlin != dstlin2 )
   1464        1.1        pk 		{
   1465        1.1        pk 		dstlong = dstlin;
   1466        1.1        pk 		dstlong2 = dstlong + dstlongs;
   1467        1.1        pk 		if ( dstrightignore != 0 )
   1468        1.1        pk 		    --dstlong2;
   1469        1.1        pk 
   1470        1.1        pk 		/* Leading edge. */
   1471        1.1        pk 		if ( dstleftignore != 0 )
   1472        1.1        pk 		    {
   1473        1.1        pk 		    ROP_DSTCOLOR(
   1474        1.1        pk 		    /*op*/  op,
   1475        1.1        pk 		    /*pre*/ dl = *dstlong;,
   1476        1.1        pk 		    /*d*/   dl,
   1477        1.1        pk 		    /*c*/   color,
   1478        1.1        pk 		    /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
   1479        1.1        pk 		    ++dstlong;
   1480        1.1        pk 		    }
   1481        1.1        pk 
   1482        1.1        pk 		/* Main rop. */
   1483        1.1        pk 		ROP_DSTCOLOR(
   1484        1.1        pk 		/*op*/  op,
   1485        1.1        pk 		/*pre*/ while ( dstlong != dstlong2 )
   1486        1.1        pk 			    {,
   1487        1.1        pk 		/*d*/       *dstlong,
   1488        1.1        pk 		/*c*/       color,
   1489        1.1        pk 		/*pst*/     ++dstlong;
   1490        1.1        pk 			    } )
   1491        1.1        pk 
   1492        1.1        pk 		/* Trailing edge. */
   1493        1.1        pk 		if ( dstrightignore != 0 )
   1494        1.1        pk 		    {
   1495        1.1        pk 		    ROP_DSTCOLOR(
   1496        1.1        pk 		    /*op*/  op,
   1497        1.1        pk 		    /*pre*/ dl = *dstlong;,
   1498        1.1        pk 		    /*d*/   dl,
   1499        1.1        pk 		    /*c*/   color,
   1500        1.1        pk 		    /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
   1501        1.1        pk 		    }
   1502        1.1        pk 
   1503        1.1        pk 		dstlin += dst->linelongs;
   1504        1.1        pk 		}
   1505        1.1        pk 	    }
   1506        1.1        pk 	}
   1507        1.7       dbj #ifdef RCONS_16BPP
   1508       1.14     perry     else
   1509        1.7       dbj 	{
   1510        1.7       dbj 	/* Sixteen-bit no-src blit. */
   1511        1.9  augustss 	u_int32_t color;
   1512        1.7       dbj 	u_int32_t* dstlin1;
   1513        1.7       dbj 	u_int32_t* dstlin2;
   1514        1.7       dbj 	u_int32_t* dstlin;
   1515        1.7       dbj 	int dstleftignore, dstrightignore, dstlongs;
   1516        1.7       dbj 	u_int32_t dl, lm, nlm, rm, nrm;
   1517        1.9  augustss 	u_int32_t* dstlong2;
   1518        1.9  augustss 	u_int32_t* dstlong;
   1519        1.7       dbj 
   1520        1.7       dbj 	dstlin1 = RAS_ADDR( dst, dx, dy );
   1521        1.7       dbj 
   1522        1.7       dbj #ifdef BCOPY_FASTER
   1523        1.7       dbj 	/* Special-case full-width clears. */
   1524        1.7       dbj 	if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 1 )
   1525        1.7       dbj 	    {
   1526       1.16    cegger 	    memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) );
   1527        1.7       dbj 	    return 0;
   1528        1.7       dbj 	    }
   1529        1.7       dbj #endif /*BCOPY_FASTER*/
   1530        1.7       dbj 
   1531        1.7       dbj 	color = RAS_GETCOLOR( rop );
   1532        1.7       dbj 	if ( color == 0 )
   1533       1.10    deberg 		color = 0xffff; /* XXX */
   1534        1.7       dbj 
   1535        1.7       dbj 	/* Make 32 bits of color so we can do the ROP without shifting. */
   1536        1.7       dbj 	color |= ( color << 16 );
   1537        1.7       dbj 
   1538        1.7       dbj 	dstleftignore = ( dx & 1 ) * 16;
   1539        1.7       dbj 	dstlongs = ( dstleftignore + w * 16 + 31 ) >> 5;
   1540        1.7       dbj 	dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31;
   1541        1.7       dbj 
   1542        1.7       dbj 	dstlin2 = dstlin1 + h * dst->linelongs;
   1543        1.7       dbj 	dstlin = dstlin1;
   1544        1.7       dbj 
   1545        1.7       dbj 	if ( dstlongs == 1 )
   1546        1.7       dbj 	    {
   1547        1.7       dbj 	    /* It fits into a single longword. */
   1548        1.7       dbj 	    lm = leftmask[dstleftignore] | rightmask[dstrightignore];
   1549        1.7       dbj 	    nlm = ~lm;
   1550        1.7       dbj 	    while ( dstlin != dstlin2 )
   1551        1.7       dbj 		{
   1552        1.7       dbj 		ROP_DSTCOLOR(
   1553        1.7       dbj 		/*op*/  op,
   1554        1.7       dbj 		/*pre*/ dl = *dstlin;,
   1555        1.7       dbj 		/*d*/   dl,
   1556        1.7       dbj 		/*c*/	color,
   1557        1.7       dbj 		/*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
   1558        1.7       dbj 
   1559        1.7       dbj 		dstlin += dst->linelongs;
   1560        1.7       dbj 		}
   1561        1.7       dbj 	    }
   1562        1.7       dbj 	else
   1563        1.7       dbj 	    {
   1564        1.7       dbj 	    lm = leftmask[dstleftignore];
   1565        1.7       dbj 	    rm = rightmask[dstrightignore];
   1566        1.7       dbj 	    nrm = ~rm;
   1567        1.7       dbj 	    nlm = ~lm;
   1568        1.7       dbj 	    while ( dstlin != dstlin2 )
   1569        1.7       dbj 		{
   1570        1.7       dbj 		dstlong = dstlin;
   1571        1.7       dbj 		dstlong2 = dstlong + dstlongs;
   1572        1.7       dbj 		if ( dstrightignore != 0 )
   1573        1.7       dbj 		    --dstlong2;
   1574        1.7       dbj 
   1575        1.7       dbj 		/* Leading edge. */
   1576        1.7       dbj 		if ( dstleftignore != 0 )
   1577        1.7       dbj 		    {
   1578        1.7       dbj 		    ROP_DSTCOLOR(
   1579        1.7       dbj 		    /*op*/  op,
   1580        1.7       dbj 		    /*pre*/ dl = *dstlong;,
   1581        1.7       dbj 		    /*d*/   dl,
   1582        1.7       dbj 		    /*c*/   color,
   1583        1.7       dbj 		    /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
   1584        1.7       dbj 		    ++dstlong;
   1585        1.7       dbj 		    }
   1586        1.7       dbj 
   1587        1.7       dbj 		/* Main rop. */
   1588        1.7       dbj 		ROP_DSTCOLOR(
   1589        1.7       dbj 		/*op*/  op,
   1590        1.7       dbj 		/*pre*/ while ( dstlong != dstlong2 )
   1591        1.7       dbj 			    {,
   1592        1.7       dbj 		/*d*/       *dstlong,
   1593        1.7       dbj 		/*c*/       color,
   1594        1.7       dbj 		/*pst*/     ++dstlong;
   1595        1.7       dbj 			    } )
   1596        1.7       dbj 
   1597        1.7       dbj 		/* Trailing edge. */
   1598        1.7       dbj 		if ( dstrightignore != 0 )
   1599        1.7       dbj 		    {
   1600        1.7       dbj 		    ROP_DSTCOLOR(
   1601        1.7       dbj 		    /*op*/  op,
   1602        1.7       dbj 		    /*pre*/ dl = *dstlong;,
   1603        1.7       dbj 		    /*d*/   dl,
   1604        1.7       dbj 		    /*c*/   color,
   1605        1.7       dbj 		    /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
   1606        1.7       dbj 		    }
   1607        1.7       dbj 
   1608        1.7       dbj 		dstlin += dst->linelongs;
   1609        1.7       dbj 		}
   1610        1.7       dbj 	    }
   1611        1.7       dbj 	}
   1612        1.7       dbj #endif /* RCONS_16BPP */
   1613        1.1        pk 
   1614        1.1        pk     return 0;
   1615        1.1        pk     }
   1616        1.1        pk 
   1617        1.1        pk /* This is a general bitblit routine, handling overlapping source and
   1618        1.1        pk ** destination.  It's used for both the 1-to-1 and 8-to-8 cases.
   1619        1.1        pk */
   1620        1.1        pk static int
   1621  1.18.16.1       mrg raster_blit(
   1622  1.18.16.1       mrg     struct raster* src, uint32_t* srclin1,
   1623  1.18.16.1       mrg     int srcleftignore, int srcrightignore, int srclongs,
   1624  1.18.16.1       mrg     struct raster* dst,
   1625  1.18.16.1       mrg     uint32_t* dstlin1,
   1626  1.18.16.1       mrg     int dstleftignore, int dstrightignore, int dstlongs,
   1627  1.18.16.1       mrg     int h, int op)
   1628        1.1        pk     {
   1629        1.2       cgd     u_int32_t* srclin2;
   1630        1.2       cgd     u_int32_t* dstlin2;
   1631        1.1        pk     int srclininc, dstlininc;
   1632        1.2       cgd     u_int32_t* srclin;
   1633        1.2       cgd     u_int32_t* dstlin;
   1634        1.9  augustss     int prevleftshift, currrightshift;
   1635        1.1        pk     int longinc;
   1636        1.9  augustss     u_int32_t* srclong;
   1637        1.9  augustss     u_int32_t* dstlong;
   1638        1.9  augustss     u_int32_t* dstlong2;
   1639        1.9  augustss     u_int32_t dl, lm, nlm, rm, nrm;
   1640        1.1        pk 
   1641        1.1        pk     prevleftshift = ( srcleftignore - dstleftignore ) & 31;
   1642        1.1        pk 
   1643        1.1        pk     srclin2 = srclin1 + h * src->linelongs;
   1644        1.1        pk     dstlin2 = dstlin1 + h * dst->linelongs;
   1645        1.1        pk     srclininc = src->linelongs;
   1646        1.1        pk     dstlininc = dst->linelongs;
   1647        1.1        pk     longinc = 1;
   1648        1.1        pk 
   1649        1.1        pk     /* Check for overlaps. */
   1650        1.1        pk     if ( ( dstlin1 >= srclin1 && dstlin1 < srclin1 + srclongs ) ||
   1651        1.1        pk 	 ( srclin1 >= dstlin1 && srclin1 < dstlin1 + dstlongs ) )
   1652        1.1        pk 	{
   1653        1.1        pk 	/* Horizontal overlap.  Should we reverse? */
   1654        1.1        pk 	if ( srclin1 < dstlin1 )
   1655        1.1        pk 	    {
   1656        1.1        pk 	    longinc = -1;
   1657        1.1        pk 	    srclin1 += srclongs - 1;
   1658        1.1        pk 	    srclin2 += srclongs - 1;
   1659        1.1        pk 	    dstlin1 += dstlongs - 1;
   1660        1.1        pk 	    }
   1661        1.1        pk 	}
   1662        1.1        pk     else if ( ( dstlin1 >= srclin1 && dstlin1 < srclin2 ) ||
   1663        1.1        pk 	      ( srclin1 >= dstlin1 && srclin1 < dstlin2 ) )
   1664        1.1        pk 	{
   1665        1.1        pk 	/* Vertical overlap.  Should we reverse? */
   1666        1.1        pk 	if ( srclin1 < dstlin1 )
   1667        1.1        pk 	    {
   1668        1.1        pk 	    srclin2 = srclin1 - srclininc;
   1669        1.1        pk 	    srclin1 += ( h - 1 ) * srclininc;
   1670        1.1        pk 	    dstlin1 += ( h - 1 ) * dstlininc;
   1671        1.1        pk 	    srclininc = -srclininc;
   1672        1.1        pk 	    dstlininc = -dstlininc;
   1673        1.1        pk 	    }
   1674        1.1        pk 	}
   1675        1.1        pk     srclin = srclin1;
   1676        1.1        pk     dstlin = dstlin1;
   1677        1.1        pk 
   1678        1.1        pk     if ( prevleftshift == 0 )
   1679        1.1        pk 	{
   1680        1.1        pk 	/* The bits line up, no shifting necessary. */
   1681        1.1        pk 	if ( dstlongs == 1 )
   1682        1.1        pk 	    {
   1683        1.1        pk 	    /* It all fits into a single longword. */
   1684        1.1        pk 	    lm = leftmask[dstleftignore] | rightmask[dstrightignore];
   1685        1.1        pk 	    nlm = ~lm;
   1686        1.1        pk 	    while ( srclin != srclin2 )
   1687        1.1        pk 		{
   1688        1.1        pk 		ROP_SRCDST(
   1689        1.1        pk 		/*op*/  op,
   1690        1.1        pk 		/*pre*/ dl = *dstlin;,
   1691        1.1        pk 		/*s*/   *srclin,
   1692        1.1        pk 		/*d*/   dl,
   1693        1.1        pk 		/*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
   1694        1.1        pk 
   1695        1.1        pk 		srclin += srclininc;
   1696        1.1        pk 		dstlin += dstlininc;
   1697        1.1        pk 		}
   1698        1.1        pk 	    }
   1699        1.1        pk 	else
   1700        1.1        pk 	    {
   1701        1.1        pk 	    /* Multiple longwords. */
   1702        1.1        pk 	    lm = leftmask[dstleftignore];
   1703        1.1        pk 	    rm = rightmask[dstrightignore];
   1704        1.1        pk 	    nrm = ~rm;
   1705        1.1        pk 	    nlm = ~lm;
   1706        1.1        pk 	    if ( longinc == 1 )
   1707        1.1        pk 		{
   1708        1.1        pk 		/* Left to right. */
   1709        1.1        pk 		while ( srclin != srclin2 )
   1710        1.1        pk 		    {
   1711        1.1        pk 		    srclong = srclin;
   1712        1.1        pk 		    dstlong = dstlin;
   1713        1.1        pk 		    dstlong2 = dstlong + dstlongs;
   1714        1.1        pk 		    if ( dstrightignore != 0 )
   1715        1.1        pk 			--dstlong2;
   1716        1.1        pk 
   1717        1.1        pk 		    /* Leading edge. */
   1718        1.1        pk 		    if ( dstleftignore != 0 )
   1719        1.1        pk 			{
   1720        1.1        pk 			ROP_SRCDST(
   1721        1.1        pk 			/*op*/  op,
   1722        1.1        pk 			/*pre*/ dl = *dstlong;,
   1723        1.1        pk 			/*s*/   *srclong,
   1724        1.1        pk 			/*d*/   dl,
   1725        1.1        pk 			/*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
   1726        1.1        pk 			++srclong;
   1727        1.1        pk 			++dstlong;
   1728        1.1        pk 			}
   1729        1.1        pk 
   1730        1.1        pk 		    /* Main rop. */
   1731        1.1        pk 		    ROP_SRCDST(
   1732        1.1        pk 		    /*op*/  op,
   1733        1.1        pk 		    /*pre*/ while ( dstlong != dstlong2 )
   1734        1.1        pk 				{,
   1735        1.1        pk 		    /*s*/       *srclong,
   1736        1.1        pk 		    /*d*/       *dstlong,
   1737        1.1        pk 		    /*pst*/     ++srclong;
   1738        1.1        pk 				++dstlong;
   1739        1.1        pk 				} )
   1740        1.1        pk 
   1741        1.1        pk 		    /* Trailing edge. */
   1742        1.1        pk 		    if ( dstrightignore != 0 )
   1743        1.1        pk 			{
   1744        1.1        pk 			ROP_SRCDST(
   1745        1.1        pk 			/*op*/  op,
   1746        1.1        pk 			/*pre*/ dl = *dstlong;,
   1747        1.1        pk 			/*s*/   *srclong,
   1748        1.1        pk 			/*d*/   dl,
   1749        1.1        pk 			/*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
   1750        1.1        pk 			}
   1751        1.1        pk 
   1752        1.1        pk 		    srclin += srclininc;
   1753        1.1        pk 		    dstlin += dstlininc;
   1754        1.1        pk 		    }
   1755        1.1        pk 		}
   1756        1.1        pk 	    else
   1757        1.1        pk 		{
   1758        1.1        pk 		/* Right to left. */
   1759        1.1        pk 		while ( srclin != srclin2 )
   1760        1.1        pk 		    {
   1761        1.1        pk 		    srclong = srclin;
   1762        1.1        pk 		    dstlong = dstlin;
   1763        1.1        pk 		    dstlong2 = dstlong - dstlongs;
   1764        1.1        pk 		    if ( dstleftignore != 0 )
   1765        1.1        pk 			++dstlong2;
   1766        1.1        pk 
   1767        1.1        pk 		    /* Leading edge. */
   1768        1.1        pk 		    if ( dstrightignore != 0 )
   1769        1.1        pk 			{
   1770        1.1        pk 			ROP_SRCDST(
   1771        1.1        pk 			/*op*/  op,
   1772        1.1        pk 			/*pre*/ dl = *dstlong;,
   1773        1.1        pk 			/*s*/   *srclong,
   1774        1.1        pk 			/*d*/   dl,
   1775        1.1        pk 			/*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
   1776        1.1        pk 			--srclong;
   1777        1.1        pk 			--dstlong;
   1778        1.1        pk 			}
   1779        1.1        pk 
   1780        1.1        pk 		    /* Main rop. */
   1781        1.1        pk 		    ROP_SRCDST(
   1782        1.1        pk 		    /*op*/  op,
   1783        1.1        pk 		    /*pre*/ while ( dstlong != dstlong2 )
   1784        1.1        pk 				{,
   1785        1.1        pk 		    /*s*/       *srclong,
   1786        1.1        pk 		    /*d*/       *dstlong,
   1787        1.1        pk 		    /*pst*/     --srclong;
   1788        1.1        pk 				--dstlong;
   1789        1.1        pk 				} )
   1790        1.1        pk 
   1791        1.1        pk 		    /* Trailing edge. */
   1792        1.1        pk 		    if ( dstleftignore != 0 )
   1793        1.1        pk 			{
   1794        1.1        pk 			ROP_SRCDST(
   1795        1.1        pk 			/*op*/  op,
   1796        1.1        pk 			/*pre*/ dl = *dstlong;,
   1797        1.1        pk 			/*s*/   *srclong,
   1798        1.1        pk 			/*d*/   dl,
   1799        1.1        pk 			/*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
   1800        1.1        pk 			}
   1801        1.1        pk 
   1802        1.1        pk 		    srclin += srclininc;
   1803        1.1        pk 		    dstlin += dstlininc;
   1804        1.1        pk 		    }
   1805        1.1        pk 		}
   1806        1.1        pk 	    }
   1807        1.1        pk 	}
   1808        1.1        pk 
   1809        1.1        pk     else
   1810        1.1        pk 	{
   1811        1.1        pk 	/* General case, with shifting and everything. */
   1812        1.9  augustss 	u_int32_t sl, prevsl;
   1813        1.1        pk 
   1814        1.1        pk 	currrightshift = 32 - prevleftshift;
   1815        1.1        pk 	if ( srclongs == 1 && dstlongs == 1 )
   1816        1.1        pk 	    {
   1817        1.1        pk 	    /* It fits into a single longword, with a shift. */
   1818        1.1        pk 	    lm = leftmask[dstleftignore] | rightmask[dstrightignore];
   1819        1.1        pk 	    nlm = ~lm;
   1820        1.1        pk 	    if ( srcleftignore > dstleftignore )
   1821        1.1        pk 		{
   1822        1.1        pk 		while ( srclin != srclin2 )
   1823        1.1        pk 		    {
   1824        1.1        pk 		    ROP_SRCDST(
   1825        1.1        pk 		    /*op*/  op,
   1826        1.1        pk 		    /*pre*/ dl = *dstlin;,
   1827        1.3        pk 		    /*s*/   *srclin LSOP prevleftshift,
   1828        1.1        pk 		    /*d*/   dl,
   1829        1.1        pk 		    /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
   1830        1.1        pk 
   1831        1.1        pk 		    srclin += srclininc;
   1832        1.1        pk 		    dstlin += dstlininc;
   1833        1.1        pk 		    }
   1834        1.1        pk 		}
   1835        1.1        pk 	    else
   1836        1.1        pk 		{
   1837        1.1        pk 		while ( srclin != srclin2 )
   1838        1.1        pk 		    {
   1839        1.1        pk 		    ROP_SRCDST(
   1840        1.1        pk 		    /*op*/  op,
   1841        1.1        pk 		    /*pre*/ dl = *dstlin;,
   1842        1.3        pk 		    /*s*/   *srclin RSOP currrightshift,
   1843        1.1        pk 		    /*d*/   dl,
   1844        1.1        pk 		    /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
   1845        1.1        pk 
   1846        1.1        pk 		    srclin += srclininc;
   1847        1.1        pk 		    dstlin += dstlininc;
   1848        1.1        pk 		    }
   1849        1.1        pk 		}
   1850        1.1        pk 	    }
   1851        1.1        pk 	else
   1852        1.1        pk 	    {
   1853        1.1        pk 	    /* Multiple longwords. */
   1854        1.1        pk 	    lm = leftmask[dstleftignore];
   1855        1.1        pk 	    rm = rightmask[dstrightignore];
   1856        1.1        pk 	    nrm = ~rm;
   1857        1.1        pk 	    nlm = ~lm;
   1858        1.1        pk 	    if ( longinc == 1 )
   1859        1.1        pk 		{
   1860        1.1        pk 		/* Left to right. */
   1861        1.1        pk 		while ( srclin != srclin2 )
   1862        1.1        pk 		    {
   1863        1.1        pk 		    srclong = srclin;
   1864        1.1        pk 		    dstlong = dstlin;
   1865        1.1        pk 		    dstlong2 = dstlong + dstlongs;
   1866        1.1        pk 		    if ( srcleftignore > dstleftignore )
   1867        1.3        pk 			prevsl = *srclong++ LSOP prevleftshift;
   1868        1.1        pk 		    else
   1869        1.1        pk 			prevsl = 0;
   1870        1.1        pk 		    if ( dstrightignore != 0 )
   1871        1.1        pk 			--dstlong2;
   1872        1.1        pk 
   1873        1.1        pk 		    /* Leading edge. */
   1874        1.1        pk 		    if ( dstleftignore != 0 )
   1875        1.1        pk 			{
   1876        1.1        pk 			ROP_SRCDST(
   1877        1.1        pk 			/*op*/  op,
   1878        1.1        pk 			/*pre*/ sl = *srclong;
   1879        1.1        pk 				dl = *dstlong;,
   1880        1.3        pk 			/*s*/   prevsl | ( sl RSOP currrightshift ),
   1881        1.1        pk 			/*d*/   dl,
   1882        1.1        pk 			/*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
   1883        1.5   thorpej 			prevsl = sl LSOP prevleftshift;
   1884        1.1        pk 			++srclong;
   1885        1.1        pk 			++dstlong;
   1886        1.1        pk 			}
   1887        1.1        pk 
   1888        1.1        pk 		    /* Main rop. */
   1889        1.1        pk 		    ROP_SRCDST(
   1890        1.1        pk 		    /*op*/  op,
   1891        1.1        pk 		    /*pre*/ while ( dstlong != dstlong2 )
   1892        1.1        pk 				{
   1893        1.1        pk 				sl = *srclong;,
   1894        1.3        pk 		    /*s*/       prevsl | ( sl RSOP currrightshift ),
   1895        1.1        pk 		    /*d*/       *dstlong,
   1896        1.3        pk 		    /*pst*/     prevsl = sl LSOP prevleftshift;
   1897        1.1        pk 				++srclong;
   1898        1.1        pk 				++dstlong;
   1899        1.1        pk 				} )
   1900        1.1        pk 
   1901        1.1        pk 		    /* Trailing edge. */
   1902        1.1        pk 		    if ( dstrightignore != 0 )
   1903        1.1        pk 			{
   1904        1.1        pk 			ROP_SRCDST(
   1905        1.1        pk 			/*op*/  op,
   1906        1.1        pk 			/*pre*/ dl = *dstlong;,
   1907        1.3        pk 			/*s*/   prevsl | ( *srclong RSOP currrightshift ),
   1908        1.1        pk 			/*d*/   dl,
   1909        1.1        pk 			/*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
   1910        1.1        pk 			}
   1911        1.1        pk 
   1912        1.1        pk 		    srclin += srclininc;
   1913        1.1        pk 		    dstlin += dstlininc;
   1914        1.1        pk 		    }
   1915        1.1        pk 		}
   1916        1.1        pk 	    else
   1917        1.1        pk 		{
   1918        1.1        pk 		/* Right to left. */
   1919        1.1        pk 		while ( srclin != srclin2 )
   1920        1.1        pk 		    {
   1921        1.1        pk 		    srclong = srclin;
   1922        1.1        pk 		    dstlong = dstlin;
   1923        1.1        pk 		    dstlong2 = dstlong - dstlongs;
   1924        1.1        pk 		    if ( srcrightignore > dstrightignore )
   1925        1.3        pk 			prevsl = *srclong-- RSOP currrightshift;
   1926        1.1        pk 		    else
   1927        1.1        pk 			prevsl = 0;
   1928        1.1        pk 		    if ( dstleftignore != 0 )
   1929        1.1        pk 			++dstlong2;
   1930        1.1        pk 
   1931        1.1        pk 		    /* Leading edge. */
   1932        1.1        pk 		    if ( dstrightignore != 0 )
   1933        1.1        pk 			{
   1934        1.1        pk 			ROP_SRCDST(
   1935        1.1        pk 			/*op*/  op,
   1936        1.1        pk 			/*pre*/ sl = *srclong;
   1937        1.1        pk 				dl = *dstlong;,
   1938        1.3        pk 			/*s*/   prevsl | ( sl LSOP prevleftshift ),
   1939        1.1        pk 			/*d*/   dl,
   1940        1.1        pk 			/*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
   1941        1.3        pk 			prevsl = sl RSOP currrightshift;
   1942        1.1        pk 			--srclong;
   1943        1.1        pk 			--dstlong;
   1944        1.1        pk 			}
   1945        1.1        pk 
   1946        1.1        pk 		    /* Main rop. */
   1947        1.1        pk 		    ROP_SRCDST(
   1948        1.1        pk 		    /*op*/  op,
   1949        1.1        pk 		    /*pre*/ while ( dstlong != dstlong2 )
   1950        1.1        pk 				{
   1951        1.1        pk 				sl = *srclong;,
   1952        1.3        pk 		    /*s*/       prevsl | ( sl LSOP prevleftshift ),
   1953        1.1        pk 		    /*d*/       *dstlong,
   1954        1.3        pk 		    /*pst*/     prevsl = sl RSOP currrightshift;
   1955        1.1        pk 				--srclong;
   1956        1.1        pk 				--dstlong;
   1957        1.1        pk 				} )
   1958        1.1        pk 
   1959        1.1        pk 		    /* Trailing edge. */
   1960        1.1        pk 		    if ( dstleftignore != 0 )
   1961        1.1        pk 			{
   1962        1.1        pk 			ROP_SRCDST(
   1963        1.1        pk 			/*op*/  op,
   1964        1.1        pk 			/*pre*/ dl = *dstlong;,
   1965        1.3        pk 			/*s*/   prevsl | ( *srclong LSOP prevleftshift ),
   1966        1.1        pk 			/*d*/   dl,
   1967        1.1        pk 			/*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
   1968        1.1        pk 			}
   1969        1.1        pk 
   1970        1.1        pk 		    srclin += srclininc;
   1971        1.1        pk 		    dstlin += dstlininc;
   1972        1.1        pk 		    }
   1973        1.1        pk 		}
   1974        1.1        pk 	    }
   1975        1.1        pk 	}
   1976        1.1        pk 
   1977        1.1        pk     return 0;
   1978        1.1        pk     }
   1979