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