2 * DIB driver primitives.
4 * Copyright 2011 Huw Davies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "gdi_private.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(dib
);
30 /* Bayer matrices for dithering */
32 static const BYTE bayer_4x4
[4][4] =
40 static const BYTE bayer_8x8
[8][8] =
42 { 0, 32, 8, 40, 2, 34, 10, 42 },
43 { 48, 16, 56, 24, 50, 18, 58, 26 },
44 { 12, 44, 4, 36, 14, 46, 6, 38 },
45 { 60, 28, 52, 20, 62, 30, 54, 22 },
46 { 3, 35, 11, 43, 1, 33, 9, 41 },
47 { 51, 19, 59, 27, 49, 17, 57, 25 },
48 { 15, 47, 7, 39, 13, 45, 5, 37 },
49 { 63, 31, 55, 23, 61, 29, 53, 21 }
52 static const BYTE bayer_16x16
[16][16] =
54 { 0, 128, 32, 160, 8, 136, 40, 168, 2, 130, 34, 162, 10, 138, 42, 170 },
55 { 192, 64, 224, 96, 200, 72, 232, 104, 194, 66, 226, 98, 202, 74, 234, 106 },
56 { 48, 176, 16, 144, 56, 184, 24, 152, 50, 178, 18, 146, 58, 186, 26, 154 },
57 { 240, 112, 208, 80, 248, 120, 216, 88, 242, 114, 210, 82, 250, 122, 218, 90 },
58 { 12, 140, 44, 172, 4, 132, 36, 164, 14, 142, 46, 174, 6, 134, 38, 166 },
59 { 204, 76, 236, 108, 196, 68, 228, 100, 206, 78, 238, 110, 198, 70, 230, 102 },
60 { 60, 188, 28, 156, 52, 180, 20, 148, 62, 190, 30, 158, 54, 182, 22, 150 },
61 { 252, 124, 220, 92, 244, 116, 212, 84, 254, 126, 222, 94, 246, 118, 214, 86 },
62 { 3, 131, 35, 163, 11, 139, 43, 171, 1, 129, 33, 161, 9, 137, 41, 169 },
63 { 195, 67, 227, 99, 203, 75, 235, 107, 193, 65, 225, 97, 201, 73, 233, 105 },
64 { 51, 179, 19, 147, 59, 187, 27, 155, 49, 177, 17, 145, 57, 185, 25, 153 },
65 { 243, 115, 211, 83, 251, 123, 219, 91, 241, 113, 209, 81, 249, 121, 217, 89 },
66 { 15, 143, 47, 175, 7, 135, 39, 167, 13, 141, 45, 173, 5, 133, 37, 165 },
67 { 207, 79, 239, 111, 199, 71, 231, 103, 205, 77, 237, 109, 197, 69, 229, 101 },
68 { 63, 191, 31, 159, 55, 183, 23, 151, 61, 189, 29, 157, 53, 181, 21, 149 },
69 { 255, 127, 223, 95, 247, 119, 215, 87, 253, 125, 221, 93, 245, 117, 213, 85 },
72 static inline DWORD
*get_pixel_ptr_32(const dib_info
*dib
, int x
, int y
)
74 return (DWORD
*)((BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) * 4);
77 static inline DWORD
*get_pixel_ptr_24_dword(const dib_info
*dib
, int x
, int y
)
79 return (DWORD
*)((BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
) + (dib
->rect
.left
+ x
) * 3 / 4;
82 static inline BYTE
*get_pixel_ptr_24(const dib_info
*dib
, int x
, int y
)
84 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) * 3;
87 static inline WORD
*get_pixel_ptr_16(const dib_info
*dib
, int x
, int y
)
89 return (WORD
*)((BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) * 2);
92 static inline BYTE
*get_pixel_ptr_8(const dib_info
*dib
, int x
, int y
)
94 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ dib
->rect
.left
+ x
;
97 static inline BYTE
*get_pixel_ptr_4(const dib_info
*dib
, int x
, int y
)
99 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) / 2;
102 static inline BYTE
*get_pixel_ptr_1(const dib_info
*dib
, int x
, int y
)
104 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) / 8;
107 static const BYTE pixel_masks_4
[2] = {0xf0, 0x0f};
108 static const BYTE pixel_masks_1
[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
109 static const BYTE edge_masks_1
[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
111 #define ROPS_WITHOUT_COPY( _d, _s ) \
112 case R2_BLACK: LOOP( (_d) = 0 ) break; \
113 case R2_NOTMERGEPEN: LOOP( (_d) = ~((_d) | (_s)) ) break; \
114 case R2_MASKNOTPEN: LOOP( (_d) &= ~(_s) ) break; \
115 case R2_NOTCOPYPEN: LOOP( (_d) = ~(_s) ) break; \
116 case R2_MASKPENNOT: LOOP( (_d) = (~(_d) & (_s)) ) break; \
117 case R2_NOT: LOOP( (_d) = ~(_d) ) break; \
118 case R2_XORPEN: LOOP( (_d) ^= (_s) ) break; \
119 case R2_NOTMASKPEN: LOOP( (_d) = ~((_d) & (_s)) ) break; \
120 case R2_MASKPEN: LOOP( (_d) &= (_s) ) break; \
121 case R2_NOTXORPEN: LOOP( (_d) = ~((_d) ^ (_s)) ) break; \
122 case R2_NOP: break; \
123 case R2_MERGENOTPEN: LOOP( (_d) = ((_d) | ~(_s)) ) break; \
124 case R2_MERGEPENNOT: LOOP( (_d) = (~(_d) | (_s)) ) break; \
125 case R2_MERGEPEN: LOOP( (_d) |= (_s) ) break; \
126 case R2_WHITE: LOOP( (_d) = ~0 ) break;
128 #define ROPS_ALL( _d, _s ) \
129 case R2_COPYPEN: LOOP( (_d) = (_s) ) break; \
130 ROPS_WITHOUT_COPY( (_d), (_s) )
132 static inline void do_rop_32(DWORD
*ptr
, DWORD
and, DWORD
xor)
134 *ptr
= (*ptr
& and) ^ xor;
137 static inline void do_rop_16(WORD
*ptr
, WORD
and, WORD
xor)
139 *ptr
= (*ptr
& and) ^ xor;
142 static inline void do_rop_8(BYTE
*ptr
, BYTE
and, BYTE
xor)
144 *ptr
= (*ptr
& and) ^ xor;
147 static inline void do_rop_mask_8(BYTE
*ptr
, BYTE
and, BYTE
xor, BYTE mask
)
149 *ptr
= (*ptr
& (and | ~mask
)) ^ (xor & mask
);
152 static inline void do_rop_codes_32(DWORD
*dst
, DWORD src
, struct rop_codes
*codes
)
154 do_rop_32( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
157 static inline void do_rop_codes_16(WORD
*dst
, WORD src
, struct rop_codes
*codes
)
159 do_rop_16( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
162 static inline void do_rop_codes_8(BYTE
*dst
, BYTE src
, struct rop_codes
*codes
)
164 do_rop_8( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
167 static inline void do_rop_codes_mask_8(BYTE
*dst
, BYTE src
, struct rop_codes
*codes
, BYTE mask
)
169 do_rop_mask_8( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
, mask
);
172 static inline void do_rop_codes_line_16(WORD
*dst
, const WORD
*src
, struct rop_codes
*codes
, int len
)
174 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_16( dst
, *src
, codes
);
177 static inline void do_rop_codes_line_rev_16(WORD
*dst
, const WORD
*src
, struct rop_codes
*codes
, int len
)
179 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
180 do_rop_codes_16( dst
, *src
, codes
);
183 static inline void do_rop_codes_line_8(BYTE
*dst
, const BYTE
*src
, struct rop_codes
*codes
, int len
)
185 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_8( dst
, *src
, codes
);
188 static inline void do_rop_codes_line_rev_8(BYTE
*dst
, const BYTE
*src
, struct rop_codes
*codes
, int len
)
190 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
191 do_rop_codes_8( dst
, *src
, codes
);
194 static inline void do_rop_codes_line_4(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
195 struct rop_codes
*codes
, int len
)
199 for (src
+= src_x
/ 2, dst
+= dst_x
/ 2; len
> 0; len
--, dst_x
++, src_x
++)
203 if (src_x
& 1) src_val
= *src
++;
204 else src_val
= *src
>> 4;
205 do_rop_codes_mask_8( dst
++, src_val
, codes
, 0x0f );
209 if (src_x
& 1) src_val
= *src
++ << 4;
211 do_rop_codes_mask_8( dst
, src_val
, codes
, 0xf0 );
216 static inline void do_rop_codes_line_rev_4(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
217 struct rop_codes
*codes
, int len
)
223 for (src
+= src_x
/ 2, dst
+= dst_x
/ 2; len
> 0; len
--, dst_x
--, src_x
--)
227 if (src_x
& 1) src_val
= *src
;
228 else src_val
= *src
-- >> 4;
229 do_rop_codes_mask_8( dst
, src_val
, codes
, 0x0f );
233 if (src_x
& 1) src_val
= *src
<< 4;
234 else src_val
= *src
--;
235 do_rop_codes_mask_8( dst
--, src_val
, codes
, 0xf0 );
240 /**************************************************
243 * Return a byte representing 8 pixels of src data
244 * that is aligned with the dst.
246 * off is the number of bits that src is ahead of dst
247 * measured from the start. If off is +ve then we need to
248 * grab data from src[0] and src[1]. If off is -ve we use
249 * last (which is equivalent to src[-1]) and src[0]. For
250 * the first call in a line the last component will not be
251 * needed so it's safe for the caller to zero-init it.
253 * S |.....xxx|xxxxxxxx
254 * D |..xxxxxx|xxxxxxxx off = +3
256 * S |..xxxxxx|xxxxxxxx
257 * D |.....xxx|xxxxxxxx off = -3
259 static inline BYTE
get_src_byte_1(const BYTE
*src
, int off
, BYTE
*last
)
266 src_val
= (src
[0] << off
) | (src
[1] >> (8 - off
));
269 src_val
= (*last
<< (8 + off
)) | (src
[0] >> -off
);
276 static inline void do_rop_codes_line_1(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
277 struct rop_codes
*codes
, int len
, int rop2
)
279 BYTE src_val
, last_src
= 0;
280 int off
= (src_x
& 7) - (dst_x
& 7), i
, full_bytes
;
281 int dst_end
= dst_x
+ len
;
287 /* Handle special case of all of dst in one byte. */
288 if ((dst_x
& ~7) == ((dst_end
- 1) & ~7))
294 src_val
= src
[0] << off
;
295 if ((dst_end
& 7) + off
> 8)
296 src_val
|= (src
[1] >> (8 - off
));
299 src_val
= src
[0] >> -off
;
301 mask
= edge_masks_1
[dst_x
& 7];
303 mask
&= ~edge_masks_1
[dst_end
& 7];
304 do_rop_codes_mask_8( dst
, src_val
, codes
, mask
);
310 src_val
= get_src_byte_1( src
, off
, &last_src
);
311 mask
= edge_masks_1
[dst_x
& 7];
312 do_rop_codes_mask_8( dst
, src_val
, codes
, mask
);
317 full_bytes
= (dst_end
- ((dst_x
+ 7) & ~7)) / 8;
321 if (rop2
== R2_COPYPEN
)
323 memmove( dst
, src
, full_bytes
);
329 for (i
= 0; i
< full_bytes
; i
++, src
++, dst
++)
330 do_rop_codes_8( dst
, src
[0], codes
);
335 if (rop2
== R2_COPYPEN
)
337 for (i
= 0; i
< full_bytes
; i
++, src
++, dst
++)
338 dst
[0] = (src
[0] << off
) | (src
[1] >> (8 - off
));
342 for (i
= 0; i
< full_bytes
; i
++, src
++, dst
++)
343 do_rop_codes_8( dst
, (src
[0] << off
) | (src
[1] >> (8 - off
)), codes
);
348 if (rop2
== R2_COPYPEN
)
350 for (i
= 0; i
< full_bytes
; i
++, src
++, dst
++)
352 src_val
= (last_src
<< (8 + off
)) | (src
[0] >> -off
);
359 for (i
= 0; i
< full_bytes
; i
++, src
++, dst
++)
361 src_val
= (last_src
<< (8 + off
)) | (src
[0] >> -off
);
363 do_rop_codes_8( dst
, src_val
, codes
);
370 if (off
> 0 && (dst_end
& 7) + off
<= 8)
371 /* Don't read src[1] if everything's in src[0]. */
372 src_val
= src
[0] << off
;
373 else if (off
< 0 && (dst_end
& 7) + off
<= 0)
374 /* Don't read src[0] if everything's in last_src. */
375 src_val
= last_src
<< (8 + off
);
377 src_val
= get_src_byte_1( src
, off
, &last_src
);
378 mask
= ~edge_masks_1
[dst_end
& 7];
379 do_rop_codes_mask_8( dst
, src_val
, codes
, mask
);
383 /**************************************************
386 * Return a byte representing 8 pixels of src data
387 * that is aligned with the dst.
389 * off is the number of bits that src is ahead of dst
390 * measured from the end. If off is +ve then we need to
391 * grab data from src[0] and last (which is equivalent to src[1]).
392 * If off is -ve we use src[-1]) and src[0]. For the first call
393 * in a line the last component wil not be needed so it is safe
394 * for the caller to zero-init it.
396 * S xxxxxxxx|xxxxxx..|
397 * D xxxxxxxx|xxx.....| off = +3
399 * S xxxxxxxx|xxx.....|
400 * D xxxxxxxx|xxxxxx..| off = -3
402 static inline BYTE
get_src_byte_rev_1(const BYTE
*src
, int off
, BYTE
*last
)
410 src_val
= (src
[0] << off
) | (*last
>> (8 - off
));
414 src_val
= (src
[-1] << (8 + off
)) | (src
[0] >> -off
);
419 static inline void do_rop_codes_line_rev_1(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
420 struct rop_codes
*codes
, int len
, int rop2
)
422 BYTE src_val
, last_src
= 0;
423 int src_end
= src_x
+ len
, dst_end
= dst_x
+ len
;
424 int off
= ((src_end
- 1) & 7) - ((dst_end
- 1) & 7), i
, full_bytes
;
427 /* Handle special case of all of dst in one byte. */
428 if ((dst_x
& ~7) == ((dst_end
- 1) & ~7))
430 do_rop_codes_line_1(dst
, dst_x
, src
, src_x
, codes
, len
, rop2
);
434 src
+= (src_end
- 1) / 8;
435 dst
+= (dst_end
- 1) / 8;
439 src_val
= get_src_byte_rev_1( src
, off
, &last_src
);
440 mask
= ~edge_masks_1
[dst_end
& 7];
441 do_rop_codes_mask_8( dst
, src_val
, codes
, mask
);
446 full_bytes
= (dst_end
- ((dst_x
+ 7) & ~7)) / 8;
450 if (rop2
== R2_COPYPEN
)
452 memmove( dst
, src
, full_bytes
);
458 for (i
= 0; i
< full_bytes
; i
++, src
--, dst
--)
459 do_rop_codes_8( dst
, src
[0], codes
);
464 if (rop2
== R2_COPYPEN
)
466 for (i
= 0; i
< full_bytes
; i
++, src
--, dst
--)
468 src_val
= (src
[0] << off
) | (last_src
>> (8 - off
));
475 for (i
= 0; i
< full_bytes
; i
++, src
--, dst
--)
477 src_val
= (src
[0] << off
) | (last_src
>> (8 - off
));
479 do_rop_codes_8( dst
, src_val
, codes
);
485 if (rop2
== R2_COPYPEN
)
487 for (i
= 0; i
< full_bytes
; i
++, src
--, dst
--)
488 dst
[0] = (src
[-1] << (8 + off
)) | (src
[0] >> -off
);
492 for (i
= 0; i
< full_bytes
; i
++, src
--, dst
--)
493 do_rop_codes_8( dst
, (src
[-1] << (8 + off
)) | (src
[0] >> -off
), codes
);
499 if (off
< 0 && (dst_x
& 7) + off
>= 0)
500 /* Don't read src[-1] if everything's in src[0]. */
501 src_val
= src
[0] >> -off
;
502 else if (off
> 0 && (dst_x
& 7) + off
>= 8)
503 /* Don't read src[0] if everything's in last_src. */
504 src_val
= last_src
>> (8 - off
);
506 src_val
= get_src_byte_rev_1( src
, off
, &last_src
);
507 mask
= edge_masks_1
[dst_x
& 7];
508 do_rop_codes_mask_8( dst
, src_val
, codes
, mask
);
512 static inline void memset_32( DWORD
*start
, DWORD val
, DWORD size
)
514 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
516 __asm__
__volatile__( "cld; rep; stosl"
517 : "=c" (dummy
), "=D" (dummy
)
518 : "a" (val
), "0" (size
), "1" (start
) );
520 while (size
--) *start
++ = val
;
524 static inline void memset_16( WORD
*start
, WORD val
, DWORD size
)
526 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
528 __asm__
__volatile__( "cld; rep; stosw"
529 : "=c" (dummy
), "=D" (dummy
)
530 : "a" (val
), "0" (size
), "1" (start
) );
532 while (size
--) *start
++ = val
;
536 static void solid_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
541 for(i
= 0; i
< num
; i
++, rc
++)
543 assert( !is_rect_empty( rc
));
545 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
547 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
548 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
549 do_rop_32(ptr
++, and, xor);
551 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
552 memset_32( start
, xor, rc
->right
- rc
->left
);
556 static void solid_rects_24(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
559 BYTE
*byte_ptr
, *byte_start
;
561 DWORD and_masks
[3], xor_masks
[3];
563 and_masks
[0] = ( and & 0x00ffffff) | ((and << 24) & 0xff000000);
564 and_masks
[1] = ((and >> 8) & 0x0000ffff) | ((and << 16) & 0xffff0000);
565 and_masks
[2] = ((and >> 16) & 0x000000ff) | ((and << 8) & 0xffffff00);
566 xor_masks
[0] = ( xor & 0x00ffffff) | ((xor << 24) & 0xff000000);
567 xor_masks
[1] = ((xor >> 8) & 0x0000ffff) | ((xor << 16) & 0xffff0000);
568 xor_masks
[2] = ((xor >> 16) & 0x000000ff) | ((xor << 8) & 0xffffff00);
570 for(i
= 0; i
< num
; i
++, rc
++)
572 int left
= dib
->rect
.left
+ rc
->left
;
573 int right
= dib
->rect
.left
+ rc
->right
;
575 assert( !is_rect_empty( rc
));
577 if ((left
& ~3) == (right
& ~3)) /* Special case for lines that start and end in the same DWORD triplet */
579 byte_start
= get_pixel_ptr_24(dib
, rc
->left
, rc
->top
);
580 for(y
= rc
->top
; y
< rc
->bottom
; y
++, byte_start
+= dib
->stride
)
582 for(x
= left
, byte_ptr
= byte_start
; x
< right
; x
++)
584 do_rop_8(byte_ptr
++, and_masks
[0] & 0xff, xor_masks
[0] & 0xff);
585 do_rop_8(byte_ptr
++, and_masks
[1] & 0xff, xor_masks
[1] & 0xff);
586 do_rop_8(byte_ptr
++, and_masks
[2] & 0xff, xor_masks
[2] & 0xff);
592 start
= get_pixel_ptr_24_dword(dib
, rc
->left
, rc
->top
);
593 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
600 do_rop_32(ptr
++, and_masks
[0] | 0x00ffffff, xor_masks
[0] & 0xff000000);
601 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
602 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
605 do_rop_32(ptr
++, and_masks
[1] | 0x0000ffff, xor_masks
[1] & 0xffff0000);
606 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
609 do_rop_32(ptr
++, and_masks
[2] | 0x000000ff, xor_masks
[2] & 0xffffff00);
613 for(x
= (left
+ 3) & ~3; x
< (right
& ~3); x
+= 4)
615 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
616 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
617 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
623 do_rop_32(ptr
, and_masks
[0] | 0xff000000, xor_masks
[0] & 0x00ffffff);
626 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
627 do_rop_32(ptr
, and_masks
[1] | 0xffff0000, xor_masks
[1] & 0x0000ffff);
630 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
631 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
632 do_rop_32(ptr
, and_masks
[2] | 0xffffff00, xor_masks
[2] & 0x000000ff);
639 start
= get_pixel_ptr_24_dword(dib
, rc
->left
, rc
->top
);
640 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
647 do_rop_32(ptr
++, 0x00ffffff, xor_masks
[0] & 0xff000000);
648 *ptr
++ = xor_masks
[1];
649 *ptr
++ = xor_masks
[2];
652 do_rop_32(ptr
++, 0x0000ffff, xor_masks
[1] & 0xffff0000);
653 *ptr
++ = xor_masks
[2];
656 do_rop_32(ptr
++, 0x000000ff, xor_masks
[2] & 0xffffff00);
660 for(x
= (left
+ 3) & ~3; x
< (right
& ~3); x
+= 4)
662 *ptr
++ = xor_masks
[0];
663 *ptr
++ = xor_masks
[1];
664 *ptr
++ = xor_masks
[2];
670 do_rop_32(ptr
, 0xff000000, xor_masks
[0] & 0x00ffffff);
673 *ptr
++ = xor_masks
[0];
674 do_rop_32(ptr
, 0xffff0000, xor_masks
[1] & 0x0000ffff);
677 *ptr
++ = xor_masks
[0];
678 *ptr
++ = xor_masks
[1];
679 do_rop_32(ptr
, 0xffffff00, xor_masks
[2] & 0x000000ff);
687 static void solid_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
692 for(i
= 0; i
< num
; i
++, rc
++)
694 assert( !is_rect_empty( rc
));
696 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
698 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
699 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
700 do_rop_16(ptr
++, and, xor);
702 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
703 memset_16( start
, xor, rc
->right
- rc
->left
);
707 static void solid_rects_8(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
712 for(i
= 0; i
< num
; i
++, rc
++)
714 assert( !is_rect_empty( rc
));
716 start
= get_pixel_ptr_8(dib
, rc
->left
, rc
->top
);
718 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
719 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
720 do_rop_8(ptr
++, and, xor);
722 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
723 memset( start
, xor, rc
->right
- rc
->left
);
727 static void solid_rects_4(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
731 BYTE byte_and
= (and & 0xf) | ((and << 4) & 0xf0);
732 BYTE byte_xor
= (xor & 0xf) | ((xor << 4) & 0xf0);
734 for(i
= 0; i
< num
; i
++, rc
++)
736 int left
= dib
->rect
.left
+ rc
->left
;
737 int right
= dib
->rect
.left
+ rc
->right
;
739 assert( !is_rect_empty( rc
));
741 start
= get_pixel_ptr_4(dib
, rc
->left
, rc
->top
);
744 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
747 if(left
& 1) /* upper nibble untouched */
748 do_rop_8(ptr
++, byte_and
| 0xf0, byte_xor
& 0x0f);
750 for(x
= (left
+ 1) & ~1; x
< (right
& ~1); x
+= 2)
751 do_rop_8(ptr
++, byte_and
, byte_xor
);
753 if(right
& 1) /* lower nibble untouched */
754 do_rop_8(ptr
, byte_and
| 0x0f, byte_xor
& 0xf0);
759 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
761 unsigned int byte_len
= (right
- ((left
+ 1) & ~1)) / 2;
764 if(left
& 1) /* upper nibble untouched */
765 do_rop_8(ptr
++, 0xf0, byte_xor
& 0x0f);
767 memset( ptr
, byte_xor
, byte_len
);
769 if(right
& 1) /* lower nibble untouched */
770 do_rop_8(ptr
+ byte_len
, 0x0f, byte_xor
& 0xf0);
776 static void solid_rects_1(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
780 BYTE byte_and
= (and & 1) ? 0xff : 0;
781 BYTE byte_xor
= (xor & 1) ? 0xff : 0;
783 for(i
= 0; i
< num
; i
++, rc
++)
785 int left
= dib
->rect
.left
+ rc
->left
;
786 int right
= dib
->rect
.left
+ rc
->right
;
788 assert( !is_rect_empty( rc
));
790 start
= get_pixel_ptr_1(dib
, rc
->left
, rc
->top
);
792 if ((left
& ~7) == (right
& ~7)) /* Special case for lines that start and end in the same byte */
794 BYTE mask
= edge_masks_1
[left
& 7] & ~edge_masks_1
[right
& 7];
796 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
798 do_rop_8(start
, byte_and
| ~mask
, byte_xor
& mask
);
803 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
808 do_rop_8(ptr
++, byte_and
| ~edge_masks_1
[left
& 7], byte_xor
& edge_masks_1
[left
& 7]);
810 for(x
= (left
+ 7) & ~7; x
< (right
& ~7); x
+= 8)
811 do_rop_8(ptr
++, byte_and
, byte_xor
);
814 /* this is inverted wrt start mask */
815 do_rop_8(ptr
, byte_and
| edge_masks_1
[right
& 7], byte_xor
& ~edge_masks_1
[right
& 7]);
820 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
822 unsigned int byte_len
= (right
- ((left
+ 7) & ~7)) / 8;
827 do_rop_8(ptr
++, ~edge_masks_1
[left
& 7], byte_xor
& edge_masks_1
[left
& 7]);
829 memset( ptr
, byte_xor
, byte_len
);
832 do_rop_8(ptr
+ byte_len
, edge_masks_1
[right
& 7], byte_xor
& ~edge_masks_1
[right
& 7]);
838 static void solid_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
843 static void solid_line_32(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
844 DWORD
and, DWORD
xor)
846 DWORD
*ptr
= get_pixel_ptr_32( dib
, start
->x
, start
->y
);
847 int len
= params
->length
, err
= params
->err_start
;
848 int major_inc
, minor_inc
;
852 major_inc
= params
->x_inc
;
853 minor_inc
= (dib
->stride
* params
->y_inc
) / 4;
857 major_inc
= (dib
->stride
* params
->y_inc
) / 4;
858 minor_inc
= params
->x_inc
;
863 do_rop_32( ptr
, and, xor );
864 if (err
+ params
->bias
> 0)
867 err
+= params
->err_add_1
;
869 else err
+= params
->err_add_2
;
874 static void solid_line_24(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
875 DWORD
and, DWORD
xor)
877 BYTE
*ptr
= get_pixel_ptr_24( dib
, start
->x
, start
->y
);
878 int len
= params
->length
, err
= params
->err_start
;
879 int major_inc
, minor_inc
;
883 major_inc
= params
->x_inc
* 3;
884 minor_inc
= dib
->stride
* params
->y_inc
;
888 major_inc
= dib
->stride
* params
->y_inc
;
889 minor_inc
= params
->x_inc
* 3;
894 do_rop_8( ptr
, and, xor );
895 do_rop_8( ptr
+ 1, and >> 8, xor >> 8 );
896 do_rop_8( ptr
+ 2, and >> 16, xor >> 16 );
897 if (err
+ params
->bias
> 0)
900 err
+= params
->err_add_1
;
902 else err
+= params
->err_add_2
;
907 static void solid_line_16(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
908 DWORD
and, DWORD
xor)
910 WORD
*ptr
= get_pixel_ptr_16( dib
, start
->x
, start
->y
);
911 int len
= params
->length
, err
= params
->err_start
;
912 int major_inc
, minor_inc
;
916 major_inc
= params
->x_inc
;
917 minor_inc
= (dib
->stride
* params
->y_inc
) / 2;
921 major_inc
= (dib
->stride
* params
->y_inc
) / 2;
922 minor_inc
= params
->x_inc
;
927 do_rop_16( ptr
, and, xor );
928 if (err
+ params
->bias
> 0)
931 err
+= params
->err_add_1
;
933 else err
+= params
->err_add_2
;
938 static void solid_line_8(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
939 DWORD
and, DWORD
xor)
941 BYTE
*ptr
= get_pixel_ptr_8( dib
, start
->x
, start
->y
);
942 int len
= params
->length
, err
= params
->err_start
;
943 int major_inc
, minor_inc
;
947 major_inc
= params
->x_inc
;
948 minor_inc
= dib
->stride
* params
->y_inc
;
952 major_inc
= dib
->stride
* params
->y_inc
;
953 minor_inc
= params
->x_inc
;
958 do_rop_8( ptr
, and, xor );
959 if (err
+ params
->bias
> 0)
962 err
+= params
->err_add_1
;
964 else err
+= params
->err_add_2
;
969 static void solid_line_4(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
970 DWORD
and, DWORD
xor)
972 BYTE
*ptr
= get_pixel_ptr_4( dib
, start
->x
, start
->y
);
973 int len
= params
->length
, err
= params
->err_start
;
974 int x
= dib
->rect
.left
+ start
->x
;
976 and = (and & 0x0f) | ((and << 4) & 0xf0);
977 xor = (xor & 0x0f) | ((xor << 4) & 0xf0);
983 do_rop_mask_8( ptr
, and, xor, pixel_masks_4
[ x
% 2 ] );
984 if (err
+ params
->bias
> 0)
986 ptr
+= dib
->stride
* params
->y_inc
;
987 err
+= params
->err_add_1
;
989 else err
+= params
->err_add_2
;
990 if ((x
/ 2) != ((x
+ params
->x_inc
) / 2))
991 ptr
+= params
->x_inc
;
999 do_rop_mask_8( ptr
, and, xor, pixel_masks_4
[ x
% 2 ] );
1000 if (err
+ params
->bias
> 0)
1002 if ((x
/ 2) != ((x
+ params
->x_inc
) / 2))
1003 ptr
+= params
->x_inc
;
1005 err
+= params
->err_add_1
;
1007 else err
+= params
->err_add_2
;
1008 ptr
+= dib
->stride
* params
->y_inc
;
1013 static void solid_line_1(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
1014 DWORD
and, DWORD
xor)
1016 BYTE
*ptr
= get_pixel_ptr_1( dib
, start
->x
, start
->y
);
1017 int len
= params
->length
, err
= params
->err_start
;
1018 int x
= dib
->rect
.left
+ start
->x
;
1020 and = (and & 0x1) ? 0xff : 0;
1021 xor = (xor & 0x1) ? 0xff : 0;
1023 if (params
->x_major
)
1027 do_rop_mask_8( ptr
, and, xor, pixel_masks_1
[ x
% 8 ] );
1028 if (err
+ params
->bias
> 0)
1030 ptr
+= dib
->stride
* params
->y_inc
;
1031 err
+= params
->err_add_1
;
1033 else err
+= params
->err_add_2
;
1034 if ((x
/ 8) != ((x
+ params
->x_inc
) / 8))
1035 ptr
+= params
->x_inc
;
1043 do_rop_mask_8( ptr
, and, xor, pixel_masks_1
[ x
% 8 ] );
1044 if (err
+ params
->bias
> 0)
1046 if ((x
/ 8) != ((x
+ params
->x_inc
) / 8))
1047 ptr
+= params
->x_inc
;
1049 err
+= params
->err_add_1
;
1051 else err
+= params
->err_add_2
;
1052 ptr
+= dib
->stride
* params
->y_inc
;
1057 static void solid_line_null(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
1058 DWORD
and, DWORD
xor)
1063 static inline INT
calc_offset(INT edge
, INT size
, INT origin
)
1067 if(edge
- origin
>= 0)
1068 offset
= (edge
- origin
) % size
;
1071 offset
= (origin
- edge
) % size
;
1072 if(offset
) offset
= size
- offset
;
1077 static inline POINT
calc_brush_offset(const RECT
*rc
, const dib_info
*brush
, const POINT
*origin
)
1081 offset
.x
= calc_offset(rc
->left
, brush
->width
, origin
->x
);
1082 offset
.y
= calc_offset(rc
->top
, brush
->height
, origin
->y
);
1087 static void pattern_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1088 const dib_info
*brush
, const rop_mask_bits
*bits
)
1090 DWORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
1091 int x
, y
, i
, len
, brush_x
;
1094 for(i
= 0; i
< num
; i
++, rc
++)
1096 offset
= calc_brush_offset(rc
, brush
, origin
);
1097 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
1098 start_xor
= (DWORD
*)bits
->xor + offset
.y
* brush
->stride
/ 4;
1102 start_and
= (DWORD
*)bits
->and + offset
.y
* brush
->stride
/ 4;
1104 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
1106 and_ptr
= start_and
+ offset
.x
;
1107 xor_ptr
= start_xor
+ offset
.x
;
1109 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
1111 do_rop_32(ptr
++, *and_ptr
++, *xor_ptr
++);
1112 if(and_ptr
== start_and
+ brush
->width
)
1114 and_ptr
= start_and
;
1115 xor_ptr
= start_xor
;
1120 if(offset
.y
== brush
->height
)
1122 start_and
= bits
->and;
1123 start_xor
= bits
->xor;
1128 start_and
+= brush
->stride
/ 4;
1129 start_xor
+= brush
->stride
/ 4;
1135 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
1137 for (x
= rc
->left
, brush_x
= offset
.x
; x
< rc
->right
; x
+= len
)
1139 len
= min( rc
->right
- x
, brush
->width
- brush_x
);
1140 memcpy( start
+ x
- rc
->left
, start_xor
+ brush_x
, len
* 4 );
1144 start_xor
+= brush
->stride
/ 4;
1146 if(offset
.y
== brush
->height
)
1148 start_xor
= bits
->xor;
1156 static void pattern_rects_24(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1157 const dib_info
*brush
, const rop_mask_bits
*bits
)
1159 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
1160 int x
, y
, i
, len
, brush_x
;
1163 for(i
= 0; i
< num
; i
++, rc
++)
1165 offset
= calc_brush_offset(rc
, brush
, origin
);
1167 start
= get_pixel_ptr_24(dib
, rc
->left
, rc
->top
);
1168 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
1172 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
1173 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1175 and_ptr
= start_and
+ offset
.x
* 3;
1176 xor_ptr
= start_xor
+ offset
.x
* 3;
1178 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
1180 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
1181 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
1182 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
1183 if(and_ptr
== start_and
+ brush
->width
* 3)
1185 and_ptr
= start_and
;
1186 xor_ptr
= start_xor
;
1191 if(offset
.y
== brush
->height
)
1193 start_and
= bits
->and;
1194 start_xor
= bits
->xor;
1199 start_and
+= brush
->stride
;
1200 start_xor
+= brush
->stride
;
1206 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1208 for (x
= rc
->left
, brush_x
= offset
.x
; x
< rc
->right
; x
+= len
)
1210 len
= min( rc
->right
- x
, brush
->width
- brush_x
);
1211 memcpy( start
+ (x
- rc
->left
) * 3, start_xor
+ brush_x
* 3, len
* 3 );
1215 start_xor
+= brush
->stride
;
1217 if(offset
.y
== brush
->height
)
1219 start_xor
= bits
->xor;
1227 static void pattern_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1228 const dib_info
*brush
, const rop_mask_bits
*bits
)
1230 WORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
1231 int x
, y
, i
, len
, brush_x
;
1234 for(i
= 0; i
< num
; i
++, rc
++)
1236 offset
= calc_brush_offset(rc
, brush
, origin
);
1238 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
1239 start_xor
= (WORD
*)bits
->xor + offset
.y
* brush
->stride
/ 2;
1243 start_and
= (WORD
*)bits
->and + offset
.y
* brush
->stride
/ 2;
1244 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
1246 and_ptr
= start_and
+ offset
.x
;
1247 xor_ptr
= start_xor
+ offset
.x
;
1249 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
1251 do_rop_16(ptr
++, *and_ptr
++, *xor_ptr
++);
1252 if(and_ptr
== start_and
+ brush
->width
)
1254 and_ptr
= start_and
;
1255 xor_ptr
= start_xor
;
1260 if(offset
.y
== brush
->height
)
1262 start_and
= bits
->and;
1263 start_xor
= bits
->xor;
1268 start_and
+= brush
->stride
/ 2;
1269 start_xor
+= brush
->stride
/ 2;
1275 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
1277 for (x
= rc
->left
, brush_x
= offset
.x
; x
< rc
->right
; x
+= len
)
1279 len
= min( rc
->right
- x
, brush
->width
- brush_x
);
1280 memcpy( start
+ x
- rc
->left
, start_xor
+ brush_x
, len
* 2 );
1284 start_xor
+= brush
->stride
/ 2;
1286 if(offset
.y
== brush
->height
)
1288 start_xor
= bits
->xor;
1296 static void pattern_rects_8(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1297 const dib_info
*brush
, const rop_mask_bits
*bits
)
1299 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
1300 int x
, y
, i
, len
, brush_x
;
1303 for(i
= 0; i
< num
; i
++, rc
++)
1305 offset
= calc_brush_offset(rc
, brush
, origin
);
1307 start
= get_pixel_ptr_8(dib
, rc
->left
, rc
->top
);
1308 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
1312 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
1313 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1315 and_ptr
= start_and
+ offset
.x
;
1316 xor_ptr
= start_xor
+ offset
.x
;
1318 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
1320 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
1321 if(and_ptr
== start_and
+ brush
->width
)
1323 and_ptr
= start_and
;
1324 xor_ptr
= start_xor
;
1329 if(offset
.y
== brush
->height
)
1331 start_and
= bits
->and;
1332 start_xor
= bits
->xor;
1337 start_and
+= brush
->stride
;
1338 start_xor
+= brush
->stride
;
1344 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1346 for (x
= rc
->left
, brush_x
= offset
.x
; x
< rc
->right
; x
+= len
)
1348 len
= min( rc
->right
- x
, brush
->width
- brush_x
);
1349 memcpy( start
+ x
- rc
->left
, start_xor
+ brush_x
, len
);
1353 start_xor
+= brush
->stride
;
1355 if(offset
.y
== brush
->height
)
1357 start_xor
= bits
->xor;
1365 static void pattern_rects_4(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1366 const dib_info
*brush
, const rop_mask_bits
*bits
)
1368 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
1369 int x
, y
, i
, left
, right
;
1372 for(i
= 0; i
< num
; i
++, rc
++)
1374 offset
= calc_brush_offset(rc
, brush
, origin
);
1375 left
= dib
->rect
.left
+ rc
->left
;
1376 right
= dib
->rect
.left
+ rc
->right
;
1378 start
= get_pixel_ptr_4(dib
, rc
->left
, rc
->top
);
1379 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
1383 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
1384 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1386 INT brush_x
= offset
.x
;
1387 BYTE byte_and
, byte_xor
;
1389 and_ptr
= start_and
+ brush_x
/ 2;
1390 xor_ptr
= start_xor
+ brush_x
/ 2;
1392 for(x
= left
, ptr
= start
; x
< right
; x
++)
1394 /* FIXME: Two pixels at a time */
1395 if(x
& 1) /* lower dst nibble */
1397 if(brush_x
& 1) /* lower pat nibble */
1399 byte_and
= *and_ptr
++ | 0xf0;
1400 byte_xor
= *xor_ptr
++ & 0x0f;
1402 else /* upper pat nibble */
1404 byte_and
= (*and_ptr
>> 4) | 0xf0;
1405 byte_xor
= (*xor_ptr
>> 4) & 0x0f;
1408 else /* upper dst nibble */
1410 if(brush_x
& 1) /* lower pat nibble */
1412 byte_and
= (*and_ptr
++ << 4) | 0x0f;
1413 byte_xor
= (*xor_ptr
++ << 4) & 0xf0;
1415 else /* upper pat nibble */
1417 byte_and
= *and_ptr
| 0x0f;
1418 byte_xor
= *xor_ptr
& 0xf0;
1421 do_rop_8(ptr
, byte_and
, byte_xor
);
1425 if(++brush_x
== brush
->width
)
1428 and_ptr
= start_and
;
1429 xor_ptr
= start_xor
;
1434 if(offset
.y
== brush
->height
)
1436 start_and
= bits
->and;
1437 start_xor
= bits
->xor;
1442 start_and
+= brush
->stride
;
1443 start_xor
+= brush
->stride
;
1449 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1451 INT brush_x
= offset
.x
;
1454 xor_ptr
= start_xor
+ brush_x
/ 2;
1456 for(x
= left
, ptr
= start
; x
< right
; x
++)
1458 /* FIXME: Two pixels at a time */
1459 if(x
& 1) /* lower dst nibble */
1461 if(brush_x
& 1) /* lower pat nibble */
1462 byte_xor
= *xor_ptr
++ & 0x0f;
1463 else /* upper pat nibble */
1464 byte_xor
= (*xor_ptr
>> 4) & 0x0f;
1465 do_rop_8(ptr
, 0xf0, byte_xor
);
1467 else /* upper dst nibble */
1469 if(brush_x
& 1) /* lower pat nibble */
1470 byte_xor
= (*xor_ptr
++ << 4) & 0xf0;
1471 else /* upper pat nibble */
1472 byte_xor
= *xor_ptr
& 0xf0;
1473 do_rop_8(ptr
, 0x0f, byte_xor
);
1478 if(++brush_x
== brush
->width
)
1481 xor_ptr
= start_xor
;
1485 start_xor
+= brush
->stride
;
1487 if(offset
.y
== brush
->height
)
1489 start_xor
= bits
->xor;
1497 static void pattern_rects_1(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1498 const dib_info
*brush
, const rop_mask_bits
*bits
)
1500 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
1501 int x
, y
, i
, left
, right
;
1504 for(i
= 0; i
< num
; i
++, rc
++)
1506 offset
= calc_brush_offset(rc
, brush
, origin
);
1507 left
= dib
->rect
.left
+ rc
->left
;
1508 right
= dib
->rect
.left
+ rc
->right
;
1510 start
= get_pixel_ptr_1(dib
, rc
->left
, rc
->top
);
1511 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
1515 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
1516 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1518 INT brush_x
= offset
.x
;
1519 BYTE byte_and
, byte_xor
;
1521 and_ptr
= start_and
+ brush_x
/ 8;
1522 xor_ptr
= start_xor
+ brush_x
/ 8;
1524 for(x
= left
, ptr
= start
; x
< right
; x
++)
1526 byte_and
= (*and_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
1527 byte_and
|= ~pixel_masks_1
[x
% 8];
1528 byte_xor
= (*xor_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
1529 byte_xor
&= pixel_masks_1
[x
% 8];
1531 do_rop_8(ptr
, byte_and
, byte_xor
);
1533 if((x
& 7) == 7) ptr
++;
1535 if((brush_x
& 7) == 7)
1541 if(++brush_x
== brush
->width
)
1544 and_ptr
= start_and
;
1545 xor_ptr
= start_xor
;
1550 if(offset
.y
== brush
->height
)
1552 start_and
= bits
->and;
1553 start_xor
= bits
->xor;
1558 start_and
+= brush
->stride
;
1559 start_xor
+= brush
->stride
;
1565 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1567 INT brush_x
= offset
.x
;
1569 xor_ptr
= start_xor
+ brush_x
/ 8;
1571 for(x
= left
, ptr
= start
; x
< right
; x
++)
1573 BYTE byte_xor
= (*xor_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
1574 byte_xor
&= pixel_masks_1
[x
% 8];
1576 do_rop_8(ptr
, ~pixel_masks_1
[x
% 8], byte_xor
);
1578 if((x
& 7) == 7) ptr
++;
1579 if((brush_x
& 7) == 7) xor_ptr
++;
1581 if(++brush_x
== brush
->width
)
1584 xor_ptr
= start_xor
;
1588 start_xor
+= brush
->stride
;
1590 if(offset
.y
== brush
->height
)
1592 start_xor
= bits
->xor;
1600 static void pattern_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1601 const dib_info
*brush
, const rop_mask_bits
*bits
)
1606 static inline void copy_rect_bits_32( DWORD
*dst_start
, const DWORD
*src_start
, const SIZE
*size
,
1607 int dst_stride
, int src_stride
, int rop2
)
1613 #define LOOP( op ) \
1614 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1615 for (x = 0, src = src_start, dst = dst_start; x < size->cx; x++, src++, dst++) \
1620 ROPS_WITHOUT_COPY( dst
[0], src
[0] )
1625 static inline void copy_rect_bits_rev_32( DWORD
*dst_start
, const DWORD
*src_start
, const SIZE
*size
,
1626 int dst_stride
, int src_stride
, int rop2
)
1632 src_start
+= size
->cx
- 1;
1633 dst_start
+= size
->cx
- 1;
1635 #define LOOP( op ) \
1636 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1637 for (x = 0, src = src_start, dst = dst_start; x < size->cx; x++, src--, dst--) \
1642 ROPS_WITHOUT_COPY( dst
[0], src
[0] )
1647 static void copy_rect_32(const dib_info
*dst
, const RECT
*rc
,
1648 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1650 DWORD
*dst_start
, *src_start
;
1651 int y
, dst_stride
, src_stride
;
1654 if (overlap
& OVERLAP_BELOW
)
1656 dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->bottom
- 1);
1657 src_start
= get_pixel_ptr_32(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1658 dst_stride
= -dst
->stride
/ 4;
1659 src_stride
= -src
->stride
/ 4;
1663 dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->top
);
1664 src_start
= get_pixel_ptr_32(src
, origin
->x
, origin
->y
);
1665 dst_stride
= dst
->stride
/ 4;
1666 src_stride
= src
->stride
/ 4;
1669 if (rop2
== R2_COPYPEN
)
1671 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1672 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 4 );
1676 size
.cx
= rc
->right
- rc
->left
;
1677 size
.cy
= rc
->bottom
- rc
->top
;
1679 if (overlap
& OVERLAP_RIGHT
)
1680 copy_rect_bits_rev_32( dst_start
, src_start
, &size
, dst_stride
, src_stride
, rop2
);
1682 copy_rect_bits_32( dst_start
, src_start
, &size
, dst_stride
, src_stride
, rop2
);
1685 static void copy_rect_24(const dib_info
*dst
, const RECT
*rc
,
1686 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1688 BYTE
*dst_start
, *src_start
;
1689 int y
, dst_stride
, src_stride
;
1690 struct rop_codes codes
;
1692 if (overlap
& OVERLAP_BELOW
)
1694 dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->bottom
- 1);
1695 src_start
= get_pixel_ptr_24(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1696 dst_stride
= -dst
->stride
;
1697 src_stride
= -src
->stride
;
1701 dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->top
);
1702 src_start
= get_pixel_ptr_24(src
, origin
->x
, origin
->y
);
1703 dst_stride
= dst
->stride
;
1704 src_stride
= src
->stride
;
1707 if (rop2
== R2_COPYPEN
)
1709 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1710 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 3 );
1714 get_rop_codes( rop2
, &codes
);
1715 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1717 if (overlap
& OVERLAP_RIGHT
)
1718 do_rop_codes_line_rev_8( dst_start
, src_start
, &codes
, (rc
->right
- rc
->left
) * 3 );
1720 do_rop_codes_line_8( dst_start
, src_start
, &codes
, (rc
->right
- rc
->left
) * 3 );
1724 static void copy_rect_16(const dib_info
*dst
, const RECT
*rc
,
1725 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1727 WORD
*dst_start
, *src_start
;
1728 int y
, dst_stride
, src_stride
;
1729 struct rop_codes codes
;
1731 if (overlap
& OVERLAP_BELOW
)
1733 dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->bottom
- 1);
1734 src_start
= get_pixel_ptr_16(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1735 dst_stride
= -dst
->stride
/ 2;
1736 src_stride
= -src
->stride
/ 2;
1740 dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->top
);
1741 src_start
= get_pixel_ptr_16(src
, origin
->x
, origin
->y
);
1742 dst_stride
= dst
->stride
/ 2;
1743 src_stride
= src
->stride
/ 2;
1746 if (rop2
== R2_COPYPEN
)
1748 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1749 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 2 );
1753 get_rop_codes( rop2
, &codes
);
1754 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1756 if (overlap
& OVERLAP_RIGHT
)
1757 do_rop_codes_line_rev_16( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1759 do_rop_codes_line_16( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1763 static void copy_rect_8(const dib_info
*dst
, const RECT
*rc
,
1764 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1766 BYTE
*dst_start
, *src_start
;
1767 int y
, dst_stride
, src_stride
;
1768 struct rop_codes codes
;
1770 if (overlap
& OVERLAP_BELOW
)
1772 dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->bottom
- 1);
1773 src_start
= get_pixel_ptr_8(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1774 dst_stride
= -dst
->stride
;
1775 src_stride
= -src
->stride
;
1779 dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->top
);
1780 src_start
= get_pixel_ptr_8(src
, origin
->x
, origin
->y
);
1781 dst_stride
= dst
->stride
;
1782 src_stride
= src
->stride
;
1785 if (rop2
== R2_COPYPEN
)
1787 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1788 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) );
1792 get_rop_codes( rop2
, &codes
);
1793 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1795 if (overlap
& OVERLAP_RIGHT
)
1796 do_rop_codes_line_rev_8( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1798 do_rop_codes_line_8( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1802 static void copy_rect_4(const dib_info
*dst
, const RECT
*rc
,
1803 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1805 BYTE
*dst_start
, *src_start
;
1806 int y
, dst_stride
, src_stride
;
1807 struct rop_codes codes
;
1808 int left
= dst
->rect
.left
+ rc
->left
;
1809 int right
= dst
->rect
.left
+ rc
->right
;
1810 int org_x
= src
->rect
.left
+ origin
->x
;
1812 if (overlap
& OVERLAP_BELOW
)
1814 dst_start
= get_pixel_ptr_4(dst
, rc
->left
, rc
->bottom
- 1);
1815 src_start
= get_pixel_ptr_4(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1816 dst_stride
= -dst
->stride
;
1817 src_stride
= -src
->stride
;
1821 dst_start
= get_pixel_ptr_4(dst
, rc
->left
, rc
->top
);
1822 src_start
= get_pixel_ptr_4(src
, origin
->x
, origin
->y
);
1823 dst_stride
= dst
->stride
;
1824 src_stride
= src
->stride
;
1827 if (rop2
== R2_COPYPEN
&& (left
& 1) == 0 && (org_x
& 1) == 0 && (right
& 1) == 0)
1829 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1830 memmove( dst_start
, src_start
, (right
- left
) / 2 );
1834 get_rop_codes( rop2
, &codes
);
1835 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1837 if (overlap
& OVERLAP_RIGHT
)
1838 do_rop_codes_line_rev_4( dst_start
, left
& 1, src_start
, org_x
& 1, &codes
, right
- left
);
1840 do_rop_codes_line_4( dst_start
, left
& 1, src_start
, org_x
& 1, &codes
, right
- left
);
1844 static void copy_rect_1(const dib_info
*dst
, const RECT
*rc
,
1845 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1847 BYTE
*dst_start
, *src_start
;
1848 int y
, dst_stride
, src_stride
;
1849 struct rop_codes codes
;
1850 int left
= dst
->rect
.left
+ rc
->left
;
1851 int right
= dst
->rect
.left
+ rc
->right
;
1852 int org_x
= src
->rect
.left
+ origin
->x
;
1854 if (overlap
& OVERLAP_BELOW
)
1856 dst_start
= get_pixel_ptr_1(dst
, rc
->left
, rc
->bottom
- 1);
1857 src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1858 dst_stride
= -dst
->stride
;
1859 src_stride
= -src
->stride
;
1863 dst_start
= get_pixel_ptr_1(dst
, rc
->left
, rc
->top
);
1864 src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
1865 dst_stride
= dst
->stride
;
1866 src_stride
= src
->stride
;
1869 if (rop2
== R2_COPYPEN
&& (left
& 7) == 0 && (org_x
& 7) == 0 && (right
& 7) == 0)
1871 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1872 memmove( dst_start
, src_start
, (right
- left
) / 8 );
1876 get_rop_codes( rop2
, &codes
);
1877 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1879 if (overlap
& OVERLAP_RIGHT
)
1880 do_rop_codes_line_rev_1( dst_start
, left
& 7, src_start
, org_x
& 7, &codes
, right
- left
, rop2
);
1882 do_rop_codes_line_1( dst_start
, left
& 7, src_start
, org_x
& 7, &codes
, right
- left
, rop2
);
1886 static void copy_rect_null(const dib_info
*dst
, const RECT
*rc
,
1887 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1892 static DWORD
get_pixel_32(const dib_info
*dib
, int x
, int y
)
1894 DWORD
*ptr
= get_pixel_ptr_32( dib
, x
, y
);
1898 static DWORD
get_pixel_24(const dib_info
*dib
, int x
, int y
)
1900 BYTE
*ptr
= get_pixel_ptr_24( dib
, x
, y
);
1901 return ptr
[0] | ((DWORD
)ptr
[1] << 8) | ((DWORD
)ptr
[2] << 16);
1904 static DWORD
get_pixel_16(const dib_info
*dib
, int x
, int y
)
1906 WORD
*ptr
= get_pixel_ptr_16( dib
, x
, y
);
1910 static DWORD
get_pixel_8(const dib_info
*dib
, int x
, int y
)
1912 BYTE
*ptr
= get_pixel_ptr_8( dib
, x
, y
);
1916 static DWORD
get_pixel_4(const dib_info
*dib
, int x
, int y
)
1918 BYTE
*ptr
= get_pixel_ptr_4( dib
, x
, y
);
1920 if ((dib
->rect
.left
+ x
) & 1)
1923 return (*ptr
>> 4) & 0x0f;
1926 static DWORD
get_pixel_1(const dib_info
*dib
, int x
, int y
)
1928 BYTE
*ptr
= get_pixel_ptr_1( dib
, x
, y
);
1929 return (*ptr
& pixel_masks_1
[(dib
->rect
.left
+ x
) & 7]) ? 1 : 0;
1932 static DWORD
get_pixel_null(const dib_info
*dib
, int x
, int y
)
1937 static DWORD
colorref_to_pixel_888(const dib_info
*dib
, COLORREF color
)
1939 return ( ((color
>> 16) & 0xff) | (color
& 0xff00) | ((color
<< 16) & 0xff0000) );
1942 static const DWORD field_masks
[33] =
1944 0x00, /* should never happen */
1945 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff,
1946 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1947 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1948 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1951 static inline DWORD
get_field(DWORD field
, int shift
, int len
)
1953 shift
= shift
- (8 - len
);
1958 field
&= field_masks
[len
];
1959 field
|= field
>> len
;
1963 static inline DWORD
put_field(DWORD field
, int shift
, int len
)
1965 shift
= shift
- (8 - len
);
1966 field
&= field_masks
[len
];
1974 static DWORD
colorref_to_pixel_masks(const dib_info
*dib
, COLORREF colour
)
1978 r
= GetRValue(colour
);
1979 g
= GetGValue(colour
);
1980 b
= GetBValue(colour
);
1982 return put_field(r
, dib
->red_shift
, dib
->red_len
) |
1983 put_field(g
, dib
->green_shift
, dib
->green_len
) |
1984 put_field(b
, dib
->blue_shift
, dib
->blue_len
);
1987 static DWORD
colorref_to_pixel_555(const dib_info
*dib
, COLORREF color
)
1989 return ( ((color
>> 19) & 0x1f) | ((color
>> 6) & 0x03e0) | ((color
<< 7) & 0x7c00) );
1992 static DWORD
rgb_to_pixel_colortable(const dib_info
*dib
, BYTE r
, BYTE g
, BYTE b
)
1994 const RGBQUAD
*color_table
= get_dib_color_table( dib
);
1995 int size
= dib
->color_table
? dib
->color_table_size
: 1 << dib
->bit_count
;
1996 int i
, best_index
= 0;
1997 DWORD diff
, best_diff
= 0xffffffff;
1999 /* special case for conversion to 1-bpp without a color table:
2000 * we get a 1-entry table containing the background color
2002 if (dib
->bit_count
== 1 && size
== 1)
2003 return (r
== color_table
[0].rgbRed
&&
2004 g
== color_table
[0].rgbGreen
&&
2005 b
== color_table
[0].rgbBlue
);
2007 for(i
= 0; i
< size
; i
++)
2009 const RGBQUAD
*cur
= color_table
+ i
;
2010 diff
= (r
- cur
->rgbRed
) * (r
- cur
->rgbRed
)
2011 + (g
- cur
->rgbGreen
) * (g
- cur
->rgbGreen
)
2012 + (b
- cur
->rgbBlue
) * (b
- cur
->rgbBlue
);
2020 if(diff
< best_diff
)
2029 static DWORD
rgb_to_pixel_mono(const dib_info
*dib
, BOOL dither
, int x
, int y
, BYTE r
, BYTE g
, BYTE b
)
2034 ret
= rgb_to_pixel_colortable( dib
, r
, g
, b
);
2036 ret
= ((30 * r
+ 59 * g
+ 11 * b
) / 100 + bayer_16x16
[y
% 16][x
% 16]) > 255;
2038 return ret
? 0xff : 0;
2041 static DWORD
colorref_to_pixel_colortable(const dib_info
*dib
, COLORREF color
)
2043 return rgb_to_pixel_colortable( dib
, GetRValue(color
), GetGValue(color
), GetBValue(color
) );
2046 static DWORD
colorref_to_pixel_null(const dib_info
*dib
, COLORREF color
)
2051 static COLORREF
pixel_to_colorref_888(const dib_info
*dib
, DWORD pixel
)
2053 return ( ((pixel
>> 16) & 0xff) | (pixel
& 0xff00) | ((pixel
<< 16) & 0xff0000) );
2056 static COLORREF
pixel_to_colorref_masks(const dib_info
*dib
, DWORD pixel
)
2058 return RGB( get_field( pixel
, dib
->red_shift
, dib
->red_len
),
2059 get_field( pixel
, dib
->green_shift
, dib
->green_len
),
2060 get_field( pixel
, dib
->blue_shift
, dib
->blue_len
) );
2063 static COLORREF
pixel_to_colorref_555(const dib_info
*dib
, DWORD pixel
)
2065 return RGB( ((pixel
>> 7) & 0xf8) | ((pixel
>> 12) & 0x07),
2066 ((pixel
>> 2) & 0xf8) | ((pixel
>> 7) & 0x07),
2067 ((pixel
<< 3) & 0xf8) | ((pixel
>> 2) & 0x07) );
2070 static COLORREF
pixel_to_colorref_colortable(const dib_info
*dib
, DWORD pixel
)
2072 const RGBQUAD
*color_table
= get_dib_color_table( dib
);
2074 if (!dib
->color_table
|| pixel
< dib
->color_table_size
)
2076 RGBQUAD quad
= color_table
[pixel
];
2077 return RGB( quad
.rgbRed
, quad
.rgbGreen
, quad
.rgbBlue
);
2082 static COLORREF
pixel_to_colorref_null(const dib_info
*dib
, DWORD pixel
)
2087 static inline BOOL
bit_fields_match(const dib_info
*d1
, const dib_info
*d2
)
2089 assert( d1
->bit_count
> 8 && d1
->bit_count
== d2
->bit_count
);
2091 return d1
->red_mask
== d2
->red_mask
&&
2092 d1
->green_mask
== d2
->green_mask
&&
2093 d1
->blue_mask
== d2
->blue_mask
;
2096 static void convert_to_8888(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2098 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
2099 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
2101 switch(src
->bit_count
)
2105 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2106 if(src
->funcs
== &funcs_8888
)
2108 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2109 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2112 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2114 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
2115 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2116 dst_start
+= dst
->stride
/ 4;
2117 src_start
+= src
->stride
/ 4;
2121 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2123 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2125 dst_pixel
= dst_start
;
2126 src_pixel
= src_start
;
2127 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2129 src_val
= *src_pixel
++;
2130 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << 16) |
2131 (((src_val
>> src
->green_shift
) & 0xff) << 8) |
2132 ((src_val
>> src
->blue_shift
) & 0xff);
2134 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2135 dst_start
+= dst
->stride
/ 4;
2136 src_start
+= src
->stride
/ 4;
2141 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2143 dst_pixel
= dst_start
;
2144 src_pixel
= src_start
;
2145 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2147 src_val
= *src_pixel
++;
2148 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
2149 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
2150 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
2152 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2153 dst_start
+= dst
->stride
/ 4;
2154 src_start
+= src
->stride
/ 4;
2162 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2164 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2166 dst_pixel
= dst_start
;
2167 src_pixel
= src_start
;
2168 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2171 rgb
.rgbBlue
= *src_pixel
++;
2172 rgb
.rgbGreen
= *src_pixel
++;
2173 rgb
.rgbRed
= *src_pixel
++;
2175 *dst_pixel
++ = ((rgb
.rgbRed
<< 16) & 0xff0000) | ((rgb
.rgbGreen
<< 8) & 0x00ff00) | (rgb
.rgbBlue
& 0x0000ff);
2177 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2178 dst_start
+= dst
->stride
/ 4;
2179 src_start
+= src
->stride
;
2186 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2187 if(src
->funcs
== &funcs_555
)
2189 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2191 dst_pixel
= dst_start
;
2192 src_pixel
= src_start
;
2193 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2195 src_val
= *src_pixel
++;
2196 *dst_pixel
++ = ((src_val
<< 9) & 0xf80000) | ((src_val
<< 4) & 0x070000) |
2197 ((src_val
<< 6) & 0x00f800) | ((src_val
<< 1) & 0x000700) |
2198 ((src_val
<< 3) & 0x0000f8) | ((src_val
>> 2) & 0x000007);
2200 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2201 dst_start
+= dst
->stride
/ 4;
2202 src_start
+= src
->stride
/ 2;
2205 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2207 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2209 dst_pixel
= dst_start
;
2210 src_pixel
= src_start
;
2211 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2213 src_val
= *src_pixel
++;
2214 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
2215 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
2216 (((src_val
>> src
->green_shift
) << 11) & 0x00f800) |
2217 (((src_val
>> src
->green_shift
) << 6) & 0x000700) |
2218 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
2219 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
2221 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2222 dst_start
+= dst
->stride
/ 4;
2223 src_start
+= src
->stride
/ 2;
2226 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2228 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2230 dst_pixel
= dst_start
;
2231 src_pixel
= src_start
;
2232 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2234 src_val
= *src_pixel
++;
2235 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
2236 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
2237 (((src_val
>> src
->green_shift
) << 10) & 0x00fc00) |
2238 (((src_val
>> src
->green_shift
) << 4) & 0x000300) |
2239 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
2240 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
2242 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2243 dst_start
+= dst
->stride
/ 4;
2244 src_start
+= src
->stride
/ 2;
2249 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2251 dst_pixel
= dst_start
;
2252 src_pixel
= src_start
;
2253 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2255 src_val
= *src_pixel
++;
2256 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
2257 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
2258 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
2260 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2261 dst_start
+= dst
->stride
/ 4;
2262 src_start
+= src
->stride
/ 2;
2270 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2271 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2272 DWORD dst_colors
[256], i
;
2274 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
2275 dst_colors
[i
] = color_table
[i
].rgbRed
<< 16 | color_table
[i
].rgbGreen
<< 8 |
2276 color_table
[i
].rgbBlue
;
2278 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2280 dst_pixel
= dst_start
;
2281 src_pixel
= src_start
;
2282 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2283 *dst_pixel
++ = dst_colors
[*src_pixel
++];
2285 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2286 dst_start
+= dst
->stride
/ 4;
2287 src_start
+= src
->stride
;
2294 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2295 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2296 DWORD dst_colors
[16], i
;
2298 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
2299 dst_colors
[i
] = color_table
[i
].rgbRed
<< 16 | color_table
[i
].rgbGreen
<< 8 |
2300 color_table
[i
].rgbBlue
;
2302 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2304 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2305 src_pixel
= src_start
;
2306 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2309 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
2311 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
2313 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2314 dst_start
+= dst
->stride
/ 4;
2315 src_start
+= src
->stride
;
2322 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2323 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2324 DWORD dst_colors
[2], i
;
2326 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
2327 dst_colors
[i
] = color_table
[i
].rgbRed
<< 16 | color_table
[i
].rgbGreen
<< 8 |
2328 color_table
[i
].rgbBlue
;
2330 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2332 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2333 for(x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2335 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2336 dst_start
[x
] = dst_colors
[src_val
];
2338 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2339 dst_start
+= dst
->stride
/ 4;
2340 src_start
+= src
->stride
;
2347 static void convert_to_32(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2349 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
2350 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
2352 switch(src
->bit_count
)
2356 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2358 if(src
->funcs
== &funcs_8888
)
2360 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2362 dst_pixel
= dst_start
;
2363 src_pixel
= src_start
;
2364 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2366 src_val
= *src_pixel
++;
2367 *dst_pixel
++ = put_field(src_val
>> 16, dst
->red_shift
, dst
->red_len
) |
2368 put_field(src_val
>> 8, dst
->green_shift
, dst
->green_len
) |
2369 put_field(src_val
, dst
->blue_shift
, dst
->blue_len
);
2371 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2372 dst_start
+= dst
->stride
/ 4;
2373 src_start
+= src
->stride
/ 4;
2376 else if(bit_fields_match(src
, dst
))
2378 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2379 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2382 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2384 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
2385 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2386 dst_start
+= dst
->stride
/ 4;
2387 src_start
+= src
->stride
/ 4;
2391 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8 &&
2392 dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
2394 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2396 dst_pixel
= dst_start
;
2397 src_pixel
= src_start
;
2398 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2400 src_val
= *src_pixel
++;
2401 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << dst
->red_shift
) |
2402 (((src_val
>> src
->green_shift
) & 0xff) << dst
->green_shift
) |
2403 (((src_val
>> src
->blue_shift
) & 0xff) << dst
->blue_shift
);
2405 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2406 dst_start
+= dst
->stride
/ 4;
2407 src_start
+= src
->stride
/ 4;
2412 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2414 dst_pixel
= dst_start
;
2415 src_pixel
= src_start
;
2416 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2418 src_val
= *src_pixel
++;
2419 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
2420 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
2421 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
2423 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2424 dst_start
+= dst
->stride
/ 4;
2425 src_start
+= src
->stride
/ 4;
2433 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2435 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2437 dst_pixel
= dst_start
;
2438 src_pixel
= src_start
;
2439 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2442 rgb
.rgbBlue
= *src_pixel
++;
2443 rgb
.rgbGreen
= *src_pixel
++;
2444 rgb
.rgbRed
= *src_pixel
++;
2446 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2447 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2448 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2450 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2451 dst_start
+= dst
->stride
/ 4;
2452 src_start
+= src
->stride
;
2459 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2460 if(src
->funcs
== &funcs_555
)
2462 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2464 dst_pixel
= dst_start
;
2465 src_pixel
= src_start
;
2466 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2468 src_val
= *src_pixel
++;
2469 *dst_pixel
++ = put_field(((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07), dst
->red_shift
, dst
->red_len
) |
2470 put_field(((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07), dst
->green_shift
, dst
->green_len
) |
2471 put_field(((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2473 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2474 dst_start
+= dst
->stride
/ 4;
2475 src_start
+= src
->stride
/ 2;
2478 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2480 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2482 dst_pixel
= dst_start
;
2483 src_pixel
= src_start
;
2484 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2486 src_val
= *src_pixel
++;
2487 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2488 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
2489 put_field( (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2490 (((src_val
>> src
->green_shift
) >> 2) & 0x07), dst
->green_shift
, dst
->green_len
) |
2491 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2492 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2494 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2495 dst_start
+= dst
->stride
/ 4;
2496 src_start
+= src
->stride
/ 2;
2499 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2501 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2503 dst_pixel
= dst_start
;
2504 src_pixel
= src_start
;
2505 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2507 src_val
= *src_pixel
++;
2508 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2509 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
2510 put_field( (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2511 (((src_val
>> src
->green_shift
) >> 4) & 0x03), dst
->green_shift
, dst
->green_len
) |
2512 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2513 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2515 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2516 dst_start
+= dst
->stride
/ 4;
2517 src_start
+= src
->stride
/ 2;
2522 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2524 dst_pixel
= dst_start
;
2525 src_pixel
= src_start
;
2526 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2528 src_val
= *src_pixel
++;
2529 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
2530 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
2531 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
2533 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2534 dst_start
+= dst
->stride
/ 4;
2535 src_start
+= src
->stride
/ 2;
2543 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2544 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2545 DWORD dst_colors
[256], i
;
2547 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
2549 RGBQUAD rgb
= color_table
[i
];
2550 dst_colors
[i
] = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2551 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2552 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2555 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2557 dst_pixel
= dst_start
;
2558 src_pixel
= src_start
;
2559 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2560 *dst_pixel
++ = dst_colors
[*src_pixel
++];
2562 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2563 dst_start
+= dst
->stride
/ 4;
2564 src_start
+= src
->stride
;
2571 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2572 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2573 DWORD dst_colors
[16], i
;
2575 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
2577 RGBQUAD rgb
= color_table
[i
];
2578 dst_colors
[i
] = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2579 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2580 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2583 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2585 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2586 src_pixel
= src_start
;
2587 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2590 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
2592 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
2594 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2595 dst_start
+= dst
->stride
/ 4;
2596 src_start
+= src
->stride
;
2603 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2604 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2605 DWORD dst_colors
[2], i
;
2607 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
2609 RGBQUAD rgb
= color_table
[i
];
2610 dst_colors
[i
] = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2611 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2612 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2615 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2617 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2618 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2620 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2621 dst_start
[x
] = dst_colors
[src_val
];
2623 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2624 dst_start
+= dst
->stride
/ 4;
2625 src_start
+= src
->stride
;
2632 static void convert_to_24(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2634 BYTE
*dst_start
= get_pixel_ptr_24(dst
, 0, 0), *dst_pixel
;
2636 int x
, y
, pad_size
= ((dst
->width
* 3 + 3) & ~3) - (src_rect
->right
- src_rect
->left
) * 3;
2638 switch(src
->bit_count
)
2642 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2643 if(src
->funcs
== &funcs_8888
)
2645 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2647 dst_pixel
= dst_start
;
2648 src_pixel
= src_start
;
2649 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2651 src_val
= *src_pixel
++;
2652 *dst_pixel
++ = src_val
& 0xff;
2653 *dst_pixel
++ = (src_val
>> 8) & 0xff;
2654 *dst_pixel
++ = (src_val
>> 16) & 0xff;
2656 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2657 dst_start
+= dst
->stride
;
2658 src_start
+= src
->stride
/ 4;
2661 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2663 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2665 dst_pixel
= dst_start
;
2666 src_pixel
= src_start
;
2667 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2669 src_val
= *src_pixel
++;
2670 *dst_pixel
++ = (src_val
>> src
->blue_shift
) & 0xff;
2671 *dst_pixel
++ = (src_val
>> src
->green_shift
) & 0xff;
2672 *dst_pixel
++ = (src_val
>> src
->red_shift
) & 0xff;
2674 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2675 dst_start
+= dst
->stride
;
2676 src_start
+= src
->stride
/ 4;
2681 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2683 dst_pixel
= dst_start
;
2684 src_pixel
= src_start
;
2685 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2687 src_val
= *src_pixel
++;
2688 *dst_pixel
++ = get_field( src_val
, src
->blue_shift
, src
->blue_len
);
2689 *dst_pixel
++ = get_field( src_val
, src
->green_shift
, src
->green_len
);
2690 *dst_pixel
++ = get_field( src_val
, src
->red_shift
, src
->red_len
);
2692 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2693 dst_start
+= dst
->stride
;
2694 src_start
+= src
->stride
/ 4;
2702 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
);
2704 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2705 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2708 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2710 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 3);
2711 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
) * 3, 0, pad_size
);
2712 dst_start
+= dst
->stride
;
2713 src_start
+= src
->stride
;
2721 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2722 if(src
->funcs
== &funcs_555
)
2724 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2726 dst_pixel
= dst_start
;
2727 src_pixel
= src_start
;
2728 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2730 src_val
= *src_pixel
++;
2731 *dst_pixel
++ = ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07);
2732 *dst_pixel
++ = ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07);
2733 *dst_pixel
++ = ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07);
2735 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2736 dst_start
+= dst
->stride
;
2737 src_start
+= src
->stride
/ 2;
2740 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2742 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2744 dst_pixel
= dst_start
;
2745 src_pixel
= src_start
;
2746 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2748 src_val
= *src_pixel
++;
2749 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2750 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
2751 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2752 (((src_val
>> src
->green_shift
) >> 2) & 0x07);
2753 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2754 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
2756 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2757 dst_start
+= dst
->stride
;
2758 src_start
+= src
->stride
/ 2;
2761 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2763 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2765 dst_pixel
= dst_start
;
2766 src_pixel
= src_start
;
2767 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2769 src_val
= *src_pixel
++;
2770 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2771 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
2772 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2773 (((src_val
>> src
->green_shift
) >> 4) & 0x03);
2774 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2775 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
2777 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2778 dst_start
+= dst
->stride
;
2779 src_start
+= src
->stride
/ 2;
2784 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2786 dst_pixel
= dst_start
;
2787 src_pixel
= src_start
;
2788 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2790 src_val
= *src_pixel
++;
2791 *dst_pixel
++ = get_field(src_val
, src
->blue_shift
, src
->blue_len
);
2792 *dst_pixel
++ = get_field(src_val
, src
->green_shift
, src
->green_len
);
2793 *dst_pixel
++ = get_field(src_val
, src
->red_shift
, src
->red_len
);
2795 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2796 dst_start
+= dst
->stride
;
2797 src_start
+= src
->stride
/ 2;
2805 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2806 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2807 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2809 dst_pixel
= dst_start
;
2810 src_pixel
= src_start
;
2811 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2813 RGBQUAD rgb
= color_table
[*src_pixel
++];
2814 *dst_pixel
++ = rgb
.rgbBlue
;
2815 *dst_pixel
++ = rgb
.rgbGreen
;
2816 *dst_pixel
++ = rgb
.rgbRed
;
2818 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2819 dst_start
+= dst
->stride
;
2820 src_start
+= src
->stride
;
2827 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2828 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2829 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2831 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2832 src_pixel
= src_start
;
2833 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2837 rgb
= color_table
[*src_pixel
++ & 0xf];
2839 rgb
= color_table
[*src_pixel
>> 4];
2840 dst_start
[x
* 3] = rgb
.rgbBlue
;
2841 dst_start
[x
* 3 + 1] = rgb
.rgbGreen
;
2842 dst_start
[x
* 3 + 2] = rgb
.rgbRed
;
2844 if(pad_size
) memset(dst_start
+ x
* 3, 0, pad_size
);
2845 dst_start
+= dst
->stride
;
2846 src_start
+= src
->stride
;
2853 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2854 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2855 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2857 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2858 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2861 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2862 rgb
= color_table
[src_val
];
2863 dst_start
[x
* 3] = rgb
.rgbBlue
;
2864 dst_start
[x
* 3 + 1] = rgb
.rgbGreen
;
2865 dst_start
[x
* 3 + 2] = rgb
.rgbRed
;
2867 if(pad_size
) memset(dst_start
+ x
* 3, 0, pad_size
);
2868 dst_start
+= dst
->stride
;
2869 src_start
+= src
->stride
;
2876 static void convert_to_555(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2878 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
2879 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
2882 switch(src
->bit_count
)
2886 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2888 if(src
->funcs
== &funcs_8888
)
2890 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2892 dst_pixel
= dst_start
;
2893 src_pixel
= src_start
;
2894 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2896 src_val
= *src_pixel
++;
2897 *dst_pixel
++ = ((src_val
>> 9) & 0x7c00) |
2898 ((src_val
>> 6) & 0x03e0) |
2899 ((src_val
>> 3) & 0x001f);
2901 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2902 dst_start
+= dst
->stride
/ 2;
2903 src_start
+= src
->stride
/ 4;
2906 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2908 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2910 dst_pixel
= dst_start
;
2911 src_pixel
= src_start
;
2912 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2914 src_val
= *src_pixel
++;
2915 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 7) & 0x7c00) |
2916 (((src_val
>> src
->green_shift
) << 2) & 0x03e0) |
2917 (((src_val
>> src
->blue_shift
) >> 3) & 0x001f);
2919 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2920 dst_start
+= dst
->stride
/ 2;
2921 src_start
+= src
->stride
/ 4;
2926 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2928 dst_pixel
= dst_start
;
2929 src_pixel
= src_start
;
2930 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2932 src_val
= *src_pixel
++;
2933 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
2934 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
2935 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
2937 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2938 dst_start
+= dst
->stride
/ 2;
2939 src_start
+= src
->stride
/ 4;
2947 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2949 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2951 dst_pixel
= dst_start
;
2952 src_pixel
= src_start
;
2953 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2956 rgb
.rgbBlue
= *src_pixel
++;
2957 rgb
.rgbGreen
= *src_pixel
++;
2958 rgb
.rgbRed
= *src_pixel
++;
2960 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2961 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2962 ((rgb
.rgbBlue
>> 3) & 0x001f);
2964 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2965 dst_start
+= dst
->stride
/ 2;
2966 src_start
+= src
->stride
;
2973 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2974 if(src
->funcs
== &funcs_555
)
2976 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2977 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2980 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2982 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
2983 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2984 dst_start
+= dst
->stride
/ 2;
2985 src_start
+= src
->stride
/ 2;
2989 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2991 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2993 dst_pixel
= dst_start
;
2994 src_pixel
= src_start
;
2995 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2997 src_val
= *src_pixel
++;
2998 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
2999 (((src_val
>> src
->green_shift
) << 5) & 0x03e0) |
3000 ( (src_val
>> src
->blue_shift
) & 0x001f);
3002 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3003 dst_start
+= dst
->stride
/ 2;
3004 src_start
+= src
->stride
/ 2;
3007 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3009 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3011 dst_pixel
= dst_start
;
3012 src_pixel
= src_start
;
3013 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3015 src_val
= *src_pixel
++;
3016 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
3017 (((src_val
>> src
->green_shift
) << 4) & 0x03e0) |
3018 ( (src_val
>> src
->blue_shift
) & 0x001f);
3020 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3021 dst_start
+= dst
->stride
/ 2;
3022 src_start
+= src
->stride
/ 2;
3027 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3029 dst_pixel
= dst_start
;
3030 src_pixel
= src_start
;
3031 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3033 src_val
= *src_pixel
++;
3034 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
3035 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
3036 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
3038 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3039 dst_start
+= dst
->stride
/ 2;
3040 src_start
+= src
->stride
/ 2;
3048 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3049 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3050 WORD dst_colors
[256];
3053 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3054 dst_colors
[i
] = ((color_table
[i
].rgbRed
<< 7) & 0x7c00) |
3055 ((color_table
[i
].rgbGreen
<< 2) & 0x03e0) |
3056 ((color_table
[i
].rgbBlue
>> 3) & 0x001f);
3058 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3060 dst_pixel
= dst_start
;
3061 src_pixel
= src_start
;
3062 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3063 *dst_pixel
++ = dst_colors
[*src_pixel
++];
3065 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3066 dst_start
+= dst
->stride
/ 2;
3067 src_start
+= src
->stride
;
3074 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3075 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3076 WORD dst_colors
[16];
3079 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3080 dst_colors
[i
] = ((color_table
[i
].rgbRed
<< 7) & 0x7c00) |
3081 ((color_table
[i
].rgbGreen
<< 2) & 0x03e0) |
3082 ((color_table
[i
].rgbBlue
>> 3) & 0x001f);
3084 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3086 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3087 src_pixel
= src_start
;
3088 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3091 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
3093 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
3095 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3096 dst_start
+= dst
->stride
/ 2;
3097 src_start
+= src
->stride
;
3104 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3105 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3109 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3110 dst_colors
[i
] = ((color_table
[i
].rgbRed
<< 7) & 0x7c00) |
3111 ((color_table
[i
].rgbGreen
<< 2) & 0x03e0) |
3112 ((color_table
[i
].rgbBlue
>> 3) & 0x001f);
3114 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3116 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3117 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3119 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3120 dst_start
[x
] = dst_colors
[src_val
];
3122 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3123 dst_start
+= dst
->stride
/ 2;
3124 src_start
+= src
->stride
;
3131 static void convert_to_16(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3133 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
3134 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
3137 switch(src
->bit_count
)
3141 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3143 if(src
->funcs
== &funcs_8888
)
3145 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3147 dst_pixel
= dst_start
;
3148 src_pixel
= src_start
;
3149 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3151 src_val
= *src_pixel
++;
3152 *dst_pixel
++ = put_field(src_val
>> 16, dst
->red_shift
, dst
->red_len
) |
3153 put_field(src_val
>> 8, dst
->green_shift
, dst
->green_len
) |
3154 put_field(src_val
, dst
->blue_shift
, dst
->blue_len
);
3156 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3157 dst_start
+= dst
->stride
/ 2;
3158 src_start
+= src
->stride
/ 4;
3161 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3163 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3165 dst_pixel
= dst_start
;
3166 src_pixel
= src_start
;
3167 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3169 src_val
= *src_pixel
++;
3170 *dst_pixel
++ = put_field(src_val
>> src
->red_shift
, dst
->red_shift
, dst
->red_len
) |
3171 put_field(src_val
>> src
->green_shift
, dst
->green_shift
, dst
->green_len
) |
3172 put_field(src_val
>> src
->blue_shift
, dst
->blue_shift
, dst
->blue_len
);
3174 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3175 dst_start
+= dst
->stride
/ 2;
3176 src_start
+= src
->stride
/ 4;
3181 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3183 dst_pixel
= dst_start
;
3184 src_pixel
= src_start
;
3185 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3187 src_val
= *src_pixel
++;
3188 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
3189 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
3190 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
3192 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3193 dst_start
+= dst
->stride
/ 2;
3194 src_start
+= src
->stride
/ 4;
3202 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3204 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3206 dst_pixel
= dst_start
;
3207 src_pixel
= src_start
;
3208 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3211 rgb
.rgbBlue
= *src_pixel
++;
3212 rgb
.rgbGreen
= *src_pixel
++;
3213 rgb
.rgbRed
= *src_pixel
++;
3215 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
3216 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
3217 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
3219 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3220 dst_start
+= dst
->stride
/ 2;
3221 src_start
+= src
->stride
;
3228 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3229 if(src
->funcs
== &funcs_555
)
3231 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3233 dst_pixel
= dst_start
;
3234 src_pixel
= src_start
;
3235 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3237 src_val
= *src_pixel
++;
3238 *dst_pixel
++ = put_field(((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07), dst
->red_shift
, dst
->red_len
) |
3239 put_field(((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07), dst
->green_shift
, dst
->green_len
) |
3240 put_field(((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
3242 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3243 dst_start
+= dst
->stride
/ 2;
3244 src_start
+= src
->stride
/ 2;
3247 else if(bit_fields_match(src
, dst
))
3249 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
3250 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3253 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3255 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
3256 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
3257 dst_start
+= dst
->stride
/ 2;
3258 src_start
+= src
->stride
/ 2;
3262 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3264 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3266 dst_pixel
= dst_start
;
3267 src_pixel
= src_start
;
3268 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3270 src_val
= *src_pixel
++;
3271 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3272 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
3273 put_field( (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3274 (((src_val
>> src
->green_shift
) >> 2) & 0x07), dst
->green_shift
, dst
->green_len
) |
3275 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3276 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
3278 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3279 dst_start
+= dst
->stride
/ 2;
3280 src_start
+= src
->stride
/ 2;
3283 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3285 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3287 dst_pixel
= dst_start
;
3288 src_pixel
= src_start
;
3289 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3291 src_val
= *src_pixel
++;
3292 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3293 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
3294 put_field( (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3295 (((src_val
>> src
->green_shift
) >> 4) & 0x03), dst
->green_shift
, dst
->green_len
) |
3296 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3297 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
3299 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3300 dst_start
+= dst
->stride
/ 2;
3301 src_start
+= src
->stride
/ 2;
3306 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3308 dst_pixel
= dst_start
;
3309 src_pixel
= src_start
;
3310 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3312 src_val
= *src_pixel
++;
3313 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
3314 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
3315 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
3317 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3318 dst_start
+= dst
->stride
/ 2;
3319 src_start
+= src
->stride
/ 2;
3327 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3328 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3329 WORD dst_colors
[256];
3332 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3334 RGBQUAD rgb
= color_table
[i
];
3335 dst_colors
[i
] = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
3336 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
3337 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
3340 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3342 dst_pixel
= dst_start
;
3343 src_pixel
= src_start
;
3344 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3345 *dst_pixel
++ = dst_colors
[*src_pixel
++];
3347 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3348 dst_start
+= dst
->stride
/ 2;
3349 src_start
+= src
->stride
;
3356 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3357 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3358 WORD dst_colors
[16];
3361 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3363 RGBQUAD rgb
= color_table
[i
];
3364 dst_colors
[i
] = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
3365 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
3366 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
3369 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3371 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3372 src_pixel
= src_start
;
3373 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3376 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
3378 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
3380 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3381 dst_start
+= dst
->stride
/ 2;
3382 src_start
+= src
->stride
;
3389 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3390 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3394 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3396 RGBQUAD rgb
= color_table
[i
];
3397 dst_colors
[i
] = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
3398 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
3399 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
3402 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3404 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3405 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3407 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3408 dst_start
[x
] = dst_colors
[src_val
];
3410 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3411 dst_start
+= dst
->stride
/ 2;
3412 src_start
+= src
->stride
;
3419 static inline BOOL
color_tables_match(const dib_info
*d1
, const dib_info
*d2
)
3421 if (!d1
->color_table
|| !d2
->color_table
) return (!d1
->color_table
&& !d2
->color_table
);
3422 return !memcmp(d1
->color_table
, d2
->color_table
, (1 << d1
->bit_count
) * sizeof(d1
->color_table
[0]));
3425 static inline DWORD
rgb_lookup_colortable(const dib_info
*dst
, BYTE r
, BYTE g
, BYTE b
)
3427 /* Windows reduces precision to 5 bits, probably in order to build some sort of lookup cache */
3428 return rgb_to_pixel_colortable( dst
, (r
& ~7) + 4, (g
& ~7) + 4, (b
& ~7) + 4 );
3431 static void convert_to_8(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3433 BYTE
*dst_start
= get_pixel_ptr_8(dst
, 0, 0), *dst_pixel
;
3434 INT x
, y
, pad_size
= ((dst
->width
+ 3) & ~3) - (src_rect
->right
- src_rect
->left
);
3437 switch(src
->bit_count
)
3441 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3443 if(src
->funcs
== &funcs_8888
)
3445 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3447 dst_pixel
= dst_start
;
3448 src_pixel
= src_start
;
3449 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3451 src_val
= *src_pixel
++;
3452 *dst_pixel
++ = rgb_lookup_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
3454 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3455 dst_start
+= dst
->stride
;
3456 src_start
+= src
->stride
/ 4;
3459 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3461 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3463 dst_pixel
= dst_start
;
3464 src_pixel
= src_start
;
3465 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3467 src_val
= *src_pixel
++;
3468 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3469 src_val
>> src
->red_shift
,
3470 src_val
>> src
->green_shift
,
3471 src_val
>> src
->blue_shift
);
3473 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3474 dst_start
+= dst
->stride
;
3475 src_start
+= src
->stride
/ 4;
3480 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3482 dst_pixel
= dst_start
;
3483 src_pixel
= src_start
;
3484 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3486 src_val
= *src_pixel
++;
3487 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3488 get_field(src_val
, src
->red_shift
, src
->red_len
),
3489 get_field(src_val
, src
->green_shift
, src
->green_len
),
3490 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3492 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3493 dst_start
+= dst
->stride
;
3494 src_start
+= src
->stride
/ 4;
3502 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3504 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3506 dst_pixel
= dst_start
;
3507 src_pixel
= src_start
;
3508 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3510 *dst_pixel
++ = rgb_lookup_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0] );
3512 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3513 dst_start
+= dst
->stride
;
3514 src_start
+= src
->stride
;
3521 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3522 if(src
->funcs
== &funcs_555
)
3524 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3526 dst_pixel
= dst_start
;
3527 src_pixel
= src_start
;
3528 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3530 src_val
= *src_pixel
++;
3531 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3532 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3533 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3534 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
3536 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3537 dst_start
+= dst
->stride
;
3538 src_start
+= src
->stride
/ 2;
3541 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3543 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3545 dst_pixel
= dst_start
;
3546 src_pixel
= src_start
;
3547 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3549 src_val
= *src_pixel
++;
3550 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3551 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3552 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3553 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3554 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3555 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3556 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3558 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3559 dst_start
+= dst
->stride
;
3560 src_start
+= src
->stride
/ 2;
3563 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3565 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3567 dst_pixel
= dst_start
;
3568 src_pixel
= src_start
;
3569 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3571 src_val
= *src_pixel
++;
3572 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3573 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3574 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3575 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3576 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3577 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3578 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3580 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3581 dst_start
+= dst
->stride
;
3582 src_start
+= src
->stride
/ 2;
3587 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3589 dst_pixel
= dst_start
;
3590 src_pixel
= src_start
;
3591 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3593 src_val
= *src_pixel
++;
3594 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3595 get_field(src_val
, src
->red_shift
, src
->red_len
),
3596 get_field(src_val
, src
->green_shift
, src
->green_len
),
3597 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3599 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3600 dst_start
+= dst
->stride
;
3601 src_start
+= src
->stride
/ 2;
3609 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3611 if(color_tables_match(dst
, src
))
3613 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
3614 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3617 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3619 memcpy(dst_start
, src_start
, src_rect
->right
- src_rect
->left
);
3620 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
3621 dst_start
+= dst
->stride
;
3622 src_start
+= src
->stride
;
3628 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3629 BYTE dst_colors
[256];
3632 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3634 RGBQUAD rgb
= color_table
[i
];
3635 dst_colors
[i
] = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3638 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3640 dst_pixel
= dst_start
;
3641 src_pixel
= src_start
;
3642 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3643 *dst_pixel
++ = dst_colors
[*src_pixel
++];
3645 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3646 dst_start
+= dst
->stride
;
3647 src_start
+= src
->stride
;
3655 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3656 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3657 BYTE dst_colors
[16];
3660 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3662 RGBQUAD rgb
= color_table
[i
];
3663 dst_colors
[i
] = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3666 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3668 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3669 src_pixel
= src_start
;
3670 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3673 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
3675 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
3677 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3678 dst_start
+= dst
->stride
;
3679 src_start
+= src
->stride
;
3686 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3687 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3691 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3693 RGBQUAD rgb
= color_table
[i
];
3694 dst_colors
[i
] = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3697 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3699 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3700 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3702 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3703 dst_start
[x
] = dst_colors
[src_val
];
3705 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3706 dst_start
+= dst
->stride
;
3707 src_start
+= src
->stride
;
3714 static void convert_to_4(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3716 BYTE
*dst_start
= get_pixel_ptr_4(dst
, 0, 0), *dst_pixel
, dst_val
;
3717 INT x
, y
, pad_size
= ((dst
->width
+ 7) & ~7) / 2 - (src_rect
->right
- src_rect
->left
+ 1) / 2;
3720 switch(src
->bit_count
)
3724 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3726 if(src
->funcs
== &funcs_8888
)
3728 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3730 dst_pixel
= dst_start
;
3731 src_pixel
= src_start
;
3732 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3734 src_val
= *src_pixel
++;
3735 dst_val
= rgb_to_pixel_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
3736 if((x
- src_rect
->left
) & 1)
3738 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3742 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3746 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3747 memset(dst_pixel
, 0, pad_size
);
3749 dst_start
+= dst
->stride
;
3750 src_start
+= src
->stride
/ 4;
3753 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3755 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3757 dst_pixel
= dst_start
;
3758 src_pixel
= src_start
;
3759 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3761 src_val
= *src_pixel
++;
3762 dst_val
= rgb_to_pixel_colortable(dst
,
3763 src_val
>> src
->red_shift
,
3764 src_val
>> src
->green_shift
,
3765 src_val
>> src
->blue_shift
);
3766 if((x
- src_rect
->left
) & 1)
3768 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3772 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3776 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3777 memset(dst_pixel
, 0, pad_size
);
3779 dst_start
+= dst
->stride
;
3780 src_start
+= src
->stride
/ 4;
3785 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3787 dst_pixel
= dst_start
;
3788 src_pixel
= src_start
;
3789 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3791 src_val
= *src_pixel
++;
3792 dst_val
= rgb_to_pixel_colortable(dst
,
3793 get_field(src_val
, src
->red_shift
, src
->red_len
),
3794 get_field(src_val
, src
->green_shift
, src
->green_len
),
3795 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3796 if((x
- src_rect
->left
) & 1)
3798 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3802 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3806 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3807 memset(dst_pixel
, 0, pad_size
);
3809 dst_start
+= dst
->stride
;
3810 src_start
+= src
->stride
/ 4;
3818 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3820 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3822 dst_pixel
= dst_start
;
3823 src_pixel
= src_start
;
3824 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3826 dst_val
= rgb_to_pixel_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
3828 if((x
- src_rect
->left
) & 1)
3830 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3834 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3838 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3839 memset(dst_pixel
, 0, pad_size
);
3841 dst_start
+= dst
->stride
;
3842 src_start
+= src
->stride
;
3849 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3850 if(src
->funcs
== &funcs_555
)
3852 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3854 dst_pixel
= dst_start
;
3855 src_pixel
= src_start
;
3856 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3858 src_val
= *src_pixel
++;
3859 dst_val
= rgb_to_pixel_colortable(dst
,
3860 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3861 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3862 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
3863 if((x
- src_rect
->left
) & 1)
3865 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3869 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3873 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3874 memset(dst_pixel
, 0, pad_size
);
3876 dst_start
+= dst
->stride
;
3877 src_start
+= src
->stride
/ 2;
3880 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3882 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3884 dst_pixel
= dst_start
;
3885 src_pixel
= src_start
;
3886 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3888 src_val
= *src_pixel
++;
3889 dst_val
= rgb_to_pixel_colortable(dst
,
3890 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3891 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3892 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3893 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3894 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3895 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3896 if((x
- src_rect
->left
) & 1)
3898 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3902 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3906 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3907 memset(dst_pixel
, 0, pad_size
);
3909 dst_start
+= dst
->stride
;
3910 src_start
+= src
->stride
/ 2;
3913 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3915 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3917 dst_pixel
= dst_start
;
3918 src_pixel
= src_start
;
3919 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3921 src_val
= *src_pixel
++;
3922 dst_val
= rgb_to_pixel_colortable(dst
,
3923 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3924 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3925 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3926 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3927 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3928 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3929 if((x
- src_rect
->left
) & 1)
3931 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3935 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3939 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3940 memset(dst_pixel
, 0, pad_size
);
3942 dst_start
+= dst
->stride
;
3943 src_start
+= src
->stride
/ 2;
3948 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3950 dst_pixel
= dst_start
;
3951 src_pixel
= src_start
;
3952 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3954 src_val
= *src_pixel
++;
3955 dst_val
= rgb_to_pixel_colortable(dst
,
3956 get_field(src_val
, src
->red_shift
, src
->red_len
),
3957 get_field(src_val
, src
->green_shift
, src
->green_len
),
3958 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3959 if((x
- src_rect
->left
) & 1)
3961 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3965 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3969 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3970 memset(dst_pixel
, 0, pad_size
);
3972 dst_start
+= dst
->stride
;
3973 src_start
+= src
->stride
/ 2;
3981 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3982 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3983 BYTE dst_colors
[256];
3986 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
3988 RGBQUAD rgb
= color_table
[i
];
3989 dst_colors
[i
] = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3992 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3994 dst_pixel
= dst_start
;
3995 src_pixel
= src_start
;
3996 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3998 dst_val
= dst_colors
[*src_pixel
++];
3999 if((x
- src_rect
->left
) & 1)
4001 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4005 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4009 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4010 memset(dst_pixel
, 0, pad_size
);
4012 dst_start
+= dst
->stride
;
4013 src_start
+= src
->stride
;
4020 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4022 if(color_tables_match(dst
, src
) && ((src
->rect
.left
+ src_rect
->left
) & 1) == 0)
4024 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
4025 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
4028 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4030 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
+ 1) / 2);
4031 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
+ 1) / 2, 0, pad_size
);
4032 dst_start
+= dst
->stride
;
4033 src_start
+= src
->stride
;
4039 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4040 BYTE dst_colors
[16];
4043 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
4045 RGBQUAD rgb
= color_table
[i
];
4046 dst_colors
[i
] = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
4049 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4051 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
4052 dst_pixel
= dst_start
;
4053 src_pixel
= src_start
;
4054 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, pos
++)
4057 dst_val
= dst_colors
[*src_pixel
++ & 0xf];
4059 dst_val
= dst_colors
[*src_pixel
>> 4];
4060 if((x
- src_rect
->left
) & 1)
4062 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4066 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4070 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4071 memset(dst_pixel
, 0, pad_size
);
4073 dst_start
+= dst
->stride
;
4074 src_start
+= src
->stride
;
4082 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4083 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
4087 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
4089 RGBQUAD rgb
= color_table
[i
];
4090 dst_colors
[i
] = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
4093 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4095 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
4096 dst_pixel
= dst_start
;
4097 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, pos
++)
4099 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
4100 dst_val
= dst_colors
[src_val
];
4101 if((x
- src_rect
->left
) & 1)
4103 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4107 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4111 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4112 memset(dst_pixel
, 0, pad_size
);
4114 dst_start
+= dst
->stride
;
4115 src_start
+= src
->stride
;
4122 static void convert_to_1(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
4124 BYTE
*dst_start
= get_pixel_ptr_1(dst
, 0, 0), *dst_pixel
, dst_val
;
4125 INT x
, y
, pad_size
= ((dst
->width
+ 31) & ~31) / 8 - (src_rect
->right
- src_rect
->left
+ 7) / 8;
4129 switch(src
->bit_count
)
4133 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4135 if(src
->funcs
== &funcs_8888
)
4137 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4139 dst_pixel
= dst_start
;
4140 src_pixel
= src_start
;
4141 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4143 src_val
= *src_pixel
++;
4144 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
>> 16, src_val
>> 8, src_val
);
4146 if(bit_pos
== 0) *dst_pixel
= 0;
4147 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4157 if(bit_pos
!= 0) dst_pixel
++;
4158 memset(dst_pixel
, 0, pad_size
);
4160 dst_start
+= dst
->stride
;
4161 src_start
+= src
->stride
/ 4;
4164 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
4166 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4168 dst_pixel
= dst_start
;
4169 src_pixel
= src_start
;
4170 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4172 src_val
= *src_pixel
++;
4173 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
,
4174 src_val
>> src
->red_shift
,
4175 src_val
>> src
->green_shift
,
4176 src_val
>> src
->blue_shift
);
4178 if(bit_pos
== 0) *dst_pixel
= 0;
4179 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4189 if(bit_pos
!= 0) dst_pixel
++;
4190 memset(dst_pixel
, 0, pad_size
);
4192 dst_start
+= dst
->stride
;
4193 src_start
+= src
->stride
/ 4;
4198 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4200 dst_pixel
= dst_start
;
4201 src_pixel
= src_start
;
4202 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4204 src_val
= *src_pixel
++;
4205 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
,
4206 get_field(src_val
, src
->red_shift
, src
->red_len
),
4207 get_field(src_val
, src
->green_shift
, src
->green_len
),
4208 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
4210 if(bit_pos
== 0) *dst_pixel
= 0;
4211 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4221 if(bit_pos
!= 0) dst_pixel
++;
4222 memset(dst_pixel
, 0, pad_size
);
4224 dst_start
+= dst
->stride
;
4225 src_start
+= src
->stride
/ 4;
4233 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4235 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4237 dst_pixel
= dst_start
;
4238 src_pixel
= src_start
;
4239 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, src_pixel
+= 3)
4241 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
4243 if(bit_pos
== 0) *dst_pixel
= 0;
4244 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4254 if(bit_pos
!= 0) dst_pixel
++;
4255 memset(dst_pixel
, 0, pad_size
);
4257 dst_start
+= dst
->stride
;
4258 src_start
+= src
->stride
;
4265 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4266 if(src
->funcs
== &funcs_555
)
4268 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4270 dst_pixel
= dst_start
;
4271 src_pixel
= src_start
;
4272 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4274 src_val
= *src_pixel
++;
4275 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
,
4276 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
4277 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
4278 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07));
4280 if(bit_pos
== 0) *dst_pixel
= 0;
4281 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4291 if(bit_pos
!= 0) dst_pixel
++;
4292 memset(dst_pixel
, 0, pad_size
);
4294 dst_start
+= dst
->stride
;
4295 src_start
+= src
->stride
/ 2;
4298 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
4300 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4302 dst_pixel
= dst_start
;
4303 src_pixel
= src_start
;
4304 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4306 src_val
= *src_pixel
++;
4307 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
,
4308 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
4309 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
4310 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
4311 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
4312 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
4313 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
4314 if(bit_pos
== 0) *dst_pixel
= 0;
4315 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4325 if(bit_pos
!= 0) dst_pixel
++;
4326 memset(dst_pixel
, 0, pad_size
);
4328 dst_start
+= dst
->stride
;
4329 src_start
+= src
->stride
/ 2;
4332 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
4334 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4336 dst_pixel
= dst_start
;
4337 src_pixel
= src_start
;
4338 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4340 src_val
= *src_pixel
++;
4341 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
,
4342 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
4343 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
4344 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
4345 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
4346 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
4347 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
4348 if(bit_pos
== 0) *dst_pixel
= 0;
4349 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4359 if(bit_pos
!= 0) dst_pixel
++;
4360 memset(dst_pixel
, 0, pad_size
);
4362 dst_start
+= dst
->stride
;
4363 src_start
+= src
->stride
/ 2;
4368 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4370 dst_pixel
= dst_start
;
4371 src_pixel
= src_start
;
4372 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4374 src_val
= *src_pixel
++;
4375 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
,
4376 get_field(src_val
, src
->red_shift
, src
->red_len
),
4377 get_field(src_val
, src
->green_shift
, src
->green_len
),
4378 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
4379 if(bit_pos
== 0) *dst_pixel
= 0;
4380 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4390 if(bit_pos
!= 0) dst_pixel
++;
4391 memset(dst_pixel
, 0, pad_size
);
4393 dst_start
+= dst
->stride
;
4394 src_start
+= src
->stride
/ 2;
4402 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4403 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4405 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4407 dst_pixel
= dst_start
;
4408 src_pixel
= src_start
;
4409 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4411 RGBQUAD rgb
= color_table
[*src_pixel
++];
4412 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
4414 if(bit_pos
== 0) *dst_pixel
= 0;
4415 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4425 if(bit_pos
!= 0) dst_pixel
++;
4426 memset(dst_pixel
, 0, pad_size
);
4428 dst_start
+= dst
->stride
;
4429 src_start
+= src
->stride
;
4436 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4437 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4439 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4441 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
4442 dst_pixel
= dst_start
;
4443 src_pixel
= src_start
;
4444 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, pos
++)
4448 rgb
= color_table
[*src_pixel
++ & 0xf];
4450 rgb
= color_table
[*src_pixel
>> 4];
4451 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
4453 if(bit_pos
== 0) *dst_pixel
= 0;
4454 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4464 if(bit_pos
!= 0) dst_pixel
++;
4465 memset(dst_pixel
, 0, pad_size
);
4467 dst_start
+= dst
->stride
;
4468 src_start
+= src
->stride
;
4473 /* Note that while MSDN states that a 1 bpp dib brush -> mono dc
4474 uses text/bkgnd colours instead of the dib's colour table, this
4475 doesn't appear to be the case for a dc backed by a
4480 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4481 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
4482 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4484 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
4485 dst_pixel
= dst_start
;
4486 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, pos
++)
4489 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
4490 rgb
= color_table
[src_val
];
4491 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
4493 if(bit_pos
== 0) *dst_pixel
= 0;
4494 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4504 if(bit_pos
!= 0) dst_pixel
++;
4505 memset(dst_pixel
, 0, pad_size
);
4507 dst_start
+= dst
->stride
;
4508 src_start
+= src
->stride
;
4515 static void convert_to_null(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
4519 static inline BYTE
blend_color(BYTE dst
, BYTE src
, DWORD alpha
)
4521 return (src
* alpha
+ dst
* (255 - alpha
) + 127) / 255;
4524 static inline DWORD
blend_argb_constant_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
4526 return (blend_color( dst
, src
, alpha
) |
4527 blend_color( dst
>> 8, src
>> 8, alpha
) << 8 |
4528 blend_color( dst
>> 16, src
>> 16, alpha
) << 16 |
4529 blend_color( dst
>> 24, src
>> 24, alpha
) << 24);
4532 static inline DWORD
blend_argb_no_src_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
4534 return (blend_color( dst
, src
, alpha
) |
4535 blend_color( dst
>> 8, src
>> 8, alpha
) << 8 |
4536 blend_color( dst
>> 16, src
>> 16, alpha
) << 16 |
4537 blend_color( dst
>> 24, 255, alpha
) << 24);
4540 static inline DWORD
blend_argb( DWORD dst
, DWORD src
)
4543 BYTE g
= (BYTE
)(src
>> 8);
4544 BYTE r
= (BYTE
)(src
>> 16);
4545 DWORD alpha
= (BYTE
)(src
>> 24);
4546 return ((b
+ ((BYTE
)dst
* (255 - alpha
) + 127) / 255) |
4547 (g
+ ((BYTE
)(dst
>> 8) * (255 - alpha
) + 127) / 255) << 8 |
4548 (r
+ ((BYTE
)(dst
>> 16) * (255 - alpha
) + 127) / 255) << 16 |
4549 (alpha
+ ((BYTE
)(dst
>> 24) * (255 - alpha
) + 127) / 255) << 24);
4552 static inline DWORD
blend_argb_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
4554 BYTE b
= ((BYTE
)src
* alpha
+ 127) / 255;
4555 BYTE g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
4556 BYTE r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
4557 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
4558 return ((b
+ ((BYTE
)dst
* (255 - alpha
) + 127) / 255) |
4559 (g
+ ((BYTE
)(dst
>> 8) * (255 - alpha
) + 127) / 255) << 8 |
4560 (r
+ ((BYTE
)(dst
>> 16) * (255 - alpha
) + 127) / 255) << 16 |
4561 (alpha
+ ((BYTE
)(dst
>> 24) * (255 - alpha
) + 127) / 255) << 24);
4564 static inline DWORD
blend_rgb( BYTE dst_r
, BYTE dst_g
, BYTE dst_b
, DWORD src
, BLENDFUNCTION blend
)
4566 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
4568 DWORD alpha
= blend
.SourceConstantAlpha
;
4569 BYTE src_b
= ((BYTE
)src
* alpha
+ 127) / 255;
4570 BYTE src_g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
4571 BYTE src_r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
4572 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
4573 return ((src_b
+ (dst_b
* (255 - alpha
) + 127) / 255) |
4574 (src_g
+ (dst_g
* (255 - alpha
) + 127) / 255) << 8 |
4575 (src_r
+ (dst_r
* (255 - alpha
) + 127) / 255) << 16);
4577 return (blend_color( dst_b
, src
, blend
.SourceConstantAlpha
) |
4578 blend_color( dst_g
, src
>> 8, blend
.SourceConstantAlpha
) << 8 |
4579 blend_color( dst_r
, src
>> 16, blend
.SourceConstantAlpha
) << 16);
4582 static void blend_rect_8888(const dib_info
*dst
, const RECT
*rc
,
4583 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4585 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4586 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
4589 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
4591 if (blend
.SourceConstantAlpha
== 255)
4592 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4593 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4594 dst_ptr
[x
] = blend_argb( dst_ptr
[x
], src_ptr
[x
] );
4596 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4597 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4598 dst_ptr
[x
] = blend_argb_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
4600 else if (src
->compression
== BI_RGB
)
4601 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4602 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4603 dst_ptr
[x
] = blend_argb_constant_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
4605 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4606 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4607 dst_ptr
[x
] = blend_argb_no_src_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
4610 static void blend_rect_32(const dib_info
*dst
, const RECT
*rc
,
4611 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4613 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4614 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
4617 if (dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
4619 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4621 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4623 DWORD val
= blend_rgb( dst_ptr
[x
] >> dst
->red_shift
,
4624 dst_ptr
[x
] >> dst
->green_shift
,
4625 dst_ptr
[x
] >> dst
->blue_shift
,
4626 src_ptr
[x
], blend
);
4627 dst_ptr
[x
] = ((( val
& 0xff) << dst
->blue_shift
) |
4628 (((val
>> 8) & 0xff) << dst
->green_shift
) |
4629 (((val
>> 16) & 0xff) << dst
->red_shift
));
4635 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4637 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4639 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
4640 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
4641 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
4642 src_ptr
[x
], blend
);
4643 dst_ptr
[x
] = (put_field( val
>> 16, dst
->red_shift
, dst
->red_len
) |
4644 put_field( val
>> 8, dst
->green_shift
, dst
->green_len
) |
4645 put_field( val
, dst
->blue_shift
, dst
->blue_len
));
4651 static void blend_rect_24(const dib_info
*dst
, const RECT
*rc
,
4652 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4654 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4655 BYTE
*dst_ptr
= get_pixel_ptr_24( dst
, rc
->left
, rc
->top
);
4658 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4660 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4662 DWORD val
= blend_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
4663 src_ptr
[x
], blend
);
4664 dst_ptr
[x
* 3] = val
;
4665 dst_ptr
[x
* 3 + 1] = val
>> 8;
4666 dst_ptr
[x
* 3 + 2] = val
>> 16;
4671 static void blend_rect_555(const dib_info
*dst
, const RECT
*rc
,
4672 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4674 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4675 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
4678 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
4680 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4682 DWORD val
= blend_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
4683 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
4684 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
4685 src_ptr
[x
], blend
);
4686 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
4691 static void blend_rect_16(const dib_info
*dst
, const RECT
*rc
,
4692 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4694 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4695 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
4698 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
4700 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4702 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
4703 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
4704 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
4705 src_ptr
[x
], blend
);
4706 dst_ptr
[x
] = (put_field((val
>> 16), dst
->red_shift
, dst
->red_len
) |
4707 put_field((val
>> 8), dst
->green_shift
, dst
->green_len
) |
4708 put_field( val
, dst
->blue_shift
, dst
->blue_len
));
4713 static void blend_rect_8(const dib_info
*dst
, const RECT
*rc
,
4714 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4716 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4717 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4718 BYTE
*dst_ptr
= get_pixel_ptr_8( dst
, rc
->left
, rc
->top
);
4721 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4723 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4725 RGBQUAD rgb
= color_table
[dst_ptr
[x
]];
4726 DWORD val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[x
], blend
);
4727 dst_ptr
[x
] = rgb_lookup_colortable( dst
, val
>> 16, val
>> 8, val
);
4732 static void blend_rect_4(const dib_info
*dst
, const RECT
*rc
,
4733 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4735 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4736 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4737 BYTE
*dst_ptr
= get_pixel_ptr_4( dst
, rc
->left
, rc
->top
);
4740 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4742 for (i
= 0, x
= (dst
->rect
.left
+ rc
->left
) & 1; i
< rc
->right
- rc
->left
; i
++, x
++)
4744 DWORD val
= ((x
& 1) ? dst_ptr
[x
/ 2] : (dst_ptr
[x
/ 2] >> 4)) & 0x0f;
4745 RGBQUAD rgb
= color_table
[val
];
4746 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[i
], blend
);
4747 val
= rgb_lookup_colortable( dst
, val
>> 16, val
>> 8, val
);
4749 dst_ptr
[x
/ 2] = val
| (dst_ptr
[x
/ 2] & 0xf0);
4751 dst_ptr
[x
/ 2] = (val
<< 4) | (dst_ptr
[x
/ 2] & 0x0f);
4756 static void blend_rect_1(const dib_info
*dst
, const RECT
*rc
,
4757 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4759 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4760 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4761 BYTE
*dst_ptr
= get_pixel_ptr_1( dst
, rc
->left
, rc
->top
);
4764 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4766 for (i
= 0, x
= (dst
->rect
.left
+ rc
->left
) & 7; i
< rc
->right
- rc
->left
; i
++, x
++)
4768 DWORD val
= (dst_ptr
[x
/ 8] & pixel_masks_1
[x
% 8]) ? 1 : 0;
4769 RGBQUAD rgb
= color_table
[val
];
4770 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[i
], blend
);
4771 val
= rgb_to_pixel_colortable(dst
, val
>> 16, val
>> 8, val
) ? 0xff : 0;
4772 dst_ptr
[x
/ 8] = (dst_ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (val
& pixel_masks_1
[x
% 8]);
4777 static void blend_rect_null(const dib_info
*dst
, const RECT
*rc
,
4778 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4782 static inline DWORD
gradient_rgb_8888( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
)
4785 r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 256;
4786 g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 256;
4787 b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 256;
4788 a
= (v
[0].Alpha
* (len
- pos
) + v
[1].Alpha
* pos
) / len
/ 256;
4789 return a
<< 24 | r
<< 16 | g
<< 8 | b
;
4792 static inline DWORD
gradient_rgb_24( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
)
4795 r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 256;
4796 g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 256;
4797 b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 256;
4798 return r
<< 16 | g
<< 8 | b
;
4801 static inline WORD
gradient_rgb_555( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
,
4802 unsigned int x
, unsigned int y
)
4804 int r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4805 int g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4806 int b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4807 r
= min( 31, max( 0, r
/ 16 ));
4808 g
= min( 31, max( 0, g
/ 16 ));
4809 b
= min( 31, max( 0, b
/ 16 ));
4810 return (r
<< 10) | (g
<< 5) | b
;
4813 static inline BYTE
gradient_rgb_8( const dib_info
*dib
, const TRIVERTEX
*v
,
4814 unsigned int pos
, unsigned int len
, unsigned int x
, unsigned int y
)
4816 BYTE r
= ((v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4817 BYTE g
= ((v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4818 BYTE b
= ((v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4819 return rgb_to_pixel_colortable( dib
, r
* 127, g
* 127, b
* 127 );
4822 /* compute the left/right triangle limit for row y */
4823 static inline void triangle_coords( const TRIVERTEX
*v
, const RECT
*rc
, int y
, int *left
, int *right
)
4827 if (y
< v
[1].y
) x1
= edge_coord( y
, v
[0].x
, v
[0].y
, v
[1].x
, v
[1].y
);
4828 else x1
= edge_coord( y
, v
[1].x
, v
[1].y
, v
[2].x
, v
[2].y
);
4830 x2
= edge_coord( y
, v
[0].x
, v
[0].y
, v
[2].x
, v
[2].y
);
4832 *left
= max( rc
->left
, min( x1
, x2
) );
4833 *right
= min( rc
->right
, max( x1
, x2
) );
4836 /* compute the matrix determinant for triangular barycentric coordinates (constant across the triangle) */
4837 static inline int triangle_det( const TRIVERTEX
*v
)
4839 return (v
[2].y
- v
[1].y
) * (v
[2].x
- v
[0].x
) - (v
[2].x
- v
[1].x
) * (v
[2].y
- v
[0].y
);
4842 /* compute the barycentric weights for a given point inside the triangle */
4843 static inline void triangle_weights( const TRIVERTEX
*v
, int x
, int y
, INT64
*l1
, INT64
*l2
)
4845 *l1
= (v
[1].y
- v
[2].y
) * (x
- v
[2].x
) - (v
[1].x
- v
[2].x
) * (y
- v
[2].y
);
4846 *l2
= (v
[2].y
- v
[0].y
) * (x
- v
[2].x
) - (v
[2].x
- v
[0].x
) * (y
- v
[2].y
);
4849 static inline DWORD
gradient_triangle_8888( const TRIVERTEX
*v
, int x
, int y
, int det
)
4854 triangle_weights( v
, x
, y
, &l1
, &l2
);
4855 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 256;
4856 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 256;
4857 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 256;
4858 a
= (v
[0].Alpha
* l1
+ v
[1].Alpha
* l2
+ v
[2].Alpha
* (det
- l1
- l2
)) / det
/ 256;
4859 return a
<< 24 | r
<< 16 | g
<< 8 | b
;
4862 static inline DWORD
gradient_triangle_24( const TRIVERTEX
*v
, int x
, int y
, int det
)
4867 triangle_weights( v
, x
, y
, &l1
, &l2
);
4868 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 256;
4869 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 256;
4870 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 256;
4871 return r
<< 16 | g
<< 8 | b
;
4874 static inline DWORD
gradient_triangle_555( const TRIVERTEX
*v
, int x
, int y
, int det
)
4879 triangle_weights( v
, x
, y
, &l1
, &l2
);
4880 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4881 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4882 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4883 r
= min( 31, max( 0, r
/ 16 ));
4884 g
= min( 31, max( 0, g
/ 16 ));
4885 b
= min( 31, max( 0, b
/ 16 ));
4886 return (r
<< 10) | (g
<< 5) | b
;
4889 static inline DWORD
gradient_triangle_8( const dib_info
*dib
, const TRIVERTEX
*v
, int x
, int y
, int det
)
4894 triangle_weights( v
, x
, y
, &l1
, &l2
);
4895 r
= ((v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4896 g
= ((v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4897 b
= ((v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4898 return rgb_to_pixel_colortable( dib
, r
* 127, g
* 127, b
* 127 );
4901 static BOOL
gradient_rect_8888( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4903 DWORD
*ptr
= get_pixel_ptr_32( dib
, rc
->left
, rc
->top
);
4904 int x
, y
, left
, right
, det
;
4908 case GRADIENT_FILL_RECT_H
:
4909 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4910 ptr
[x
] = gradient_rgb_8888( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
4912 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4913 memcpy( ptr
+ dib
->stride
/ 4, ptr
, (rc
->right
- rc
->left
) * 4 );
4916 case GRADIENT_FILL_RECT_V
:
4917 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4919 DWORD val
= gradient_rgb_8888( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4920 memset_32( ptr
, val
, rc
->right
- rc
->left
);
4924 case GRADIENT_FILL_TRIANGLE
:
4925 if (!(det
= triangle_det( v
))) return FALSE
;
4926 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4928 triangle_coords( v
, rc
, y
, &left
, &right
);
4929 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_8888( v
, x
, y
, det
);
4936 static BOOL
gradient_rect_32( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4938 DWORD
*ptr
= get_pixel_ptr_32( dib
, rc
->left
, rc
->top
);
4939 int x
, y
, left
, right
, det
;
4943 case GRADIENT_FILL_RECT_H
:
4944 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
4946 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4948 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
4949 ptr
[x
] = ((( val
& 0xff) << dib
->blue_shift
) |
4950 (((val
>> 8) & 0xff) << dib
->green_shift
) |
4951 (((val
>> 16) & 0xff) << dib
->red_shift
));
4956 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4958 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
4959 ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4960 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4961 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4965 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4966 memcpy( ptr
+ dib
->stride
/ 4, ptr
, (rc
->right
- rc
->left
) * 4 );
4969 case GRADIENT_FILL_RECT_V
:
4970 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4972 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4973 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
4974 val
= ((( val
& 0xff) << dib
->blue_shift
) |
4975 (((val
>> 8) & 0xff) << dib
->green_shift
) |
4976 (((val
>> 16) & 0xff) << dib
->red_shift
));
4978 val
= (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4979 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4980 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4982 memset_32( ptr
, val
, rc
->right
- rc
->left
);
4986 case GRADIENT_FILL_TRIANGLE
:
4987 if (!(det
= triangle_det( v
))) return FALSE
;
4988 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4990 triangle_coords( v
, rc
, y
, &left
, &right
);
4992 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
4993 for (x
= left
; x
< right
; x
++)
4995 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
4996 ptr
[x
- rc
->left
] = ((( val
& 0xff) << dib
->blue_shift
) |
4997 (((val
>> 8) & 0xff) << dib
->green_shift
) |
4998 (((val
>> 16) & 0xff) << dib
->red_shift
));
5001 for (x
= left
; x
< right
; x
++)
5003 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
5004 ptr
[x
- rc
->left
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
5005 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
5006 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
5014 static BOOL
gradient_rect_24( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5016 BYTE
*ptr
= get_pixel_ptr_24( dib
, rc
->left
, rc
->top
);
5017 int x
, y
, left
, right
, det
;
5021 case GRADIENT_FILL_RECT_H
:
5022 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
5024 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
5026 ptr
[x
* 3 + 1] = val
>> 8;
5027 ptr
[x
* 3 + 2] = val
>> 16;
5030 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5031 memcpy( ptr
+ dib
->stride
, ptr
, (rc
->right
- rc
->left
) * 3 );
5034 case GRADIENT_FILL_RECT_V
:
5035 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5037 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
5038 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
5041 ptr
[x
* 3 + 1] = val
>> 8;
5042 ptr
[x
* 3 + 2] = val
>> 16;
5047 case GRADIENT_FILL_TRIANGLE
:
5048 if (!(det
= triangle_det( v
))) return FALSE
;
5049 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5051 triangle_coords( v
, rc
, y
, &left
, &right
);
5052 for (x
= left
; x
< right
; x
++)
5054 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
5055 ptr
[(x
- rc
->left
) * 3] = val
;
5056 ptr
[(x
- rc
->left
) * 3 + 1] = val
>> 8;
5057 ptr
[(x
- rc
->left
) * 3 + 2] = val
>> 16;
5065 static BOOL
gradient_rect_555( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5067 WORD
*ptr
= get_pixel_ptr_16( dib
, rc
->left
, rc
->top
);
5068 int x
, y
, left
, right
, det
;
5072 case GRADIENT_FILL_RECT_H
:
5073 for (y
= rc
->top
; y
< min( rc
->top
+ 4, rc
->bottom
); y
++, ptr
+= dib
->stride
/ 2)
5074 for (x
= rc
->left
; x
< rc
->right
; x
++)
5075 ptr
[x
- rc
->left
] = gradient_rgb_555( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
5076 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5077 memcpy( ptr
, ptr
- dib
->stride
* 2, (rc
->right
- rc
->left
) * 2 );
5080 case GRADIENT_FILL_RECT_V
:
5081 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5084 for (x
= 0; x
< 4; x
++) values
[x
] = gradient_rgb_555( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
5085 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 4];
5089 case GRADIENT_FILL_TRIANGLE
:
5090 if (!(det
= triangle_det( v
))) return FALSE
;
5091 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5093 triangle_coords( v
, rc
, y
, &left
, &right
);
5094 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_555( v
, x
, y
, det
);
5101 static BOOL
gradient_rect_16( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5103 WORD
*ptr
= get_pixel_ptr_16( dib
, rc
->left
, rc
->top
);
5104 int x
, y
, left
, right
, det
;
5108 case GRADIENT_FILL_RECT_H
:
5109 for (y
= rc
->top
; y
< min( rc
->top
+ 4, rc
->bottom
); y
++, ptr
+= dib
->stride
/ 2)
5110 for (x
= rc
->left
; x
< rc
->right
; x
++)
5112 WORD val
= gradient_rgb_555( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
5113 ptr
[x
- rc
->left
] = (put_field(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07), dib
->red_shift
, dib
->red_len
) |
5114 put_field(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07), dib
->green_shift
, dib
->green_len
) |
5115 put_field(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07), dib
->blue_shift
, dib
->blue_len
));
5117 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5118 memcpy( ptr
, ptr
- dib
->stride
* 2, (rc
->right
- rc
->left
) * 2 );
5121 case GRADIENT_FILL_RECT_V
:
5122 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5125 for (x
= 0; x
< 4; x
++)
5127 WORD val
= gradient_rgb_555( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
5128 values
[x
] = (put_field(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07), dib
->red_shift
, dib
->red_len
) |
5129 put_field(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07), dib
->green_shift
, dib
->green_len
) |
5130 put_field(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07), dib
->blue_shift
, dib
->blue_len
));
5132 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 4];
5136 case GRADIENT_FILL_TRIANGLE
:
5137 if (!(det
= triangle_det( v
))) return FALSE
;
5138 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5140 triangle_coords( v
, rc
, y
, &left
, &right
);
5141 for (x
= left
; x
< right
; x
++)
5143 WORD val
= gradient_triangle_555( v
, x
, y
, det
);
5144 ptr
[x
- rc
->left
] = (put_field(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07), dib
->red_shift
, dib
->red_len
) |
5145 put_field(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07), dib
->green_shift
, dib
->green_len
) |
5146 put_field(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07), dib
->blue_shift
, dib
->blue_len
));
5154 static BOOL
gradient_rect_8( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5156 BYTE
*ptr
= get_pixel_ptr_8( dib
, rc
->left
, rc
->top
);
5157 int x
, y
, left
, right
, det
;
5161 case GRADIENT_FILL_RECT_H
:
5162 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
5163 for (x
= rc
->left
; x
< rc
->right
; x
++)
5164 ptr
[x
- rc
->left
] = gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
5165 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5166 memcpy( ptr
, ptr
- dib
->stride
* 16, rc
->right
- rc
->left
);
5169 case GRADIENT_FILL_RECT_V
:
5170 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5173 for (x
= 0; x
< 16; x
++)
5174 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
5175 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 16];
5179 case GRADIENT_FILL_TRIANGLE
:
5180 if (!(det
= triangle_det( v
))) return FALSE
;
5181 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5183 triangle_coords( v
, rc
, y
, &left
, &right
);
5184 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_8( dib
, v
, x
, y
, det
);
5191 static BOOL
gradient_rect_4( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5193 BYTE
*ptr
= get_pixel_ptr_4( dib
, rc
->left
, rc
->top
);
5194 int x
, y
, left
, right
, det
, pos
;
5198 case GRADIENT_FILL_RECT_H
:
5199 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
5201 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 1; x
< rc
->right
; x
++, pos
++)
5203 BYTE val
= gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
5205 ptr
[pos
/ 2] = val
| (ptr
[pos
/ 2] & 0xf0);
5207 ptr
[pos
/ 2] = (val
<< 4) | (ptr
[pos
/ 2] & 0x0f);
5210 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5213 pos
= (dib
->rect
.left
+ rc
->left
) & 1;
5216 ptr
[0] = (ptr
[-16 * dib
->stride
] & 0x0f) | (ptr
[0] & 0xf0);
5220 for (; x
< rc
->right
- 1; x
+= 2, pos
+= 2) ptr
[pos
/ 2] = ptr
[pos
/ 2 - 16 * dib
->stride
];
5222 ptr
[pos
/ 2] = (ptr
[pos
/ 2] & 0x0f) | (ptr
[pos
/ 2 - 16 * dib
->stride
] & 0xf0);
5226 case GRADIENT_FILL_RECT_V
:
5227 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5230 for (x
= 0; x
< 16; x
++)
5231 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
5232 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 1; x
< rc
->right
; x
++, pos
++)
5234 ptr
[pos
/ 2] = values
[x
% 16] | (ptr
[pos
/ 2] & 0xf0);
5236 ptr
[pos
/ 2] = (values
[x
% 16] << 4) | (ptr
[pos
/ 2] & 0x0f);
5240 case GRADIENT_FILL_TRIANGLE
:
5241 if (!(det
= triangle_det( v
))) return FALSE
;
5242 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5244 triangle_coords( v
, rc
, y
, &left
, &right
);
5245 for (x
= left
, pos
= left
- rc
->left
+ ((dib
->rect
.left
+ rc
->left
) & 1); x
< right
; x
++, pos
++)
5247 BYTE val
= gradient_triangle_8( dib
, v
, x
, y
, det
);
5249 ptr
[pos
/ 2] = val
| (ptr
[pos
/ 2] & 0xf0);
5251 ptr
[pos
/ 2] = (val
<< 4) | (ptr
[pos
/ 2] & 0x0f);
5259 static BOOL
gradient_rect_1( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5261 BYTE
*ptr
= get_pixel_ptr_1( dib
, rc
->left
, rc
->top
);
5262 int x
, y
, left
, right
, det
, pos
;
5266 case GRADIENT_FILL_RECT_H
:
5267 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
5269 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
5271 BYTE val
= gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
) ? 0xff : 0;
5272 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) | (val
& pixel_masks_1
[pos
% 8]);
5275 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5276 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
5277 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
5278 (ptr
[pos
/ 8 - 16 * dib
->stride
] & pixel_masks_1
[pos
% 8]);
5281 case GRADIENT_FILL_RECT_V
:
5282 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5285 for (x
= 0; x
< 16; x
++)
5286 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
) ? 0xff : 0;
5287 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
5288 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
5289 (values
[x
% 16] & pixel_masks_1
[pos
% 8]);
5293 case GRADIENT_FILL_TRIANGLE
:
5294 if (!(det
= triangle_det( v
))) return FALSE
;
5295 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5297 triangle_coords( v
, rc
, y
, &left
, &right
);
5298 for (x
= left
, pos
= left
- rc
->left
+ ((dib
->rect
.left
+ rc
->left
) & 7); x
< right
; x
++, pos
++)
5300 BYTE val
= gradient_triangle_8( dib
, v
, x
, y
, det
) ? 0xff : 0;
5301 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) | (val
& pixel_masks_1
[pos
% 8]);
5309 static BOOL
gradient_rect_null( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5314 static void mask_rect_32( const dib_info
*dst
, const RECT
*rc
,
5315 const dib_info
*src
, const POINT
*origin
, int rop2
)
5317 DWORD
*dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->top
), dst_colors
[256];
5318 DWORD src_val
, bit_val
, i
, full
, pos
;
5319 int x
, y
, origin_end
= origin
->x
+ rc
->right
- rc
->left
;
5320 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5321 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5323 if (dst
->funcs
== &funcs_8888
)
5324 for (i
= 0; i
< 2; i
++)
5325 dst_colors
[i
] = color_table
[i
].rgbRed
<< 16 | color_table
[i
].rgbGreen
<< 8 |
5326 color_table
[i
].rgbBlue
;
5328 for (i
= 0; i
< 2; i
++)
5329 dst_colors
[i
] = put_field(color_table
[i
].rgbRed
, dst
->red_shift
, dst
->red_len
) |
5330 put_field(color_table
[i
].rgbGreen
, dst
->green_shift
, dst
->green_len
) |
5331 put_field(color_table
[i
].rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
5333 /* Creating a BYTE-sized table so we don't need to mask the lsb of bit_val */
5334 for (i
= 2; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
5335 dst_colors
[i
] = dst_colors
[i
& 1];
5337 /* Special case starting and finishing in same byte, neither on byte boundary */
5338 if ((origin
->x
& 7) && (origin_end
& 7) && (origin
->x
& ~7) == (origin_end
& ~7))
5340 struct rop_codes codes
;
5342 get_rop_codes( rop2
, &codes
);
5344 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5346 pos
= origin
->x
& 7;
5347 for (x
= 0; x
< rc
->right
- rc
->left
; x
++, pos
++)
5349 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5350 do_rop_codes_32( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5352 dst_start
+= dst
->stride
/ 4;
5353 src_start
+= src
->stride
;
5358 full
= ((rc
->right
- rc
->left
) - ((8 - (origin
->x
& 7)) & 7)) / 8;
5360 #define LOOP( op ) \
5361 for (y = rc->top; y < rc->bottom; y++) \
5363 pos = origin->x & 7; \
5364 src_val = src_start[pos / 8]; \
5368 case 1: bit_val = src_val >> 6; op; x++; \
5369 /* fall through */ \
5370 case 2: bit_val = src_val >> 5; op; x++; \
5371 /* fall through */ \
5372 case 3: bit_val = src_val >> 4; op; x++; \
5373 /* fall through */ \
5374 case 4: bit_val = src_val >> 3; op; x++; \
5375 /* fall through */ \
5376 case 5: bit_val = src_val >> 2; op; x++; \
5377 /* fall through */ \
5378 case 6: bit_val = src_val >> 1; op; x++; \
5379 /* fall through */ \
5380 case 7: bit_val = src_val; op; x++; \
5381 pos = (pos + 7) & ~7; \
5383 for (i = 0; i < full; i++, pos += 8) \
5385 src_val = src_start[pos / 8]; \
5386 bit_val = src_val >> 7; op; x++; \
5387 bit_val = src_val >> 6; op; x++; \
5388 bit_val = src_val >> 5; op; x++; \
5389 bit_val = src_val >> 4; op; x++; \
5390 bit_val = src_val >> 3; op; x++; \
5391 bit_val = src_val >> 2; op; x++; \
5392 bit_val = src_val >> 1; op; x++; \
5393 bit_val = src_val; op; x++; \
5395 if (origin_end & 7) \
5397 src_val = src_start[pos / 8]; \
5398 x += (origin_end & 7) - 1; \
5399 switch (origin_end & 7) \
5401 case 7: bit_val = src_val >> 1; op; x--; \
5402 /* fall through */ \
5403 case 6: bit_val = src_val >> 2; op; x--; \
5404 /* fall through */ \
5405 case 5: bit_val = src_val >> 3; op; x--; \
5406 /* fall through */ \
5407 case 4: bit_val = src_val >> 4; op; x--; \
5408 /* fall through */ \
5409 case 3: bit_val = src_val >> 5; op; x--; \
5410 /* fall through */ \
5411 case 2: bit_val = src_val >> 6; op; x--; \
5412 /* fall through */ \
5413 case 1: bit_val = src_val >> 7; op; \
5416 dst_start += dst->stride / 4; \
5417 src_start += src->stride; \
5422 ROPS_ALL( dst_start
[x
], dst_colors
[bit_val
] )
5427 static void mask_rect_24( const dib_info
*dst
, const RECT
*rc
,
5428 const dib_info
*src
, const POINT
*origin
, int rop2
)
5430 BYTE
*dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->top
);
5431 DWORD src_val
, bit_val
, i
, full
, pos
;
5432 struct rop_codes codes
;
5433 int x
, y
, origin_end
= origin
->x
+ rc
->right
- rc
->left
;
5434 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5435 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5438 get_rop_codes( rop2
, &codes
);
5440 /* Special case starting and finishing in same byte, neither on byte boundary */
5441 if ((origin
->x
& 7) && (origin_end
& 7) && (origin
->x
& ~7) == (origin_end
& ~7))
5443 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5445 pos
= origin
->x
& 7;
5446 for (x
= 0; x
< rc
->right
- rc
->left
; x
++, pos
++)
5448 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5449 rgb
= color_table
[bit_val
];
5450 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5451 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5452 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5454 dst_start
+= dst
->stride
;
5455 src_start
+= src
->stride
;
5460 full
= ((rc
->right
- rc
->left
) - ((8 - (origin
->x
& 7)) & 7)) / 8;
5462 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5464 pos
= origin
->x
& 7;
5465 src_val
= src_start
[pos
/ 8];
5471 bit_val
= (src_val
>> 6) & 1;
5472 rgb
= color_table
[bit_val
];
5473 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5474 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5475 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5479 bit_val
= (src_val
>> 5) & 1;
5480 rgb
= color_table
[bit_val
];
5481 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5482 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5483 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5487 bit_val
= (src_val
>> 4) & 1;
5488 rgb
= color_table
[bit_val
];
5489 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5490 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5491 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5495 bit_val
= (src_val
>> 3) & 1;
5496 rgb
= color_table
[bit_val
];
5497 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5498 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5499 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5503 bit_val
= (src_val
>> 2) & 1;
5504 rgb
= color_table
[bit_val
];
5505 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5506 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5507 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5511 bit_val
= (src_val
>> 1) & 1;
5512 rgb
= color_table
[bit_val
];
5513 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5514 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5515 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5519 bit_val
= src_val
& 1;
5520 rgb
= color_table
[bit_val
];
5521 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5522 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5523 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5525 pos
= (pos
+ 7) & ~7;
5528 for (i
= 0; i
< full
; i
++, pos
+= 8)
5530 src_val
= src_start
[pos
/ 8];
5532 bit_val
= (src_val
>> 7) & 1;
5533 rgb
= color_table
[bit_val
];
5534 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5535 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5536 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5539 bit_val
= (src_val
>> 6) & 1;
5540 rgb
= color_table
[bit_val
];
5541 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5542 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5543 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5546 bit_val
= (src_val
>> 5) & 1;
5547 rgb
= color_table
[bit_val
];
5548 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5549 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5550 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5553 bit_val
= (src_val
>> 4) & 1;
5554 rgb
= color_table
[bit_val
];
5555 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5556 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5557 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5560 bit_val
= (src_val
>> 3) & 1;
5561 rgb
= color_table
[bit_val
];
5562 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5563 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5564 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5567 bit_val
= (src_val
>> 2) & 1;
5568 rgb
= color_table
[bit_val
];
5569 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5570 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5571 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5574 bit_val
= (src_val
>> 1) & 1;
5575 rgb
= color_table
[bit_val
];
5576 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5577 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5578 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5581 bit_val
= src_val
& 1;
5582 rgb
= color_table
[bit_val
];
5583 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5584 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5585 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5591 src_val
= src_start
[pos
/ 8];
5592 x
+= (origin_end
& 7) - 1;
5594 switch (origin_end
& 7)
5597 bit_val
= (src_val
>> 1) & 1;
5598 rgb
= color_table
[bit_val
];
5599 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5600 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5601 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5605 bit_val
= (src_val
>> 2) & 1;
5606 rgb
= color_table
[bit_val
];
5607 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5608 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5609 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5613 bit_val
= (src_val
>> 3) & 1;
5614 rgb
= color_table
[bit_val
];
5615 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5616 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5617 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5621 bit_val
= (src_val
>> 4) & 1;
5622 rgb
= color_table
[bit_val
];
5623 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5624 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5625 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5629 bit_val
= (src_val
>> 5) & 1;
5630 rgb
= color_table
[bit_val
];
5631 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5632 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5633 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5637 bit_val
= (src_val
>> 6) & 1;
5638 rgb
= color_table
[bit_val
];
5639 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5640 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5641 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5645 bit_val
= (src_val
>> 7) & 1;
5646 rgb
= color_table
[bit_val
];
5647 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5648 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5649 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5653 dst_start
+= dst
->stride
;
5654 src_start
+= src
->stride
;
5658 static void mask_rect_16( const dib_info
*dst
, const RECT
*rc
,
5659 const dib_info
*src
, const POINT
*origin
, int rop2
)
5661 WORD
*dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->top
), dst_colors
[2];
5662 DWORD src_val
, bit_val
, i
, full
, pos
;
5663 struct rop_codes codes
;
5664 int x
, y
, origin_end
= origin
->x
+ rc
->right
- rc
->left
;
5665 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5666 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5668 get_rop_codes( rop2
, &codes
);
5670 if (dst
->funcs
== &funcs_555
)
5671 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
5672 dst_colors
[i
] = ((color_table
[i
].rgbRed
<< 7) & 0x7c00) |
5673 ((color_table
[i
].rgbGreen
<< 2) & 0x03e0) |
5674 ((color_table
[i
].rgbBlue
>> 3) & 0x001f);
5676 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
5677 dst_colors
[i
] = put_field(color_table
[i
].rgbRed
, dst
->red_shift
, dst
->red_len
) |
5678 put_field(color_table
[i
].rgbGreen
, dst
->green_shift
, dst
->green_len
) |
5679 put_field(color_table
[i
].rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
5681 /* Special case starting and finishing in same byte, neither on byte boundary */
5682 if ((origin
->x
& 7) && (origin_end
& 7) && (origin
->x
& ~7) == (origin_end
& ~7))
5684 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5686 pos
= origin
->x
& 7;
5687 for (x
= 0; x
< rc
->right
- rc
->left
; x
++, pos
++)
5689 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5690 do_rop_codes_16( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5692 dst_start
+= dst
->stride
/ 2;
5693 src_start
+= src
->stride
;
5698 full
= ((rc
->right
- rc
->left
) - ((8 - (origin
->x
& 7)) & 7)) / 8;
5700 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5702 pos
= origin
->x
& 7;
5703 src_val
= src_start
[pos
/ 8];
5709 bit_val
= (src_val
>> 6) & 1;
5710 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5713 bit_val
= (src_val
>> 5) & 1;
5714 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5717 bit_val
= (src_val
>> 4) & 1;
5718 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5721 bit_val
= (src_val
>> 3) & 1;
5722 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5725 bit_val
= (src_val
>> 2) & 1;
5726 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5729 bit_val
= (src_val
>> 1) & 1;
5730 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5733 bit_val
= src_val
& 1;
5734 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5735 pos
= (pos
+ 7) & ~7;
5738 for (i
= 0; i
< full
; i
++, pos
+= 8)
5740 src_val
= src_start
[pos
/ 8];
5742 bit_val
= (src_val
>> 7) & 1;
5743 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5744 bit_val
= (src_val
>> 6) & 1;
5745 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5746 bit_val
= (src_val
>> 5) & 1;
5747 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5748 bit_val
= (src_val
>> 4) & 1;
5749 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5750 bit_val
= (src_val
>> 3) & 1;
5751 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5752 bit_val
= (src_val
>> 2) & 1;
5753 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5754 bit_val
= (src_val
>> 1) & 1;
5755 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5756 bit_val
= src_val
& 1;
5757 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5762 src_val
= src_start
[pos
/ 8];
5763 x
+= (origin_end
& 7) - 1;
5765 switch (origin_end
& 7)
5768 bit_val
= (src_val
>> 1) & 1;
5769 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5772 bit_val
= (src_val
>> 2) & 1;
5773 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5776 bit_val
= (src_val
>> 3) & 1;
5777 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5780 bit_val
= (src_val
>> 4) & 1;
5781 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5784 bit_val
= (src_val
>> 5) & 1;
5785 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5788 bit_val
= (src_val
>> 6) & 1;
5789 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5792 bit_val
= (src_val
>> 7) & 1;
5793 do_rop_codes_16( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5797 dst_start
+= dst
->stride
/ 2;
5798 src_start
+= src
->stride
;
5802 static void mask_rect_8( const dib_info
*dst
, const RECT
*rc
,
5803 const dib_info
*src
, const POINT
*origin
, int rop2
)
5805 BYTE
*dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->top
), dst_colors
[2];
5806 DWORD src_val
, bit_val
, i
, full
, pos
;
5807 struct rop_codes codes
;
5808 int x
, y
, origin_end
= origin
->x
+ rc
->right
- rc
->left
;
5809 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5810 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5812 get_rop_codes( rop2
, &codes
);
5814 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
5815 dst_colors
[i
] = rgb_to_pixel_colortable( dst
, color_table
[i
].rgbRed
, color_table
[i
].rgbGreen
,
5816 color_table
[i
].rgbBlue
);
5818 /* Special case starting and finishing in same byte, neither on byte boundary */
5819 if ((origin
->x
& 7) && (origin_end
& 7) && (origin
->x
& ~7) == (origin_end
& ~7))
5821 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5823 pos
= origin
->x
& 7;
5824 for (x
= 0; x
< rc
->right
- rc
->left
; x
++, pos
++)
5826 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5827 do_rop_codes_8( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5829 dst_start
+= dst
->stride
;
5830 src_start
+= src
->stride
;
5835 full
= ((rc
->right
- rc
->left
) - ((8 - (origin
->x
& 7)) & 7)) / 8;
5837 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5839 pos
= origin
->x
& 7;
5840 src_val
= src_start
[pos
/ 8];
5846 bit_val
= (src_val
>> 6) & 1;
5847 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5850 bit_val
= (src_val
>> 5) & 1;
5851 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5854 bit_val
= (src_val
>> 4) & 1;
5855 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5858 bit_val
= (src_val
>> 3) & 1;
5859 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5862 bit_val
= (src_val
>> 2) & 1;
5863 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5866 bit_val
= (src_val
>> 1) & 1;
5867 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5870 bit_val
= src_val
& 1;
5871 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5872 pos
= (pos
+ 7) & ~7;
5875 for (i
= 0; i
< full
; i
++, pos
+= 8)
5877 src_val
= src_start
[pos
/ 8];
5879 bit_val
= (src_val
>> 7) & 1;
5880 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5881 bit_val
= (src_val
>> 6) & 1;
5882 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5883 bit_val
= (src_val
>> 5) & 1;
5884 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5885 bit_val
= (src_val
>> 4) & 1;
5886 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5887 bit_val
= (src_val
>> 3) & 1;
5888 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5889 bit_val
= (src_val
>> 2) & 1;
5890 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5891 bit_val
= (src_val
>> 1) & 1;
5892 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5893 bit_val
= src_val
& 1;
5894 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5899 src_val
= src_start
[pos
/ 8];
5900 x
+= (origin_end
& 7) - 1;
5902 switch (origin_end
& 7)
5905 bit_val
= (src_val
>> 1) & 1;
5906 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5909 bit_val
= (src_val
>> 2) & 1;
5910 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5913 bit_val
= (src_val
>> 3) & 1;
5914 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5917 bit_val
= (src_val
>> 4) & 1;
5918 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5921 bit_val
= (src_val
>> 5) & 1;
5922 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5925 bit_val
= (src_val
>> 6) & 1;
5926 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5929 bit_val
= (src_val
>> 7) & 1;
5930 do_rop_codes_8( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5934 dst_start
+= dst
->stride
;
5935 src_start
+= src
->stride
;
5939 static void mask_rect_4( const dib_info
*dst
, const RECT
*rc
,
5940 const dib_info
*src
, const POINT
*origin
, int rop2
)
5942 BYTE
*dst_start
= get_pixel_ptr_4(dst
, rc
->left
, rc
->top
), dst_colors
[2], *dst_ptr
;
5943 DWORD bit_val
, i
, pos
;
5944 struct rop_codes codes
;
5946 int left
= dst
->rect
.left
+ rc
->left
;
5947 int right
= dst
->rect
.left
+ rc
->right
;
5948 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5949 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5951 get_rop_codes( rop2
, &codes
);
5953 for (i
= 0; i
< sizeof(dst_colors
) / sizeof(dst_colors
[0]); i
++)
5955 dst_colors
[i
] = rgb_to_pixel_colortable( dst
, color_table
[i
].rgbRed
, color_table
[i
].rgbGreen
,
5956 color_table
[i
].rgbBlue
);
5957 /* Set high nibble to match so we don't need to shift it later. */
5958 dst_colors
[i
] |= dst_colors
[i
] << 4;
5961 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5963 pos
= origin
->x
& 7;
5965 for (x
= left
, dst_ptr
= dst_start
; x
< right
; x
++, pos
++)
5967 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5969 do_rop_codes_mask_8( dst_ptr
++, dst_colors
[bit_val
], &codes
, 0x0f );
5971 do_rop_codes_mask_8( dst_ptr
, dst_colors
[bit_val
], &codes
, 0xf0 );
5973 dst_start
+= dst
->stride
;
5974 src_start
+= src
->stride
;
5978 static void mask_rect_null( const dib_info
*dst
, const RECT
*rc
,
5979 const dib_info
*src
, const POINT
*origin
, int rop2
)
5983 static inline BYTE
aa_color( BYTE dst
, BYTE text
, BYTE min_comp
, BYTE max_comp
)
5985 if (dst
== text
) return dst
;
5989 DWORD diff
= dst
- text
;
5990 DWORD range
= max_comp
- text
;
5991 dst
= text
+ (diff
* range
) / (0xff - text
);
5996 DWORD diff
= text
- dst
;
5997 DWORD range
= text
- min_comp
;
5998 dst
= text
- (diff
* range
) / text
;
6003 static inline DWORD
aa_rgb( BYTE r_dst
, BYTE g_dst
, BYTE b_dst
, DWORD text
, const struct intensity_range
*range
)
6005 return (aa_color( b_dst
, text
, range
->b_min
, range
->b_max
) |
6006 aa_color( g_dst
, text
>> 8, range
->g_min
, range
->g_max
) << 8 |
6007 aa_color( r_dst
, text
>> 16, range
->r_min
, range
->r_max
) << 16);
6010 static void draw_glyph_8888( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6011 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6013 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
6014 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6017 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6019 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6021 if (glyph_ptr
[x
] <= 1) continue;
6022 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
6023 dst_ptr
[x
] = aa_rgb( dst_ptr
[x
] >> 16, dst_ptr
[x
] >> 8, dst_ptr
[x
], text_pixel
, ranges
+ glyph_ptr
[x
] );
6025 dst_ptr
+= dib
->stride
/ 4;
6026 glyph_ptr
+= glyph
->stride
;
6030 static void draw_glyph_32( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6031 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6033 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
6034 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6038 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
6039 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
6040 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
6042 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6044 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6046 if (glyph_ptr
[x
] <= 1) continue;
6047 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
6048 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
6049 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
6050 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
6051 text
, ranges
+ glyph_ptr
[x
] );
6052 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
6053 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
6054 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
6056 dst_ptr
+= dib
->stride
/ 4;
6057 glyph_ptr
+= glyph
->stride
;
6061 static void draw_glyph_24( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6062 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6064 BYTE
*dst_ptr
= get_pixel_ptr_24( dib
, rect
->left
, rect
->top
);
6065 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6069 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6071 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6073 if (glyph_ptr
[x
] <= 1) continue;
6074 if (glyph_ptr
[x
] >= 16)
6077 val
= aa_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
6078 text_pixel
, ranges
+ glyph_ptr
[x
] );
6079 dst_ptr
[x
* 3] = val
;
6080 dst_ptr
[x
* 3 + 1] = val
>> 8;
6081 dst_ptr
[x
* 3 + 2] = val
>> 16;
6083 dst_ptr
+= dib
->stride
;
6084 glyph_ptr
+= glyph
->stride
;
6088 static void draw_glyph_555( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6089 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6091 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
6092 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6096 text
= ((text_pixel
<< 9) & 0xf80000) | ((text_pixel
<< 4) & 0x070000) |
6097 ((text_pixel
<< 6) & 0x00f800) | ((text_pixel
<< 1) & 0x000700) |
6098 ((text_pixel
<< 3) & 0x0000f8) | ((text_pixel
>> 2) & 0x000007);
6100 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6102 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6104 if (glyph_ptr
[x
] <= 1) continue;
6105 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
6106 val
= aa_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
6107 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
6108 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
6109 text
, ranges
+ glyph_ptr
[x
] );
6110 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
6112 dst_ptr
+= dib
->stride
/ 2;
6113 glyph_ptr
+= glyph
->stride
;
6117 static void draw_glyph_16( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6118 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6120 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
6121 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6125 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
6126 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
6127 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
6129 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6131 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6133 if (glyph_ptr
[x
] <= 1) continue;
6134 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
6135 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
6136 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
6137 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
6138 text
, ranges
+ glyph_ptr
[x
] );
6139 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
6140 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
6141 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
6143 dst_ptr
+= dib
->stride
/ 2;
6144 glyph_ptr
+= glyph
->stride
;
6148 static void draw_glyph_8( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6149 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6151 BYTE
*dst_ptr
= get_pixel_ptr_8( dib
, rect
->left
, rect
->top
);
6152 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6155 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6157 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6159 /* no antialiasing, glyph should only contain 0 or 16. */
6160 if (glyph_ptr
[x
] >= 16)
6161 dst_ptr
[x
] = text_pixel
;
6163 dst_ptr
+= dib
->stride
;
6164 glyph_ptr
+= glyph
->stride
;
6168 static void draw_glyph_4( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6169 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6171 BYTE
*dst_ptr
= get_pixel_ptr_4( dib
, rect
->left
, rect
->top
);
6172 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6175 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6177 for (x
= 0, pos
= (dib
->rect
.left
+ rect
->left
) & 1; x
< rect
->right
- rect
->left
; x
++, pos
++)
6179 /* no antialiasing, glyph should only contain 0 or 16. */
6180 if (glyph_ptr
[x
] >= 16)
6183 dst_ptr
[pos
/ 2] = text_pixel
| (dst_ptr
[pos
/ 2] & 0xf0);
6185 dst_ptr
[pos
/ 2] = (text_pixel
<< 4) | (dst_ptr
[pos
/ 2] & 0x0f);
6188 dst_ptr
+= dib
->stride
;
6189 glyph_ptr
+= glyph
->stride
;
6193 static void draw_glyph_1( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6194 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6196 BYTE
*dst_ptr
= get_pixel_ptr_1( dib
, rect
->left
, rect
->top
);
6197 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6199 BYTE text
= (text_pixel
& 1) ? 0xff : 0;
6201 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6203 for (x
= 0, pos
= (dib
->rect
.left
+ rect
->left
) & 7; x
< rect
->right
- rect
->left
; x
++, pos
++)
6205 /* no antialiasing, glyph should only contain 0 or 16. */
6206 if (glyph_ptr
[x
] >= 16)
6207 dst_ptr
[pos
/ 8] = (dst_ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
6208 (text
& pixel_masks_1
[pos
% 8]);
6210 dst_ptr
+= dib
->stride
;
6211 glyph_ptr
+= glyph
->stride
;
6215 static void draw_glyph_null( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6216 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6221 static inline DWORD
blend_subpixel( BYTE r
, BYTE g
, BYTE b
, DWORD text
, DWORD alpha
)
6223 return blend_color( r
, text
>> 16, (BYTE
)(alpha
>> 16) ) << 16 |
6224 blend_color( g
, text
>> 8, (BYTE
)(alpha
>> 8) ) << 8 |
6225 blend_color( b
, text
, (BYTE
) alpha
);
6228 static void draw_subpixel_glyph_8888( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6229 const POINT
*origin
, DWORD text_pixel
)
6231 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
6232 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6235 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6237 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6239 if (glyph_ptr
[x
] == 0) continue;
6240 dst_ptr
[x
] = blend_subpixel( dst_ptr
[x
] >> 16, dst_ptr
[x
] >> 8, dst_ptr
[x
], text_pixel
, glyph_ptr
[x
] );
6242 dst_ptr
+= dib
->stride
/ 4;
6243 glyph_ptr
+= glyph
->stride
/ 4;
6247 static void draw_subpixel_glyph_32( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6248 const POINT
*origin
, DWORD text_pixel
)
6250 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
6251 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6255 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
6256 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
6257 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
6259 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6261 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6263 if (glyph_ptr
[x
] == 0) continue;
6264 val
= blend_subpixel( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
6265 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
6266 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
6267 text
, glyph_ptr
[x
] );
6268 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
6269 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
6270 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
6272 dst_ptr
+= dib
->stride
/ 4;
6273 glyph_ptr
+= glyph
->stride
/ 4;
6277 static void draw_subpixel_glyph_24( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6278 const POINT
*origin
, DWORD text_pixel
)
6280 BYTE
*dst_ptr
= get_pixel_ptr_24( dib
, rect
->left
, rect
->top
);
6281 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6285 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6287 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6289 if (glyph_ptr
[x
] == 0) continue;
6290 val
= blend_subpixel( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
6291 text_pixel
, glyph_ptr
[x
] );
6292 dst_ptr
[x
* 3] = val
;
6293 dst_ptr
[x
* 3 + 1] = val
>> 8;
6294 dst_ptr
[x
* 3 + 2] = val
>> 16;
6296 dst_ptr
+= dib
->stride
;
6297 glyph_ptr
+= glyph
->stride
/ 4;
6301 static void draw_subpixel_glyph_555( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6302 const POINT
*origin
, DWORD text_pixel
)
6304 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
6305 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6309 text
= ((text_pixel
<< 9) & 0xf80000) | ((text_pixel
<< 4) & 0x070000) |
6310 ((text_pixel
<< 6) & 0x00f800) | ((text_pixel
<< 1) & 0x000700) |
6311 ((text_pixel
<< 3) & 0x0000f8) | ((text_pixel
>> 2) & 0x000007);
6313 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6315 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6317 if (glyph_ptr
[x
] == 0) continue;
6318 val
= blend_subpixel( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
6319 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
6320 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
6321 text
, glyph_ptr
[x
] );
6322 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
6324 dst_ptr
+= dib
->stride
/ 2;
6325 glyph_ptr
+= glyph
->stride
/ 4;
6329 static void draw_subpixel_glyph_16( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6330 const POINT
*origin
, DWORD text_pixel
)
6332 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
6333 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6337 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
6338 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
6339 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
6341 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6343 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6345 if (glyph_ptr
[x
] == 0) continue;
6346 val
= blend_subpixel( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
6347 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
6348 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
6349 text
, glyph_ptr
[x
] );
6350 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
6351 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
6352 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
6354 dst_ptr
+= dib
->stride
/ 2;
6355 glyph_ptr
+= glyph
->stride
/ 4;
6359 static void draw_subpixel_glyph_null( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6360 const POINT
*origin
, DWORD text_pixel
)
6365 static void create_rop_masks_32(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6366 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6368 DWORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6371 /* masks are always 8x8 */
6372 assert( dib
->width
== 8 );
6373 assert( dib
->height
== 8 );
6375 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6377 for(x
= 0; x
< 8; x
++)
6379 if(*hatch_ptr
& pixel_masks_1
[x
])
6381 and_bits
[x
] = fg
->and;
6382 xor_bits
[x
] = fg
->xor;
6386 and_bits
[x
] = bg
->and;
6387 xor_bits
[x
] = bg
->xor;
6390 and_bits
+= dib
->stride
/ 4;
6391 xor_bits
+= dib
->stride
/ 4;
6395 static void create_rop_masks_24(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6396 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6398 DWORD mask_start
= 0, mask_offset
;
6399 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6402 /* masks are always 8x8 */
6403 assert( dib
->width
== 8 );
6404 assert( dib
->height
== 8 );
6406 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6408 mask_offset
= mask_start
;
6409 for(x
= 0; x
< 8; x
++)
6411 if(*hatch_ptr
& pixel_masks_1
[x
])
6413 and_bits
[mask_offset
] = fg
->and & 0xff;
6414 xor_bits
[mask_offset
++] = fg
->xor & 0xff;
6415 and_bits
[mask_offset
] = (fg
->and >> 8) & 0xff;
6416 xor_bits
[mask_offset
++] = (fg
->xor >> 8) & 0xff;
6417 and_bits
[mask_offset
] = (fg
->and >> 16) & 0xff;
6418 xor_bits
[mask_offset
++] = (fg
->xor >> 16) & 0xff;
6422 and_bits
[mask_offset
] = bg
->and & 0xff;
6423 xor_bits
[mask_offset
++] = bg
->xor & 0xff;
6424 and_bits
[mask_offset
] = (bg
->and >> 8) & 0xff;
6425 xor_bits
[mask_offset
++] = (bg
->xor >> 8) & 0xff;
6426 and_bits
[mask_offset
] = (bg
->and >> 16) & 0xff;
6427 xor_bits
[mask_offset
++] = (bg
->xor >> 16) & 0xff;
6430 mask_start
+= dib
->stride
;
6434 static void create_rop_masks_16(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6435 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6437 WORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6440 /* masks are always 8x8 */
6441 assert( dib
->width
== 8 );
6442 assert( dib
->height
== 8 );
6444 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6446 for(x
= 0; x
< 8; x
++)
6448 if(*hatch_ptr
& pixel_masks_1
[x
])
6450 and_bits
[x
] = fg
->and;
6451 xor_bits
[x
] = fg
->xor;
6455 and_bits
[x
] = bg
->and;
6456 xor_bits
[x
] = bg
->xor;
6459 and_bits
+= dib
->stride
/ 2;
6460 xor_bits
+= dib
->stride
/ 2;
6464 static void create_rop_masks_8(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6465 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6467 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6470 /* masks are always 8x8 */
6471 assert( dib
->width
== 8 );
6472 assert( dib
->height
== 8 );
6474 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6476 for(x
= 0; x
< 8; x
++)
6478 if(*hatch_ptr
& pixel_masks_1
[x
])
6480 and_bits
[x
] = fg
->and;
6481 xor_bits
[x
] = fg
->xor;
6485 and_bits
[x
] = bg
->and;
6486 xor_bits
[x
] = bg
->xor;
6489 and_bits
+= dib
->stride
;
6490 xor_bits
+= dib
->stride
;
6494 static void create_rop_masks_4(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6495 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6498 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6499 const rop_mask
*rop_mask
;
6502 /* masks are always 8x8 */
6503 assert( dib
->width
== 8 );
6504 assert( dib
->height
== 8 );
6506 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6508 for(x
= mask_offset
= 0; x
< 8; x
++)
6510 if(*hatch_ptr
& pixel_masks_1
[x
])
6517 and_bits
[mask_offset
] |= (rop_mask
->and & 0x0f);
6518 xor_bits
[mask_offset
] |= (rop_mask
->xor & 0x0f);
6523 and_bits
[mask_offset
] = (rop_mask
->and << 4) & 0xf0;
6524 xor_bits
[mask_offset
] = (rop_mask
->xor << 4) & 0xf0;
6527 and_bits
+= dib
->stride
;
6528 xor_bits
+= dib
->stride
;
6532 static void create_rop_masks_1(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6533 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6535 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6539 /* masks are always 8x8 */
6540 assert( dib
->width
== 8 );
6541 assert( dib
->height
== 8 );
6543 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6545 *and_bits
= *xor_bits
= 0;
6546 for(x
= 0; x
< 8; x
++)
6548 if(*hatch_ptr
& pixel_masks_1
[x
])
6550 rop_mask
.and = (fg
->and & 1) ? 0xff : 0;
6551 rop_mask
.xor = (fg
->xor & 1) ? 0xff : 0;
6555 rop_mask
.and = (bg
->and & 1) ? 0xff : 0;
6556 rop_mask
.xor = (bg
->xor & 1) ? 0xff : 0;
6558 *and_bits
|= (rop_mask
.and & pixel_masks_1
[x
]);
6559 *xor_bits
|= (rop_mask
.xor & pixel_masks_1
[x
]);
6561 and_bits
+= dib
->stride
;
6562 xor_bits
+= dib
->stride
;
6566 static void create_rop_masks_null(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6567 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6571 static void create_dither_masks_8(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
6573 /* mapping between RGB triples and the default color table */
6574 static const BYTE mapping
[27] =
6576 0, /* 000000 -> 000000 */
6577 4, /* 00007f -> 000080 */
6578 252, /* 0000ff -> 0000ff */
6579 2, /* 007f00 -> 008000 */
6580 6, /* 007f7f -> 008080 */
6581 224, /* 007fff -> 0080c0 */
6582 250, /* 00ff00 -> 00ff00 */
6583 184, /* 00ff7f -> 00e080 */
6584 254, /* 00ffff -> 00ffff */
6585 1, /* 7f0000 -> 800000 */
6586 5, /* 7f007f -> 800080 */
6587 196, /* 7f00ff -> 8000c0 */
6588 3, /* 7f7f00 -> 808000 */
6589 248, /* 7f7f7f -> 808080 */
6590 228, /* 7f7fff -> 8080c0 */
6591 60, /* 7fff00 -> 80e000 */
6592 188, /* 7fff7f -> 80e080 */
6593 244, /* 7fffff -> 80c0c0 */
6594 249, /* ff0000 -> ff0000 */
6595 135, /* ff007f -> e00080 */
6596 253, /* ff00ff -> ff00ff */
6597 39, /* ff7f00 -> e08000 */
6598 167, /* ff7f7f -> e08080 */
6599 231, /* ff7fff -> e080c0 */
6600 251, /* ffff00 -> ffff00 */
6601 191, /* ffff7f -> e0e080 */
6602 255 /* ffffff -> ffffff */
6605 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6606 struct rop_codes codes
;
6609 /* masks are always 8x8 */
6610 assert( dib
->width
== 8 );
6611 assert( dib
->height
== 8 );
6613 get_rop_codes( rop2
, &codes
);
6615 for (y
= 0; y
< 8; y
++)
6617 for (x
= 0; x
< 8; x
++)
6619 DWORD r
= ((GetRValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6620 DWORD g
= ((GetGValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6621 DWORD b
= ((GetBValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6622 DWORD pixel
= mapping
[r
* 9 + g
* 3 + b
];
6623 and_bits
[x
] = (pixel
& codes
.a1
) ^ codes
.a2
;
6624 xor_bits
[x
] = (pixel
& codes
.x1
) ^ codes
.x2
;
6626 and_bits
+= dib
->stride
;
6627 xor_bits
+= dib
->stride
;
6631 static void create_dither_masks_4(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
6633 /* mapping between RGB triples and the default color table */
6634 static const BYTE mapping
[27] =
6636 0, /* 000000 -> 000000 */
6637 4, /* 00007f -> 000080 */
6638 12, /* 0000ff -> 0000ff */
6639 2, /* 007f00 -> 008000 */
6640 6, /* 007f7f -> 008080 */
6641 6, /* 007fff -> 008080 */
6642 10, /* 00ff00 -> 00ff00 */
6643 6, /* 00ff7f -> 008080 */
6644 14, /* 00ffff -> 00ffff */
6645 1, /* 7f0000 -> 800000 */
6646 5, /* 7f007f -> 800080 */
6647 5, /* 7f00ff -> 800080 */
6648 3, /* 7f7f00 -> 808000 */
6649 7, /* 7f7f7f -> 808080 */
6650 8, /* 7f7fff -> c0c0c0 */
6651 3, /* 7fff00 -> 808000 */
6652 8, /* 7fff7f -> c0c0c0 */
6653 8, /* 7fffff -> c0c0c0 */
6654 9, /* ff0000 -> ff0000 */
6655 5, /* ff007f -> 800080 */
6656 13, /* ff00ff -> ff00ff */
6657 3, /* ff7f00 -> 808000 */
6658 8, /* ff7f7f -> c0c0c0 */
6659 8, /* ff7fff -> c0c0c0 */
6660 11, /* ffff00 -> ffff00 */
6661 8, /* ffff7f -> c0c0c0 */
6662 15 /* ffffff -> ffffff */
6665 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6666 struct rop_codes codes
;
6669 /* masks are always 8x8 */
6670 assert( dib
->width
== 8 );
6671 assert( dib
->height
== 8 );
6673 get_rop_codes( rop2
, &codes
);
6675 for (y
= 0; y
< 8; y
++)
6677 for (x
= 0; x
< 8; x
++)
6679 DWORD r
= ((GetRValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6680 DWORD g
= ((GetGValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6681 DWORD b
= ((GetBValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6682 DWORD pixel
= mapping
[r
* 9 + g
* 3 + b
];
6685 and_bits
[x
/ 2] |= (pixel
& codes
.a1
) ^ codes
.a2
;
6686 xor_bits
[x
/ 2] |= (pixel
& codes
.x1
) ^ codes
.x2
;
6690 and_bits
[x
/ 2] = ((pixel
& codes
.a1
) ^ codes
.a2
) << 4;
6691 xor_bits
[x
/ 2] = ((pixel
& codes
.x1
) ^ codes
.x2
) << 4;
6694 and_bits
+= dib
->stride
;
6695 xor_bits
+= dib
->stride
;
6699 static void create_dither_masks_1(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
6701 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6702 struct rop_codes codes
;
6704 int x
, y
, grey
= (30 * GetRValue(color
) + 59 * GetGValue(color
) + 11 * GetBValue(color
) + 200) / 400;
6706 /* masks are always 8x8 */
6707 assert( dib
->width
== 8 );
6708 assert( dib
->height
== 8 );
6710 get_rop_codes( rop2
, &codes
);
6712 for (y
= 0; y
< 8; y
++)
6714 *and_bits
= *xor_bits
= 0;
6715 for (x
= 0; x
< 8; x
++)
6717 if (grey
+ bayer_8x8
[y
][x
] > 63)
6719 rop_mask
.and = (0xff & codes
.a1
) ^ codes
.a2
;
6720 rop_mask
.xor = (0xff & codes
.x1
) ^ codes
.x2
;
6724 rop_mask
.and = (0x00 & codes
.a1
) ^ codes
.a2
;
6725 rop_mask
.xor = (0x00 & codes
.x1
) ^ codes
.x2
;
6727 *and_bits
|= (rop_mask
.and & pixel_masks_1
[x
]);
6728 *xor_bits
|= (rop_mask
.xor & pixel_masks_1
[x
]);
6730 and_bits
+= dib
->stride
;
6731 xor_bits
+= dib
->stride
;
6735 static void create_dither_masks_null(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
6739 static inline void rop_codes_from_stretch_mode( int mode
, struct rop_codes
*codes
)
6744 case STRETCH_DELETESCANS
:
6745 get_rop_codes( R2_COPYPEN
, codes
);
6747 case STRETCH_ORSCANS
:
6748 get_rop_codes( R2_MERGEPEN
, codes
);
6750 case STRETCH_ANDSCANS
:
6751 get_rop_codes( R2_MASKPEN
, codes
);
6757 static void stretch_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
6758 const dib_info
*src_dib
, const POINT
*src_start
,
6759 const struct stretch_params
*params
, int mode
,
6762 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
6763 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
6764 int err
= params
->err_start
;
6767 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
6769 for (width
= params
->length
; width
; width
--)
6771 *dst_ptr
= *src_ptr
;
6772 dst_ptr
+= params
->dst_inc
;
6775 src_ptr
+= params
->src_inc
;
6776 err
+= params
->err_add_1
;
6778 else err
+= params
->err_add_2
;
6783 struct rop_codes codes
;
6785 rop_codes_from_stretch_mode( mode
, &codes
);
6786 for (width
= params
->length
; width
; width
--)
6788 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
6789 dst_ptr
+= params
->dst_inc
;
6792 src_ptr
+= params
->src_inc
;
6793 err
+= params
->err_add_1
;
6795 else err
+= params
->err_add_2
;
6800 static void stretch_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
6801 const dib_info
*src_dib
, const POINT
*src_start
,
6802 const struct stretch_params
*params
, int mode
,
6805 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
6806 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
6807 int err
= params
->err_start
;
6810 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
6812 for (width
= params
->length
; width
; width
--)
6814 dst_ptr
[0] = src_ptr
[0];
6815 dst_ptr
[1] = src_ptr
[1];
6816 dst_ptr
[2] = src_ptr
[2];
6817 dst_ptr
+= 3 * params
->dst_inc
;
6820 src_ptr
+= 3 * params
->src_inc
;
6821 err
+= params
->err_add_1
;
6823 else err
+= params
->err_add_2
;
6828 struct rop_codes codes
;
6830 rop_codes_from_stretch_mode( mode
, &codes
);
6831 for (width
= params
->length
; width
; width
--)
6833 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
6834 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
6835 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
6836 dst_ptr
+= 3 * params
->dst_inc
;
6839 src_ptr
+= 3 * params
->src_inc
;
6840 err
+= params
->err_add_1
;
6842 else err
+= params
->err_add_2
;
6847 static void stretch_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
6848 const dib_info
*src_dib
, const POINT
*src_start
,
6849 const struct stretch_params
*params
, int mode
,
6852 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
6853 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
6854 int err
= params
->err_start
;
6857 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
6859 for (width
= params
->length
; width
; width
--)
6861 *dst_ptr
= *src_ptr
;
6862 dst_ptr
+= params
->dst_inc
;
6865 src_ptr
+= params
->src_inc
;
6866 err
+= params
->err_add_1
;
6868 else err
+= params
->err_add_2
;
6873 struct rop_codes codes
;
6875 rop_codes_from_stretch_mode( mode
, &codes
);
6876 for (width
= params
->length
; width
; width
--)
6878 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
6879 dst_ptr
+= params
->dst_inc
;
6882 src_ptr
+= params
->src_inc
;
6883 err
+= params
->err_add_1
;
6885 else err
+= params
->err_add_2
;
6890 static void stretch_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
6891 const dib_info
*src_dib
, const POINT
*src_start
,
6892 const struct stretch_params
*params
, int mode
,
6895 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
6896 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
6897 int err
= params
->err_start
;
6900 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
6902 for (width
= params
->length
; width
; width
--)
6904 *dst_ptr
= *src_ptr
;
6905 dst_ptr
+= params
->dst_inc
;
6908 src_ptr
+= params
->src_inc
;
6909 err
+= params
->err_add_1
;
6911 else err
+= params
->err_add_2
;
6916 struct rop_codes codes
;
6918 rop_codes_from_stretch_mode( mode
, &codes
);
6919 for (width
= params
->length
; width
; width
--)
6921 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
6922 dst_ptr
+= params
->dst_inc
;
6925 src_ptr
+= params
->src_inc
;
6926 err
+= params
->err_add_1
;
6928 else err
+= params
->err_add_2
;
6933 static void stretch_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
6934 const dib_info
*src_dib
, const POINT
*src_start
,
6935 const struct stretch_params
*params
, int mode
,
6938 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
6939 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
6940 int err
= params
->err_start
;
6941 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
6942 struct rop_codes codes
;
6945 if (!keep_dst
) mode
= STRETCH_DELETESCANS
;
6946 rop_codes_from_stretch_mode( mode
, &codes
);
6947 for (width
= params
->length
; width
; width
--)
6949 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
6950 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
6952 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
6954 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
6955 dst_ptr
+= params
->dst_inc
;
6956 dst_x
+= params
->dst_inc
;
6960 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
6961 src_ptr
+= params
->src_inc
;
6962 src_x
+= params
->src_inc
;
6963 err
+= params
->err_add_1
;
6965 else err
+= params
->err_add_2
;
6969 static void stretch_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
6970 const dib_info
*src_dib
, const POINT
*src_start
,
6971 const struct stretch_params
*params
, int mode
,
6974 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
6975 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
6976 int err
= params
->err_start
;
6977 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
6978 struct rop_codes codes
;
6981 if (!keep_dst
) mode
= STRETCH_DELETESCANS
;
6982 rop_codes_from_stretch_mode( mode
, &codes
);
6983 for (width
= params
->length
; width
; width
--)
6985 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
6986 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
6988 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
6989 dst_ptr
+= params
->dst_inc
;
6990 dst_x
+= params
->dst_inc
;
6994 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
6995 src_ptr
+= params
->src_inc
;
6996 src_x
+= params
->src_inc
;
6997 err
+= params
->err_add_1
;
6999 else err
+= params
->err_add_2
;
7003 static void stretch_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
7004 const dib_info
*src_dib
, const POINT
*src_start
,
7005 const struct stretch_params
*params
, int mode
,
7008 FIXME("bit count %d\n", dst_dib
->bit_count
);
7012 static void shrink_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
7013 const dib_info
*src_dib
, const POINT
*src_start
,
7014 const struct stretch_params
*params
, int mode
,
7017 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
7018 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
7019 int err
= params
->err_start
;
7022 if (mode
== STRETCH_DELETESCANS
)
7024 for (width
= params
->length
; width
; width
--)
7026 *dst_ptr
= *src_ptr
;
7027 src_ptr
+= params
->src_inc
;
7030 dst_ptr
+= params
->dst_inc
;
7031 err
+= params
->err_add_1
;
7033 else err
+= params
->err_add_2
;
7038 struct rop_codes codes
;
7039 DWORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
7040 BOOL new_pix
= TRUE
;
7042 rop_codes_from_stretch_mode( mode
, &codes
);
7043 for (width
= params
->length
; width
; width
--)
7045 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
7046 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
7048 src_ptr
+= params
->src_inc
;
7051 dst_ptr
+= params
->dst_inc
;
7053 err
+= params
->err_add_1
;
7055 else err
+= params
->err_add_2
;
7060 static void shrink_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
7061 const dib_info
*src_dib
, const POINT
*src_start
,
7062 const struct stretch_params
*params
, int mode
,
7065 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
7066 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
7067 int err
= params
->err_start
;
7070 if (mode
== STRETCH_DELETESCANS
)
7072 for (width
= params
->length
; width
; width
--)
7074 dst_ptr
[0] = src_ptr
[0];
7075 dst_ptr
[1] = src_ptr
[1];
7076 dst_ptr
[2] = src_ptr
[2];
7077 src_ptr
+= 3 * params
->src_inc
;
7080 dst_ptr
+= 3 * params
->dst_inc
;
7081 err
+= params
->err_add_1
;
7083 else err
+= params
->err_add_2
;
7088 struct rop_codes codes
;
7089 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
7090 BOOL new_pix
= TRUE
;
7092 rop_codes_from_stretch_mode( mode
, &codes
);
7093 for (width
= params
->length
; width
; width
--)
7095 if (new_pix
&& !keep_dst
) memset( dst_ptr
, init_val
, 3 );
7096 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
7097 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
7098 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
7100 src_ptr
+= 3 * params
->src_inc
;
7103 dst_ptr
+= 3 * params
->dst_inc
;
7105 err
+= params
->err_add_1
;
7107 else err
+= params
->err_add_2
;
7112 static void shrink_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
7113 const dib_info
*src_dib
, const POINT
*src_start
,
7114 const struct stretch_params
*params
, int mode
,
7117 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
7118 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
7119 int err
= params
->err_start
;
7122 if (mode
== STRETCH_DELETESCANS
)
7124 for (width
= params
->length
; width
; width
--)
7126 *dst_ptr
= *src_ptr
;
7127 src_ptr
+= params
->src_inc
;
7130 dst_ptr
+= params
->dst_inc
;
7131 err
+= params
->err_add_1
;
7133 else err
+= params
->err_add_2
;
7138 struct rop_codes codes
;
7139 WORD init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xffff : 0;
7140 BOOL new_pix
= TRUE
;
7142 rop_codes_from_stretch_mode( mode
, &codes
);
7143 for (width
= params
->length
; width
; width
--)
7145 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
7146 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
7148 src_ptr
+= params
->src_inc
;
7151 dst_ptr
+= params
->dst_inc
;
7153 err
+= params
->err_add_1
;
7155 else err
+= params
->err_add_2
;
7160 static void shrink_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
7161 const dib_info
*src_dib
, const POINT
*src_start
,
7162 const struct stretch_params
*params
, int mode
,
7165 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
7166 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
7167 int err
= params
->err_start
;
7170 if (mode
== STRETCH_DELETESCANS
)
7172 for (width
= params
->length
; width
; width
--)
7174 *dst_ptr
= *src_ptr
;
7175 src_ptr
+= params
->src_inc
;
7178 dst_ptr
+= params
->dst_inc
;
7179 err
+= params
->err_add_1
;
7181 else err
+= params
->err_add_2
;
7186 struct rop_codes codes
;
7187 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
7188 BOOL new_pix
= TRUE
;
7190 rop_codes_from_stretch_mode( mode
, &codes
);
7191 for (width
= params
->length
; width
; width
--)
7193 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
7194 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
7196 src_ptr
+= params
->src_inc
;
7199 dst_ptr
+= params
->dst_inc
;
7201 err
+= params
->err_add_1
;
7203 else err
+= params
->err_add_2
;
7208 static void shrink_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
7209 const dib_info
*src_dib
, const POINT
*src_start
,
7210 const struct stretch_params
*params
, int mode
,
7213 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
7214 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
7215 int err
= params
->err_start
;
7216 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
7217 struct rop_codes codes
;
7218 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
7219 BOOL new_pix
= TRUE
;
7221 rop_codes_from_stretch_mode( mode
, &codes
);
7222 for (width
= params
->length
; width
; width
--)
7224 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, (dst_x
& 1) ? 0x0f : 0xf0 );
7226 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
7227 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
7229 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
7232 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
7233 src_ptr
+= params
->src_inc
;
7234 src_x
+= params
->src_inc
;
7238 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
7239 dst_ptr
+= params
->dst_inc
;
7240 dst_x
+= params
->dst_inc
;
7242 err
+= params
->err_add_1
;
7244 else err
+= params
->err_add_2
;
7248 static void shrink_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
7249 const dib_info
*src_dib
, const POINT
*src_start
,
7250 const struct stretch_params
*params
, int mode
,
7253 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
7254 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
7255 int err
= params
->err_start
;
7256 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
7257 struct rop_codes codes
;
7258 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
7259 BOOL new_pix
= TRUE
;
7261 rop_codes_from_stretch_mode( mode
, &codes
);
7262 for (width
= params
->length
; width
; width
--)
7264 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, pixel_masks_1
[dst_x
% 8] );
7265 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
7266 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
7269 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
7270 src_ptr
+= params
->src_inc
;
7271 src_x
+= params
->src_inc
;
7275 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
7276 dst_ptr
+= params
->dst_inc
;
7277 dst_x
+= params
->dst_inc
;
7279 err
+= params
->err_add_1
;
7281 else err
+= params
->err_add_2
;
7285 static void shrink_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
7286 const dib_info
*src_dib
, const POINT
*src_start
,
7287 const struct stretch_params
*params
, int mode
,
7290 FIXME("bit count %d\n", dst_dib
->bit_count
);
7294 const primitive_funcs funcs_8888
=
7304 draw_subpixel_glyph_8888
,
7306 colorref_to_pixel_888
,
7307 pixel_to_colorref_888
,
7309 create_rop_masks_32
,
7310 create_dither_masks_null
,
7315 const primitive_funcs funcs_32
=
7325 draw_subpixel_glyph_32
,
7327 colorref_to_pixel_masks
,
7328 pixel_to_colorref_masks
,
7330 create_rop_masks_32
,
7331 create_dither_masks_null
,
7336 const primitive_funcs funcs_24
=
7346 draw_subpixel_glyph_24
,
7348 colorref_to_pixel_888
,
7349 pixel_to_colorref_888
,
7351 create_rop_masks_24
,
7352 create_dither_masks_null
,
7357 const primitive_funcs funcs_555
=
7367 draw_subpixel_glyph_555
,
7369 colorref_to_pixel_555
,
7370 pixel_to_colorref_555
,
7372 create_rop_masks_16
,
7373 create_dither_masks_null
,
7378 const primitive_funcs funcs_16
=
7388 draw_subpixel_glyph_16
,
7390 colorref_to_pixel_masks
,
7391 pixel_to_colorref_masks
,
7393 create_rop_masks_16
,
7394 create_dither_masks_null
,
7399 const primitive_funcs funcs_8
=
7409 draw_subpixel_glyph_null
,
7411 colorref_to_pixel_colortable
,
7412 pixel_to_colorref_colortable
,
7415 create_dither_masks_8
,
7420 const primitive_funcs funcs_4
=
7430 draw_subpixel_glyph_null
,
7432 colorref_to_pixel_colortable
,
7433 pixel_to_colorref_colortable
,
7436 create_dither_masks_4
,
7441 const primitive_funcs funcs_1
=
7451 draw_subpixel_glyph_null
,
7453 colorref_to_pixel_colortable
,
7454 pixel_to_colorref_colortable
,
7457 create_dither_masks_1
,
7462 const primitive_funcs funcs_null
=
7472 draw_subpixel_glyph_null
,
7474 colorref_to_pixel_null
,
7475 pixel_to_colorref_null
,
7477 create_rop_masks_null
,
7478 create_dither_masks_null
,