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