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