Sync usage with man page.
[netbsd-mini2440.git] / sys / dev / rcons / raster_op.c
blob0cdcefc4261fd42b28cd9526454c0869b722d7d9
1 /* $NetBSD: raster_op.c,v 1.17 2009/03/18 17:06:50 cegger Exp $ */
3 /*-
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
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.
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.
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.
35 * @(#)raster_op.c 8.1 (Berkeley) 6/11/93
39 * Bitblit routine for raster library.
41 * This raster-op is machined to exacting tolerances by skilled native
42 * craftsmen with pride in their work.
44 * The various cases are broken down like this:
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
69 #include <sys/cdefs.h>
70 __KERNEL_RCSID(0, "$NetBSD: raster_op.c,v 1.17 2009/03/18 17:06:50 cegger Exp $");
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
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.
84 #ifdef _KERNEL
85 #define PARTIAL_LOGICAL_OPS
86 #endif
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.
95 #undef BCOPY_FASTER
97 /* End of configurable definitions. */
100 /* Definitions. */
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.
111 #ifndef PARTIAL_LOGICAL_OPS
113 #define ROP_DST(op,pre,d,pst) \
114 switch ( op ) \
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; \
138 #define ROP_DSTCOLOR(op,pre,d,c,pst) \
139 switch ( op ) \
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; \
163 #define ROP_SRCDST(op,pre,s,d,pst) \
164 switch ( op ) \
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; \
230 #define ROP_SRCDSTCOLOR(op,pre,s,d,c,pst) \
231 switch ( op ) \
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; \
327 #else /*PARTIAL_LOGICAL_OPS*/
329 #define ROP_DST(op,pre,d,pst) \
330 switch ( op ) \
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; \
351 #define ROP_DSTCOLOR(op,pre,d,c,pst) \
352 switch ( op ) \
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; \
373 #define ROP_SRCDST(op,pre,s,d,pst) \
374 switch ( op ) \
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; \
395 #define ROP_SRCDSTCOLOR(op,pre,s,d,c,pst) \
396 switch ( op ) \
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; \
424 #endif /*PARTIAL_LOGICAL_OPS*/
427 /* Variables. */
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 */
432 #ifdef MSBIT_FIRST
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 };
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 };
464 #define LSOP <<
465 #define RSOP >>
466 #endif /*MSBYTE_FIRST*/
468 #else /*MSBIT_FIRST*/
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 };
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*/
503 #endif /*MSBIT_FIRST*/
505 /* (The odd combinations MSBIT+~MSBYTE and ~MSBIT+MSBYTE could be added.) */
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*/
548 /* Forward routines. */
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);
554 /* Raster operations. */
556 /* Performs a bitblit. Returns 0 on success, -1 on failure. */
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;
564 if ( dst == (struct raster*) 0 )
565 return -1; /* no destination */
567 if ( needsrc[RAS_GETOP( rop )] )
569 /* Two-operand blit. */
570 if ( src == (struct raster*) 0 )
571 return -1; /* no source */
573 /* Clip against source. */
574 if ( sx < 0 )
576 w += sx;
577 sx = 0;
579 if ( sy < 0 )
581 h += sy;
582 sy = 0;
584 if ( sx + w > src->width )
585 w = src->width - sx;
586 if ( sy + h > src->height )
587 h = src->height - sy;
589 /* Clip against dest. */
590 if ( dx < 0 )
592 w += dx;
593 sx -= dx;
594 dx = 0;
596 if ( dy < 0 )
598 h += dy;
599 sy -= dy;
600 dy = 0;
602 if ( dx + w > dst->width )
603 w = dst->width - dx;
604 if ( dy + h > dst->height )
605 h = dst->height - dy;
607 if ( w <= 0 || h <= 0 )
608 return 0; /* nothing to do */
610 return raster_op_noclip( dst, dx, dy, w, h, rop, src, sx, sy );
613 /* No source necessary - one-operand blit. */
614 if ( src != (struct raster*) 0 )
615 return -1; /* unwanted source */
617 /* Clip against dest. */
618 if ( dx < 0 )
620 w += dx;
621 dx = 0;
623 if ( dy < 0 )
625 h += dy;
626 dy = 0;
628 if ( dx + w > dst->width )
629 w = dst->width - dx;
630 if ( dy + h > dst->height )
631 h = dst->height - dy;
633 if ( w <= 0 || h <= 0 )
634 return 0; /* nothing to do */
636 return raster_op_nosrc_noclip( dst, dx, dy, w, h, rop );
639 /* Semi-public routine to do a bitblit without clipping. Returns 0 on
640 ** success, -1 on failure.
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;
649 int op;
651 op = RAS_GETOP( rop );
653 if ( src->depth == 1 )
655 /* One-bit to ? blit. */
656 if ( dst->depth == 1 )
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;
664 srclin1 = RAS_ADDR( src, sx, sy );
665 dstlin1 = RAS_ADDR( dst, dx, dy );
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 )
672 bcopy(
673 (char*) srclin1, (char*) dstlin1,
674 h * src->linelongs * sizeof(u_int32_t) );
675 return 0;
677 #endif /*BCOPY_FASTER*/
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;
686 return raster_blit(
687 src, srclin1, srcleftignore, srcrightignore, srclongs,
688 dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
691 #ifdef RCONS_2BPP
692 else if ( dst->depth == 2 )
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;
705 color = RAS_GETCOLOR( rop );
706 if ( color == 0 )
707 color = 3;
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 ));
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;
723 while ( srclin != srclin2 )
725 srclong = srclin;
726 srcbit = sx & 31;
727 dstlong = dstlin;
728 dstbyte = dx & 15;
729 i = w;
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 )
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 )
744 srcbit = 0;
745 ++srclong;
747 else
748 ++srcbit;
749 if ( dstbyte == 15 )
751 dstbyte = 0;
752 ++dstlong;
754 else
755 ++dstbyte;
756 --i;
759 srclin += src->linelongs;
760 dstlin += dst->linelongs;
763 #endif /* RCONS_2BPP */
764 #ifdef RCONS_4BPP
765 else if ( dst->depth == 4 )
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;
778 color = RAS_GETCOLOR( rop );
779 if ( color == 0 )
780 color = 15;
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 ));
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;
795 while ( srclin != srclin2 )
797 srclong = srclin;
798 srcbit = sx & 31;
799 dstlong = dstlin;
800 dstbyte = dx & 7;
801 i = w;
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 )
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 )
816 srcbit = 0;
817 ++srclong;
819 else
820 ++srcbit;
821 if ( dstbyte == 7 )
823 dstbyte = 0;
824 ++dstlong;
826 else
827 ++dstbyte;
828 --i;
831 srclin += src->linelongs;
832 dstlin += dst->linelongs;
835 #endif /* RCONS_4BPP */
836 else if ( dst->depth == 8 )
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.
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;
853 color = RAS_GETCOLOR( rop );
854 if ( color == 0 )
855 color = 255;
857 /* Make 32 bits of color so we can do the ROP without shifting. */
858 color |= ( color << 24 ) | ( color << 16 ) | ( color << 8 );
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 )
868 srclong = srclin;
869 srcbit = sx & 31;
870 dstlong = dstlin;
871 dstbyte = dx & 3;
872 i = w;
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 )
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 )
887 srcbit = 0;
888 ++srclong;
890 else
891 ++srcbit;
892 if ( dstbyte == 3 )
894 dstbyte = 0;
895 ++dstlong;
897 else
898 ++dstbyte;
899 --i;
902 srclin += src->linelongs;
903 dstlin += dst->linelongs;
906 #ifdef RCONS_16BPP
907 else
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.
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;
924 color = RAS_GETCOLOR( rop );
925 if ( color == 0 )
926 color = 0xffff;
928 /* Make 32 bits of color so we can do the ROP without shifting. */
929 color |= ( color << 16 );
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 )
939 srclong = srclin;
940 srcbit = sx & 31;
941 dstlong = dstlin;
942 dstbyte = dx & 1;
943 i = w;
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 )
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 )
958 srcbit = 0;
959 ++srclong;
961 else
962 ++srcbit;
963 if ( dstbyte == 1 )
965 dstbyte = 0;
966 ++dstlong;
968 else
969 ++dstbyte;
970 --i;
973 srclin += src->linelongs;
974 dstlin += dst->linelongs;
977 #endif /* RCONS_16BPP */
979 #ifdef RCONS_2BPP
980 else if ( src->depth == 2 )
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;
988 srclin1 = RAS_ADDR( src, sx, sy );
989 dstlin1 = RAS_ADDR( dst, dx, dy );
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;
998 return raster_blit(
999 src, srclin1, srcleftignore, srcrightignore, srclongs,
1000 dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
1002 #endif /* RCONS_2BPP */
1003 #ifdef RCONS_4BPP
1004 else if ( src->depth == 4 )
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;
1012 srclin1 = RAS_ADDR( src, sx, sy );
1013 dstlin1 = RAS_ADDR( dst, dx, dy );
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;
1022 return raster_blit(
1023 src, srclin1, srcleftignore, srcrightignore, srclongs,
1024 dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
1026 #endif /* RCONS_4BPP */
1028 else if ( src->depth == 8 )
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;
1036 if ( dst->depth != 8 )
1037 return -1; /* depth mismatch */
1039 srclin1 = RAS_ADDR( src, sx, sy );
1040 dstlin1 = RAS_ADDR( dst, dx, dy );
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 )
1047 bcopy( (char*) srclin1, (char*) dstlin1,
1048 h * src->linelongs * sizeof(u_int32_t) );
1049 return 0;
1051 #endif /*BCOPY_FASTER*/
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;
1060 return raster_blit(
1061 src, srclin1, srcleftignore, srcrightignore, srclongs,
1062 dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
1064 #ifdef RCONS_16BPP
1065 else
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;
1073 srclin1 = RAS_ADDR( src, sx, sy );
1074 dstlin1 = RAS_ADDR( dst, dx, dy );
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;
1083 return raster_blit(
1084 src, srclin1, srcleftignore, srcrightignore, srclongs,
1085 dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
1087 #endif /* RCONS_16BPP */
1088 return 0;
1091 /* Semi-public routine to do a no-src bitblit without clipping. Returns 0
1092 ** on success, -1 on failure.
1095 raster_op_nosrc_noclip( dst, dx, dy, w, h, rop )
1096 struct raster* dst;
1097 int dx, dy, w, h, rop;
1099 int op;
1101 op = RAS_GETOP( rop );
1103 if ( dst->depth == 1 )
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;
1114 dstlin1 = RAS_ADDR( dst, dx, dy );
1116 #ifdef BCOPY_FASTER
1117 /* Special-case full-width clears. */
1118 if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 5 )
1120 memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) );
1121 return 0;
1123 #endif /*BCOPY_FASTER*/
1125 dstleftignore = ( dx & 31 );
1126 dstlongs = ( dstleftignore + w + 31 ) >> 5;
1127 dstrightignore = ( dstlongs * 32 - w - dstleftignore ) & 31;
1129 dstlin2 = dstlin1 + h * dst->linelongs;
1130 dstlin = dstlin1;
1132 if ( dstlongs == 1 )
1134 /* It fits into a single longword. */
1135 lm = leftmask[dstleftignore] | rightmask[dstrightignore];
1136 nlm = ~lm;
1137 while ( dstlin != dstlin2 )
1139 ROP_DST(
1140 /*op*/ op,
1141 /*pre*/ dl = *dstlin;,
1142 /*d*/ dl,
1143 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
1145 dstlin += dst->linelongs;
1148 else
1150 lm = leftmask[dstleftignore];
1151 rm = rightmask[dstrightignore];
1152 nrm = ~rm;
1153 nlm = ~lm;
1155 while ( dstlin != dstlin2 )
1157 dstlong = dstlin;
1158 dstlong2 = dstlong + dstlongs;
1159 if ( dstrightignore != 0 )
1160 --dstlong2;
1162 /* Leading edge. */
1163 if ( dstleftignore != 0 )
1165 ROP_DST(
1166 /*op*/ op,
1167 /*pre*/ dl = *dstlong;,
1168 /*d*/ dl,
1169 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
1170 ++dstlong;
1173 /* Main rop. */
1174 ROP_DST(
1175 /*op*/ op,
1176 /*pre*/ while ( dstlong != dstlong2 )
1178 /*d*/ *dstlong,
1179 /*pst*/ ++dstlong;
1182 /* Trailing edge. */
1183 if ( dstrightignore != 0 )
1185 ROP_DST(
1186 /*op*/ op,
1187 /*pre*/ dl = *dstlong;,
1188 /*d*/ dl,
1189 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
1192 dstlin += dst->linelongs;
1197 #ifdef RCONS_2BPP
1198 else if ( dst->depth == 2 )
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;
1210 dstlin1 = RAS_ADDR( dst, dx, dy );
1212 #ifdef BCOPY_FASTER
1213 /* Special-case full-width clears. */
1214 if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 4 )
1216 memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) );
1217 return 0;
1219 #endif /*BCOPY_FASTER*/
1221 color = RAS_GETCOLOR( rop );
1222 if ( color == 0 )
1223 color = 3;
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 ));
1232 dstleftignore = ( dx & 15 ) * 2;
1233 dstlongs = ( dstleftignore + w * 2 + 31 ) >> 5;
1234 dstrightignore = ( dstlongs * 32 - w * 2 - dstleftignore ) & 31;
1236 dstlin2 = dstlin1 + h * dst->linelongs;
1237 dstlin = dstlin1;
1239 if ( dstlongs == 1 )
1241 /* It fits into a single longword. */
1242 lm = leftmask[dstleftignore] | rightmask[dstrightignore];
1243 nlm = ~lm;
1244 while ( dstlin != dstlin2 )
1246 ROP_DST(
1247 /*op*/ op,
1248 /*pre*/ dl = *dstlin;,
1249 /*d*/ dl,
1250 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
1252 dstlin += dst->linelongs;
1255 else
1257 lm = leftmask[dstleftignore];
1258 rm = rightmask[dstrightignore];
1259 nrm = ~rm;
1260 nlm = ~lm;
1262 while ( dstlin != dstlin2 )
1264 dstlong = dstlin;
1265 dstlong2 = dstlong + dstlongs;
1266 if ( dstrightignore != 0 )
1267 --dstlong2;
1269 /* Leading edge. */
1270 if ( dstleftignore != 0 )
1272 ROP_DST(
1273 /*op*/ op,
1274 /*pre*/ dl = *dstlong;,
1275 /*d*/ dl,
1276 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
1277 ++dstlong;
1280 /* Main rop. */
1281 ROP_DST(
1282 /*op*/ op,
1283 /*pre*/ while ( dstlong != dstlong2 )
1285 /*d*/ *dstlong,
1286 /*pst*/ ++dstlong;
1289 /* Trailing edge. */
1290 if ( dstrightignore != 0 )
1292 ROP_DST(
1293 /*op*/ op,
1294 /*pre*/ dl = *dstlong;,
1295 /*d*/ dl,
1296 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
1299 dstlin += dst->linelongs;
1303 #endif /* RCONS_2BPP */
1304 #ifdef RCONS_4BPP
1305 else if ( dst->depth == 4 )
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;
1317 dstlin1 = RAS_ADDR( dst, dx, dy );
1319 #ifdef BCOPY_FASTER
1320 /* Special-case full-width clears. */
1321 if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 3 )
1323 memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) );
1324 return 0;
1326 #endif /*BCOPY_FASTER*/
1328 color = RAS_GETCOLOR( rop );
1329 if ( color == 0 )
1330 color = 15;
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 ));
1338 dstleftignore = ( dx & 7 ) * 4;
1339 dstlongs = ( dstleftignore + w * 4 + 31 ) >> 5;
1340 dstrightignore = ( dstlongs * 32 - w * 4 - dstleftignore ) & 31;
1342 dstlin2 = dstlin1 + h * dst->linelongs;
1343 dstlin = dstlin1;
1345 if ( dstlongs == 1 )
1347 /* It fits into a single longword. */
1348 lm = leftmask[dstleftignore] | rightmask[dstrightignore];
1349 nlm = ~lm;
1350 while ( dstlin != dstlin2 )
1352 ROP_DST(
1353 /*op*/ op,
1354 /*pre*/ dl = *dstlin;,
1355 /*d*/ dl,
1356 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
1358 dstlin += dst->linelongs;
1361 else
1363 lm = leftmask[dstleftignore];
1364 rm = rightmask[dstrightignore];
1365 nrm = ~rm;
1366 nlm = ~lm;
1368 while ( dstlin != dstlin2 )
1370 dstlong = dstlin;
1371 dstlong2 = dstlong + dstlongs;
1372 if ( dstrightignore != 0 )
1373 --dstlong2;
1375 /* Leading edge. */
1376 if ( dstleftignore != 0 )
1378 ROP_DST(
1379 /*op*/ op,
1380 /*pre*/ dl = *dstlong;,
1381 /*d*/ dl,
1382 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
1383 ++dstlong;
1386 /* Main rop. */
1387 ROP_DST(
1388 /*op*/ op,
1389 /*pre*/ while ( dstlong != dstlong2 )
1391 /*d*/ *dstlong,
1392 /*pst*/ ++dstlong;
1395 /* Trailing edge. */
1396 if ( dstrightignore != 0 )
1398 ROP_DST(
1399 /*op*/ op,
1400 /*pre*/ dl = *dstlong;,
1401 /*d*/ dl,
1402 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
1405 dstlin += dst->linelongs;
1409 #endif /* RCONS_4BPP */
1410 else if ( dst->depth == 8)
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;
1422 dstlin1 = RAS_ADDR( dst, dx, dy );
1424 #ifdef BCOPY_FASTER
1425 /* Special-case full-width clears. */
1426 if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 2 )
1428 memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) );
1429 return 0;
1431 #endif /*BCOPY_FASTER*/
1433 color = RAS_GETCOLOR( rop );
1434 if ( color == 0 )
1435 color = 255;
1437 /* Make 32 bits of color so we can do the ROP without shifting. */
1438 color |= ( color << 24 ) | ( color << 16 ) | ( color << 8 );
1440 dstleftignore = ( dx & 3 ) * 8;
1441 dstlongs = ( dstleftignore + w * 8 + 31 ) >> 5;
1442 dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31;
1444 dstlin2 = dstlin1 + h * dst->linelongs;
1445 dstlin = dstlin1;
1447 if ( dstlongs == 1 )
1449 /* It fits into a single longword. */
1450 lm = leftmask[dstleftignore] | rightmask[dstrightignore];
1451 nlm = ~lm;
1452 while ( dstlin != dstlin2 )
1454 ROP_DSTCOLOR(
1455 /*op*/ op,
1456 /*pre*/ dl = *dstlin;,
1457 /*d*/ dl,
1458 /*c*/ color,
1459 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
1461 dstlin += dst->linelongs;
1464 else
1466 lm = leftmask[dstleftignore];
1467 rm = rightmask[dstrightignore];
1468 nrm = ~rm;
1469 nlm = ~lm;
1470 while ( dstlin != dstlin2 )
1472 dstlong = dstlin;
1473 dstlong2 = dstlong + dstlongs;
1474 if ( dstrightignore != 0 )
1475 --dstlong2;
1477 /* Leading edge. */
1478 if ( dstleftignore != 0 )
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;
1489 /* Main rop. */
1490 ROP_DSTCOLOR(
1491 /*op*/ op,
1492 /*pre*/ while ( dstlong != dstlong2 )
1494 /*d*/ *dstlong,
1495 /*c*/ color,
1496 /*pst*/ ++dstlong;
1499 /* Trailing edge. */
1500 if ( dstrightignore != 0 )
1502 ROP_DSTCOLOR(
1503 /*op*/ op,
1504 /*pre*/ dl = *dstlong;,
1505 /*d*/ dl,
1506 /*c*/ color,
1507 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
1510 dstlin += dst->linelongs;
1514 #ifdef RCONS_16BPP
1515 else
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;
1527 dstlin1 = RAS_ADDR( dst, dx, dy );
1529 #ifdef BCOPY_FASTER
1530 /* Special-case full-width clears. */
1531 if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 1 )
1533 memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) );
1534 return 0;
1536 #endif /*BCOPY_FASTER*/
1538 color = RAS_GETCOLOR( rop );
1539 if ( color == 0 )
1540 color = 0xffff; /* XXX */
1542 /* Make 32 bits of color so we can do the ROP without shifting. */
1543 color |= ( color << 16 );
1545 dstleftignore = ( dx & 1 ) * 16;
1546 dstlongs = ( dstleftignore + w * 16 + 31 ) >> 5;
1547 dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31;
1549 dstlin2 = dstlin1 + h * dst->linelongs;
1550 dstlin = dstlin1;
1552 if ( dstlongs == 1 )
1554 /* It fits into a single longword. */
1555 lm = leftmask[dstleftignore] | rightmask[dstrightignore];
1556 nlm = ~lm;
1557 while ( dstlin != dstlin2 )
1559 ROP_DSTCOLOR(
1560 /*op*/ op,
1561 /*pre*/ dl = *dstlin;,
1562 /*d*/ dl,
1563 /*c*/ color,
1564 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
1566 dstlin += dst->linelongs;
1569 else
1571 lm = leftmask[dstleftignore];
1572 rm = rightmask[dstrightignore];
1573 nrm = ~rm;
1574 nlm = ~lm;
1575 while ( dstlin != dstlin2 )
1577 dstlong = dstlin;
1578 dstlong2 = dstlong + dstlongs;
1579 if ( dstrightignore != 0 )
1580 --dstlong2;
1582 /* Leading edge. */
1583 if ( dstleftignore != 0 )
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;
1594 /* Main rop. */
1595 ROP_DSTCOLOR(
1596 /*op*/ op,
1597 /*pre*/ while ( dstlong != dstlong2 )
1599 /*d*/ *dstlong,
1600 /*c*/ color,
1601 /*pst*/ ++dstlong;
1604 /* Trailing edge. */
1605 if ( dstrightignore != 0 )
1607 ROP_DSTCOLOR(
1608 /*op*/ op,
1609 /*pre*/ dl = *dstlong;,
1610 /*d*/ dl,
1611 /*c*/ color,
1612 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
1615 dstlin += dst->linelongs;
1619 #endif /* RCONS_16BPP */
1621 return 0;
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.
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;
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;
1649 prevleftshift = ( srcleftignore - dstleftignore ) & 31;
1651 srclin2 = srclin1 + h * src->linelongs;
1652 dstlin2 = dstlin1 + h * dst->linelongs;
1653 srclininc = src->linelongs;
1654 dstlininc = dst->linelongs;
1655 longinc = 1;
1657 /* Check for overlaps. */
1658 if ( ( dstlin1 >= srclin1 && dstlin1 < srclin1 + srclongs ) ||
1659 ( srclin1 >= dstlin1 && srclin1 < dstlin1 + dstlongs ) )
1661 /* Horizontal overlap. Should we reverse? */
1662 if ( srclin1 < dstlin1 )
1664 longinc = -1;
1665 srclin1 += srclongs - 1;
1666 srclin2 += srclongs - 1;
1667 dstlin1 += dstlongs - 1;
1670 else if ( ( dstlin1 >= srclin1 && dstlin1 < srclin2 ) ||
1671 ( srclin1 >= dstlin1 && srclin1 < dstlin2 ) )
1673 /* Vertical overlap. Should we reverse? */
1674 if ( srclin1 < dstlin1 )
1676 srclin2 = srclin1 - srclininc;
1677 srclin1 += ( h - 1 ) * srclininc;
1678 dstlin1 += ( h - 1 ) * dstlininc;
1679 srclininc = -srclininc;
1680 dstlininc = -dstlininc;
1683 srclin = srclin1;
1684 dstlin = dstlin1;
1686 if ( prevleftshift == 0 )
1688 /* The bits line up, no shifting necessary. */
1689 if ( dstlongs == 1 )
1691 /* It all fits into a single longword. */
1692 lm = leftmask[dstleftignore] | rightmask[dstrightignore];
1693 nlm = ~lm;
1694 while ( srclin != srclin2 )
1696 ROP_SRCDST(
1697 /*op*/ op,
1698 /*pre*/ dl = *dstlin;,
1699 /*s*/ *srclin,
1700 /*d*/ dl,
1701 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
1703 srclin += srclininc;
1704 dstlin += dstlininc;
1707 else
1709 /* Multiple longwords. */
1710 lm = leftmask[dstleftignore];
1711 rm = rightmask[dstrightignore];
1712 nrm = ~rm;
1713 nlm = ~lm;
1714 if ( longinc == 1 )
1716 /* Left to right. */
1717 while ( srclin != srclin2 )
1719 srclong = srclin;
1720 dstlong = dstlin;
1721 dstlong2 = dstlong + dstlongs;
1722 if ( dstrightignore != 0 )
1723 --dstlong2;
1725 /* Leading edge. */
1726 if ( dstleftignore != 0 )
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;
1738 /* Main rop. */
1739 ROP_SRCDST(
1740 /*op*/ op,
1741 /*pre*/ while ( dstlong != dstlong2 )
1743 /*s*/ *srclong,
1744 /*d*/ *dstlong,
1745 /*pst*/ ++srclong;
1746 ++dstlong;
1749 /* Trailing edge. */
1750 if ( dstrightignore != 0 )
1752 ROP_SRCDST(
1753 /*op*/ op,
1754 /*pre*/ dl = *dstlong;,
1755 /*s*/ *srclong,
1756 /*d*/ dl,
1757 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
1760 srclin += srclininc;
1761 dstlin += dstlininc;
1764 else
1766 /* Right to left. */
1767 while ( srclin != srclin2 )
1769 srclong = srclin;
1770 dstlong = dstlin;
1771 dstlong2 = dstlong - dstlongs;
1772 if ( dstleftignore != 0 )
1773 ++dstlong2;
1775 /* Leading edge. */
1776 if ( dstrightignore != 0 )
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;
1788 /* Main rop. */
1789 ROP_SRCDST(
1790 /*op*/ op,
1791 /*pre*/ while ( dstlong != dstlong2 )
1793 /*s*/ *srclong,
1794 /*d*/ *dstlong,
1795 /*pst*/ --srclong;
1796 --dstlong;
1799 /* Trailing edge. */
1800 if ( dstleftignore != 0 )
1802 ROP_SRCDST(
1803 /*op*/ op,
1804 /*pre*/ dl = *dstlong;,
1805 /*s*/ *srclong,
1806 /*d*/ dl,
1807 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
1810 srclin += srclininc;
1811 dstlin += dstlininc;
1817 else
1819 /* General case, with shifting and everything. */
1820 u_int32_t sl, prevsl;
1822 currrightshift = 32 - prevleftshift;
1823 if ( srclongs == 1 && dstlongs == 1 )
1825 /* It fits into a single longword, with a shift. */
1826 lm = leftmask[dstleftignore] | rightmask[dstrightignore];
1827 nlm = ~lm;
1828 if ( srcleftignore > dstleftignore )
1830 while ( srclin != srclin2 )
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 ); )
1839 srclin += srclininc;
1840 dstlin += dstlininc;
1843 else
1845 while ( srclin != srclin2 )
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 ); )
1854 srclin += srclininc;
1855 dstlin += dstlininc;
1859 else
1861 /* Multiple longwords. */
1862 lm = leftmask[dstleftignore];
1863 rm = rightmask[dstrightignore];
1864 nrm = ~rm;
1865 nlm = ~lm;
1866 if ( longinc == 1 )
1868 /* Left to right. */
1869 while ( srclin != srclin2 )
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;
1881 /* Leading edge. */
1882 if ( dstleftignore != 0 )
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;
1896 /* Main rop. */
1897 ROP_SRCDST(
1898 /*op*/ op,
1899 /*pre*/ while ( dstlong != dstlong2 )
1901 sl = *srclong;,
1902 /*s*/ prevsl | ( sl RSOP currrightshift ),
1903 /*d*/ *dstlong,
1904 /*pst*/ prevsl = sl LSOP prevleftshift;
1905 ++srclong;
1906 ++dstlong;
1909 /* Trailing edge. */
1910 if ( dstrightignore != 0 )
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 ); )
1920 srclin += srclininc;
1921 dstlin += dstlininc;
1924 else
1926 /* Right to left. */
1927 while ( srclin != srclin2 )
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;
1939 /* Leading edge. */
1940 if ( dstrightignore != 0 )
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;
1954 /* Main rop. */
1955 ROP_SRCDST(
1956 /*op*/ op,
1957 /*pre*/ while ( dstlong != dstlong2 )
1959 sl = *srclong;,
1960 /*s*/ prevsl | ( sl LSOP prevleftshift ),
1961 /*d*/ *dstlong,
1962 /*pst*/ prevsl = sl RSOP currrightshift;
1963 --srclong;
1964 --dstlong;
1967 /* Trailing edge. */
1968 if ( dstleftignore != 0 )
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 ); )
1978 srclin += srclininc;
1979 dstlin += dstlininc;
1985 return 0;