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