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