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
27 #include "ntgdi_private.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(dib
);
34 /* Bayer matrices for dithering */
36 static const BYTE bayer_4x4
[4][4] =
44 static const BYTE bayer_8x8
[8][8] =
46 { 0, 32, 8, 40, 2, 34, 10, 42 },
47 { 48, 16, 56, 24, 50, 18, 58, 26 },
48 { 12, 44, 4, 36, 14, 46, 6, 38 },
49 { 60, 28, 52, 20, 62, 30, 54, 22 },
50 { 3, 35, 11, 43, 1, 33, 9, 41 },
51 { 51, 19, 59, 27, 49, 17, 57, 25 },
52 { 15, 47, 7, 39, 13, 45, 5, 37 },
53 { 63, 31, 55, 23, 61, 29, 53, 21 }
56 static const BYTE bayer_16x16
[16][16] =
58 { 0, 128, 32, 160, 8, 136, 40, 168, 2, 130, 34, 162, 10, 138, 42, 170 },
59 { 192, 64, 224, 96, 200, 72, 232, 104, 194, 66, 226, 98, 202, 74, 234, 106 },
60 { 48, 176, 16, 144, 56, 184, 24, 152, 50, 178, 18, 146, 58, 186, 26, 154 },
61 { 240, 112, 208, 80, 248, 120, 216, 88, 242, 114, 210, 82, 250, 122, 218, 90 },
62 { 12, 140, 44, 172, 4, 132, 36, 164, 14, 142, 46, 174, 6, 134, 38, 166 },
63 { 204, 76, 236, 108, 196, 68, 228, 100, 206, 78, 238, 110, 198, 70, 230, 102 },
64 { 60, 188, 28, 156, 52, 180, 20, 148, 62, 190, 30, 158, 54, 182, 22, 150 },
65 { 252, 124, 220, 92, 244, 116, 212, 84, 254, 126, 222, 94, 246, 118, 214, 86 },
66 { 3, 131, 35, 163, 11, 139, 43, 171, 1, 129, 33, 161, 9, 137, 41, 169 },
67 { 195, 67, 227, 99, 203, 75, 235, 107, 193, 65, 225, 97, 201, 73, 233, 105 },
68 { 51, 179, 19, 147, 59, 187, 27, 155, 49, 177, 17, 145, 57, 185, 25, 153 },
69 { 243, 115, 211, 83, 251, 123, 219, 91, 241, 113, 209, 81, 249, 121, 217, 89 },
70 { 15, 143, 47, 175, 7, 135, 39, 167, 13, 141, 45, 173, 5, 133, 37, 165 },
71 { 207, 79, 239, 111, 199, 71, 231, 103, 205, 77, 237, 109, 197, 69, 229, 101 },
72 { 63, 191, 31, 159, 55, 183, 23, 151, 61, 189, 29, 157, 53, 181, 21, 149 },
73 { 255, 127, 223, 95, 247, 119, 215, 87, 253, 125, 221, 93, 245, 117, 213, 85 },
76 static inline DWORD
*get_pixel_ptr_32(const dib_info
*dib
, int x
, int y
)
78 return (DWORD
*)((BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) * 4);
81 static inline DWORD
*get_pixel_ptr_24_dword(const dib_info
*dib
, int x
, int y
)
83 return (DWORD
*)((BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
) + (dib
->rect
.left
+ x
) * 3 / 4;
86 static inline BYTE
*get_pixel_ptr_24(const dib_info
*dib
, int x
, int y
)
88 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) * 3;
91 static inline WORD
*get_pixel_ptr_16(const dib_info
*dib
, int x
, int y
)
93 return (WORD
*)((BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) * 2);
96 static inline BYTE
*get_pixel_ptr_8(const dib_info
*dib
, int x
, int y
)
98 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ dib
->rect
.left
+ x
;
101 static inline BYTE
*get_pixel_ptr_4(const dib_info
*dib
, int x
, int y
)
103 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) / 2;
106 static inline BYTE
*get_pixel_ptr_1(const dib_info
*dib
, int x
, int y
)
108 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) / 8;
111 static const BYTE pixel_masks_4
[2] = {0xf0, 0x0f};
112 static const BYTE pixel_masks_1
[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
113 static const BYTE edge_masks_1
[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
115 #define FILTER_DIBINDEX(rgbquad,other_val) \
116 (HIWORD( *(DWORD *)(&rgbquad) ) == 0x10ff ? LOWORD( *(DWORD *)(&rgbquad) ) : (other_val))
118 #define ROPS_WITHOUT_COPY( _d, _s ) \
119 case R2_BLACK: LOOP( (_d) = 0 ) break; \
120 case R2_NOTMERGEPEN: LOOP( (_d) = ~((_d) | (_s)) ) break; \
121 case R2_MASKNOTPEN: LOOP( (_d) &= ~(_s) ) break; \
122 case R2_NOTCOPYPEN: LOOP( (_d) = ~(_s) ) break; \
123 case R2_MASKPENNOT: LOOP( (_d) = (~(_d) & (_s)) ) break; \
124 case R2_NOT: LOOP( (_d) = ~(_d) ) break; \
125 case R2_XORPEN: LOOP( (_d) ^= (_s) ) break; \
126 case R2_NOTMASKPEN: LOOP( (_d) = ~((_d) & (_s)) ) break; \
127 case R2_MASKPEN: LOOP( (_d) &= (_s) ) break; \
128 case R2_NOTXORPEN: LOOP( (_d) = ~((_d) ^ (_s)) ) break; \
129 case R2_NOP: break; \
130 case R2_MERGENOTPEN: LOOP( (_d) = ((_d) | ~(_s)) ) break; \
131 case R2_MERGEPENNOT: LOOP( (_d) = (~(_d) | (_s)) ) break; \
132 case R2_MERGEPEN: LOOP( (_d) |= (_s) ) break; \
133 case R2_WHITE: LOOP( (_d) = ~0 ) break;
135 #define ROPS_ALL( _d, _s ) \
136 case R2_COPYPEN: LOOP( (_d) = (_s) ) break; \
137 ROPS_WITHOUT_COPY( (_d), (_s) )
139 static inline void do_rop_32(DWORD
*ptr
, DWORD
and, DWORD
xor)
141 *ptr
= (*ptr
& and) ^ xor;
144 static inline void do_rop_16(WORD
*ptr
, WORD
and, WORD
xor)
146 *ptr
= (*ptr
& and) ^ xor;
149 static inline void do_rop_8(BYTE
*ptr
, BYTE
and, BYTE
xor)
151 *ptr
= (*ptr
& and) ^ xor;
154 static inline void do_rop_mask_8(BYTE
*ptr
, BYTE
and, BYTE
xor, BYTE mask
)
156 *ptr
= (*ptr
& (and | ~mask
)) ^ (xor & mask
);
159 static inline void do_rop_codes_32(DWORD
*dst
, DWORD src
, struct rop_codes
*codes
)
161 do_rop_32( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
164 static inline void do_rop_codes_16(WORD
*dst
, WORD src
, struct rop_codes
*codes
)
166 do_rop_16( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
169 static inline void do_rop_codes_8(BYTE
*dst
, BYTE src
, struct rop_codes
*codes
)
171 do_rop_8( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
174 static inline void do_rop_codes_mask_8(BYTE
*dst
, BYTE src
, struct rop_codes
*codes
, BYTE mask
)
176 do_rop_mask_8( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
, mask
);
179 static inline void do_rop_codes_line_16(WORD
*dst
, const WORD
*src
, struct rop_codes
*codes
, int len
)
181 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_16( dst
, *src
, codes
);
184 static inline void do_rop_codes_line_rev_16(WORD
*dst
, const WORD
*src
, struct rop_codes
*codes
, int len
)
186 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
187 do_rop_codes_16( dst
, *src
, codes
);
190 static inline void do_rop_codes_line_8(BYTE
*dst
, const BYTE
*src
, struct rop_codes
*codes
, int len
)
192 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_8( dst
, *src
, codes
);
195 static inline void do_rop_codes_line_rev_8(BYTE
*dst
, const BYTE
*src
, struct rop_codes
*codes
, int len
)
197 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
198 do_rop_codes_8( dst
, *src
, codes
);
201 static inline void do_rop_codes_line_4(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
202 struct rop_codes
*codes
, int len
)
206 for (src
+= src_x
/ 2, dst
+= dst_x
/ 2; len
> 0; len
--, dst_x
++, src_x
++)
210 if (src_x
& 1) src_val
= *src
++;
211 else src_val
= *src
>> 4;
212 do_rop_codes_mask_8( dst
++, src_val
, codes
, 0x0f );
216 if (src_x
& 1) src_val
= *src
++ << 4;
218 do_rop_codes_mask_8( dst
, src_val
, codes
, 0xf0 );
223 static inline void do_rop_codes_line_rev_4(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
224 struct rop_codes
*codes
, int len
)
230 for (src
+= src_x
/ 2, dst
+= dst_x
/ 2; len
> 0; len
--, dst_x
--, src_x
--)
234 if (src_x
& 1) src_val
= *src
;
235 else src_val
= *src
-- >> 4;
236 do_rop_codes_mask_8( dst
, src_val
, codes
, 0x0f );
240 if (src_x
& 1) src_val
= *src
<< 4;
241 else src_val
= *src
--;
242 do_rop_codes_mask_8( dst
--, src_val
, codes
, 0xf0 );
247 static inline void memset_32( DWORD
*start
, DWORD val
, DWORD size
)
249 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
251 __asm__
__volatile__( "cld; rep; stosl"
252 : "=c" (dummy
), "=D" (dummy
)
253 : "a" (val
), "0" (size
), "1" (start
) );
255 while (size
--) *start
++ = val
;
259 static inline void memset_16( WORD
*start
, WORD val
, DWORD size
)
261 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
263 __asm__
__volatile__( "cld; rep; stosw"
264 : "=c" (dummy
), "=D" (dummy
)
265 : "a" (val
), "0" (size
), "1" (start
) );
267 while (size
--) *start
++ = val
;
271 static void solid_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
276 for(i
= 0; i
< num
; i
++, rc
++)
278 assert( !IsRectEmpty( rc
));
280 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
282 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
283 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
284 do_rop_32(ptr
++, and, xor);
286 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
287 memset_32( start
, xor, rc
->right
- rc
->left
);
291 static void solid_rects_24(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
294 BYTE
*byte_ptr
, *byte_start
;
296 DWORD and_masks
[3], xor_masks
[3];
298 and_masks
[0] = ( and & 0x00ffffff) | ((and << 24) & 0xff000000);
299 and_masks
[1] = ((and >> 8) & 0x0000ffff) | ((and << 16) & 0xffff0000);
300 and_masks
[2] = ((and >> 16) & 0x000000ff) | ((and << 8) & 0xffffff00);
301 xor_masks
[0] = ( xor & 0x00ffffff) | ((xor << 24) & 0xff000000);
302 xor_masks
[1] = ((xor >> 8) & 0x0000ffff) | ((xor << 16) & 0xffff0000);
303 xor_masks
[2] = ((xor >> 16) & 0x000000ff) | ((xor << 8) & 0xffffff00);
305 for(i
= 0; i
< num
; i
++, rc
++)
307 int left
= dib
->rect
.left
+ rc
->left
;
308 int right
= dib
->rect
.left
+ rc
->right
;
310 assert( !IsRectEmpty( rc
));
312 if ((left
& ~3) == (right
& ~3)) /* Special case for lines that start and end in the same DWORD triplet */
314 byte_start
= get_pixel_ptr_24(dib
, rc
->left
, rc
->top
);
315 for(y
= rc
->top
; y
< rc
->bottom
; y
++, byte_start
+= dib
->stride
)
317 for(x
= left
, byte_ptr
= byte_start
; x
< right
; x
++)
319 do_rop_8(byte_ptr
++, and_masks
[0] & 0xff, xor_masks
[0] & 0xff);
320 do_rop_8(byte_ptr
++, and_masks
[1] & 0xff, xor_masks
[1] & 0xff);
321 do_rop_8(byte_ptr
++, and_masks
[2] & 0xff, xor_masks
[2] & 0xff);
327 start
= get_pixel_ptr_24_dword(dib
, rc
->left
, rc
->top
);
328 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
335 do_rop_32(ptr
++, and_masks
[0] | 0x00ffffff, xor_masks
[0] & 0xff000000);
336 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
337 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
340 do_rop_32(ptr
++, and_masks
[1] | 0x0000ffff, xor_masks
[1] & 0xffff0000);
341 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
344 do_rop_32(ptr
++, and_masks
[2] | 0x000000ff, xor_masks
[2] & 0xffffff00);
348 for(x
= (left
+ 3) & ~3; x
< (right
& ~3); x
+= 4)
350 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
351 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
352 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
358 do_rop_32(ptr
, and_masks
[0] | 0xff000000, xor_masks
[0] & 0x00ffffff);
361 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
362 do_rop_32(ptr
, and_masks
[1] | 0xffff0000, xor_masks
[1] & 0x0000ffff);
365 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
366 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
367 do_rop_32(ptr
, and_masks
[2] | 0xffffff00, xor_masks
[2] & 0x000000ff);
374 start
= get_pixel_ptr_24_dword(dib
, rc
->left
, rc
->top
);
375 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
382 do_rop_32(ptr
++, 0x00ffffff, xor_masks
[0] & 0xff000000);
383 *ptr
++ = xor_masks
[1];
384 *ptr
++ = xor_masks
[2];
387 do_rop_32(ptr
++, 0x0000ffff, xor_masks
[1] & 0xffff0000);
388 *ptr
++ = xor_masks
[2];
391 do_rop_32(ptr
++, 0x000000ff, xor_masks
[2] & 0xffffff00);
395 for(x
= (left
+ 3) & ~3; x
< (right
& ~3); x
+= 4)
397 *ptr
++ = xor_masks
[0];
398 *ptr
++ = xor_masks
[1];
399 *ptr
++ = xor_masks
[2];
405 do_rop_32(ptr
, 0xff000000, xor_masks
[0] & 0x00ffffff);
408 *ptr
++ = xor_masks
[0];
409 do_rop_32(ptr
, 0xffff0000, xor_masks
[1] & 0x0000ffff);
412 *ptr
++ = xor_masks
[0];
413 *ptr
++ = xor_masks
[1];
414 do_rop_32(ptr
, 0xffffff00, xor_masks
[2] & 0x000000ff);
422 static void solid_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
427 for(i
= 0; i
< num
; i
++, rc
++)
429 assert( !IsRectEmpty( rc
));
431 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
433 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
434 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
435 do_rop_16(ptr
++, and, xor);
437 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
438 memset_16( start
, xor, rc
->right
- rc
->left
);
442 static void solid_rects_8(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
447 for(i
= 0; i
< num
; i
++, rc
++)
449 assert( !IsRectEmpty( rc
));
451 start
= get_pixel_ptr_8(dib
, rc
->left
, rc
->top
);
453 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
454 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
455 do_rop_8(ptr
++, and, xor);
457 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
458 memset( start
, xor, rc
->right
- rc
->left
);
462 static void solid_rects_4(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
466 BYTE byte_and
= (and & 0xf) | ((and << 4) & 0xf0);
467 BYTE byte_xor
= (xor & 0xf) | ((xor << 4) & 0xf0);
469 for(i
= 0; i
< num
; i
++, rc
++)
471 int left
= dib
->rect
.left
+ rc
->left
;
472 int right
= dib
->rect
.left
+ rc
->right
;
474 assert( !IsRectEmpty( rc
));
476 start
= get_pixel_ptr_4(dib
, rc
->left
, rc
->top
);
479 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
482 if(left
& 1) /* upper nibble untouched */
483 do_rop_8(ptr
++, byte_and
| 0xf0, byte_xor
& 0x0f);
485 for(x
= (left
+ 1) & ~1; x
< (right
& ~1); x
+= 2)
486 do_rop_8(ptr
++, byte_and
, byte_xor
);
488 if(right
& 1) /* lower nibble untouched */
489 do_rop_8(ptr
, byte_and
| 0x0f, byte_xor
& 0xf0);
494 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
496 unsigned int byte_len
= (right
- ((left
+ 1) & ~1)) / 2;
499 if(left
& 1) /* upper nibble untouched */
500 do_rop_8(ptr
++, 0xf0, byte_xor
& 0x0f);
502 memset( ptr
, byte_xor
, byte_len
);
504 if(right
& 1) /* lower nibble untouched */
505 do_rop_8(ptr
+ byte_len
, 0x0f, byte_xor
& 0xf0);
511 static void solid_rects_1(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
515 BYTE byte_and
= (and & 1) ? 0xff : 0;
516 BYTE byte_xor
= (xor & 1) ? 0xff : 0;
518 for(i
= 0; i
< num
; i
++, rc
++)
520 int left
= dib
->rect
.left
+ rc
->left
;
521 int right
= dib
->rect
.left
+ rc
->right
;
523 assert( !IsRectEmpty( rc
));
525 start
= get_pixel_ptr_1(dib
, rc
->left
, rc
->top
);
527 if ((left
& ~7) == (right
& ~7)) /* Special case for lines that start and end in the same byte */
529 BYTE mask
= edge_masks_1
[left
& 7] & ~edge_masks_1
[right
& 7];
531 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
533 do_rop_8(start
, byte_and
| ~mask
, byte_xor
& mask
);
538 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
543 do_rop_8(ptr
++, byte_and
| ~edge_masks_1
[left
& 7], byte_xor
& edge_masks_1
[left
& 7]);
545 for(x
= (left
+ 7) & ~7; x
< (right
& ~7); x
+= 8)
546 do_rop_8(ptr
++, byte_and
, byte_xor
);
549 /* this is inverted wrt start mask */
550 do_rop_8(ptr
, byte_and
| edge_masks_1
[right
& 7], byte_xor
& ~edge_masks_1
[right
& 7]);
555 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
557 unsigned int byte_len
= (right
- ((left
+ 7) & ~7)) / 8;
562 do_rop_8(ptr
++, ~edge_masks_1
[left
& 7], byte_xor
& edge_masks_1
[left
& 7]);
564 memset( ptr
, byte_xor
, byte_len
);
567 do_rop_8(ptr
+ byte_len
, edge_masks_1
[right
& 7], byte_xor
& ~edge_masks_1
[right
& 7]);
573 static void solid_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
578 static void solid_line_32(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
579 DWORD
and, DWORD
xor)
581 DWORD
*ptr
= get_pixel_ptr_32( dib
, start
->x
, start
->y
);
582 int len
= params
->length
, err
= params
->err_start
;
583 int major_inc
, minor_inc
;
587 major_inc
= params
->x_inc
;
588 minor_inc
= (dib
->stride
* params
->y_inc
) / 4;
592 major_inc
= (dib
->stride
* params
->y_inc
) / 4;
593 minor_inc
= params
->x_inc
;
598 do_rop_32( ptr
, and, xor );
599 if (err
+ params
->bias
> 0)
602 err
+= params
->err_add_1
;
604 else err
+= params
->err_add_2
;
609 static void solid_line_24(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
610 DWORD
and, DWORD
xor)
612 BYTE
*ptr
= get_pixel_ptr_24( dib
, start
->x
, start
->y
);
613 int len
= params
->length
, err
= params
->err_start
;
614 int major_inc
, minor_inc
;
618 major_inc
= params
->x_inc
* 3;
619 minor_inc
= dib
->stride
* params
->y_inc
;
623 major_inc
= dib
->stride
* params
->y_inc
;
624 minor_inc
= params
->x_inc
* 3;
629 do_rop_8( ptr
, and, xor );
630 do_rop_8( ptr
+ 1, and >> 8, xor >> 8 );
631 do_rop_8( ptr
+ 2, and >> 16, xor >> 16 );
632 if (err
+ params
->bias
> 0)
635 err
+= params
->err_add_1
;
637 else err
+= params
->err_add_2
;
642 static void solid_line_16(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
643 DWORD
and, DWORD
xor)
645 WORD
*ptr
= get_pixel_ptr_16( dib
, start
->x
, start
->y
);
646 int len
= params
->length
, err
= params
->err_start
;
647 int major_inc
, minor_inc
;
651 major_inc
= params
->x_inc
;
652 minor_inc
= (dib
->stride
* params
->y_inc
) / 2;
656 major_inc
= (dib
->stride
* params
->y_inc
) / 2;
657 minor_inc
= params
->x_inc
;
662 do_rop_16( ptr
, and, xor );
663 if (err
+ params
->bias
> 0)
666 err
+= params
->err_add_1
;
668 else err
+= params
->err_add_2
;
673 static void solid_line_8(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
674 DWORD
and, DWORD
xor)
676 BYTE
*ptr
= get_pixel_ptr_8( dib
, start
->x
, start
->y
);
677 int len
= params
->length
, err
= params
->err_start
;
678 int major_inc
, minor_inc
;
682 major_inc
= params
->x_inc
;
683 minor_inc
= dib
->stride
* params
->y_inc
;
687 major_inc
= dib
->stride
* params
->y_inc
;
688 minor_inc
= params
->x_inc
;
693 do_rop_8( ptr
, and, xor );
694 if (err
+ params
->bias
> 0)
697 err
+= params
->err_add_1
;
699 else err
+= params
->err_add_2
;
704 static void solid_line_4(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
705 DWORD
and, DWORD
xor)
707 BYTE
*ptr
= get_pixel_ptr_4( dib
, start
->x
, start
->y
);
708 int len
= params
->length
, err
= params
->err_start
;
709 int x
= dib
->rect
.left
+ start
->x
;
711 and = (and & 0x0f) | ((and << 4) & 0xf0);
712 xor = (xor & 0x0f) | ((xor << 4) & 0xf0);
718 do_rop_mask_8( ptr
, and, xor, pixel_masks_4
[ x
% 2 ] );
719 if (err
+ params
->bias
> 0)
721 ptr
+= dib
->stride
* params
->y_inc
;
722 err
+= params
->err_add_1
;
724 else err
+= params
->err_add_2
;
725 if ((x
/ 2) != ((x
+ params
->x_inc
) / 2))
726 ptr
+= params
->x_inc
;
734 do_rop_mask_8( ptr
, and, xor, pixel_masks_4
[ x
% 2 ] );
735 if (err
+ params
->bias
> 0)
737 if ((x
/ 2) != ((x
+ params
->x_inc
) / 2))
738 ptr
+= params
->x_inc
;
740 err
+= params
->err_add_1
;
742 else err
+= params
->err_add_2
;
743 ptr
+= dib
->stride
* params
->y_inc
;
748 static void solid_line_1(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
749 DWORD
and, DWORD
xor)
751 BYTE
*ptr
= get_pixel_ptr_1( dib
, start
->x
, start
->y
);
752 int len
= params
->length
, err
= params
->err_start
;
753 int x
= dib
->rect
.left
+ start
->x
;
755 and = (and & 0x1) ? 0xff : 0;
756 xor = (xor & 0x1) ? 0xff : 0;
762 do_rop_mask_8( ptr
, and, xor, pixel_masks_1
[ x
% 8 ] );
763 if (err
+ params
->bias
> 0)
765 ptr
+= dib
->stride
* params
->y_inc
;
766 err
+= params
->err_add_1
;
768 else err
+= params
->err_add_2
;
769 if ((x
/ 8) != ((x
+ params
->x_inc
) / 8))
770 ptr
+= params
->x_inc
;
778 do_rop_mask_8( ptr
, and, xor, pixel_masks_1
[ x
% 8 ] );
779 if (err
+ params
->bias
> 0)
781 if ((x
/ 8) != ((x
+ params
->x_inc
) / 8))
782 ptr
+= params
->x_inc
;
784 err
+= params
->err_add_1
;
786 else err
+= params
->err_add_2
;
787 ptr
+= dib
->stride
* params
->y_inc
;
792 static void solid_line_null(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
793 DWORD
and, DWORD
xor)
798 static inline INT
calc_offset(INT edge
, INT size
, INT origin
)
802 if(edge
- origin
>= 0)
803 offset
= (edge
- origin
) % size
;
806 offset
= (origin
- edge
) % size
;
807 if(offset
) offset
= size
- offset
;
812 static inline POINT
calc_brush_offset(const RECT
*rc
, const dib_info
*brush
, const POINT
*origin
)
816 offset
.x
= calc_offset(rc
->left
, brush
->width
, origin
->x
);
817 offset
.y
= calc_offset(rc
->top
, brush
->height
, origin
->y
);
822 static void pattern_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
823 const dib_info
*brush
, const rop_mask_bits
*bits
)
825 DWORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
826 int x
, y
, i
, len
, brush_x
;
829 for(i
= 0; i
< num
; i
++, rc
++)
831 offset
= calc_brush_offset(rc
, brush
, origin
);
832 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
833 start_xor
= (DWORD
*)bits
->xor + offset
.y
* brush
->stride
/ 4;
837 start_and
= (DWORD
*)bits
->and + offset
.y
* brush
->stride
/ 4;
839 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
841 and_ptr
= start_and
+ offset
.x
;
842 xor_ptr
= start_xor
+ offset
.x
;
844 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
846 do_rop_32(ptr
++, *and_ptr
++, *xor_ptr
++);
847 if(and_ptr
== start_and
+ brush
->width
)
855 if(offset
.y
== brush
->height
)
857 start_and
= bits
->and;
858 start_xor
= bits
->xor;
863 start_and
+= brush
->stride
/ 4;
864 start_xor
+= brush
->stride
/ 4;
870 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
872 for (x
= rc
->left
, brush_x
= offset
.x
; x
< rc
->right
; x
+= len
)
874 len
= min( rc
->right
- x
, brush
->width
- brush_x
);
875 memcpy( start
+ x
- rc
->left
, start_xor
+ brush_x
, len
* 4 );
879 start_xor
+= brush
->stride
/ 4;
881 if(offset
.y
== brush
->height
)
883 start_xor
= bits
->xor;
891 static void pattern_rects_24(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
892 const dib_info
*brush
, const rop_mask_bits
*bits
)
894 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
895 int x
, y
, i
, len
, brush_x
;
898 for(i
= 0; i
< num
; i
++, rc
++)
900 offset
= calc_brush_offset(rc
, brush
, origin
);
902 start
= get_pixel_ptr_24(dib
, rc
->left
, rc
->top
);
903 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
907 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
908 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
910 and_ptr
= start_and
+ offset
.x
* 3;
911 xor_ptr
= start_xor
+ offset
.x
* 3;
913 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
915 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
916 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
917 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
918 if(and_ptr
== start_and
+ brush
->width
* 3)
926 if(offset
.y
== brush
->height
)
928 start_and
= bits
->and;
929 start_xor
= bits
->xor;
934 start_and
+= brush
->stride
;
935 start_xor
+= brush
->stride
;
941 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
943 for (x
= rc
->left
, brush_x
= offset
.x
; x
< rc
->right
; x
+= len
)
945 len
= min( rc
->right
- x
, brush
->width
- brush_x
);
946 memcpy( start
+ (x
- rc
->left
) * 3, start_xor
+ brush_x
* 3, len
* 3 );
950 start_xor
+= brush
->stride
;
952 if(offset
.y
== brush
->height
)
954 start_xor
= bits
->xor;
962 static void pattern_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
963 const dib_info
*brush
, const rop_mask_bits
*bits
)
965 WORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
966 int x
, y
, i
, len
, brush_x
;
969 for(i
= 0; i
< num
; i
++, rc
++)
971 offset
= calc_brush_offset(rc
, brush
, origin
);
973 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
974 start_xor
= (WORD
*)bits
->xor + offset
.y
* brush
->stride
/ 2;
978 start_and
= (WORD
*)bits
->and + offset
.y
* brush
->stride
/ 2;
979 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
981 and_ptr
= start_and
+ offset
.x
;
982 xor_ptr
= start_xor
+ offset
.x
;
984 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
986 do_rop_16(ptr
++, *and_ptr
++, *xor_ptr
++);
987 if(and_ptr
== start_and
+ brush
->width
)
995 if(offset
.y
== brush
->height
)
997 start_and
= bits
->and;
998 start_xor
= bits
->xor;
1003 start_and
+= brush
->stride
/ 2;
1004 start_xor
+= brush
->stride
/ 2;
1010 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
1012 for (x
= rc
->left
, brush_x
= offset
.x
; x
< rc
->right
; x
+= len
)
1014 len
= min( rc
->right
- x
, brush
->width
- brush_x
);
1015 memcpy( start
+ x
- rc
->left
, start_xor
+ brush_x
, len
* 2 );
1019 start_xor
+= brush
->stride
/ 2;
1021 if(offset
.y
== brush
->height
)
1023 start_xor
= bits
->xor;
1031 static void pattern_rects_8(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1032 const dib_info
*brush
, const rop_mask_bits
*bits
)
1034 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
1035 int x
, y
, i
, len
, brush_x
;
1038 for(i
= 0; i
< num
; i
++, rc
++)
1040 offset
= calc_brush_offset(rc
, brush
, origin
);
1042 start
= get_pixel_ptr_8(dib
, rc
->left
, rc
->top
);
1043 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
1047 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
1048 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1050 and_ptr
= start_and
+ offset
.x
;
1051 xor_ptr
= start_xor
+ offset
.x
;
1053 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
1055 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
1056 if(and_ptr
== start_and
+ brush
->width
)
1058 and_ptr
= start_and
;
1059 xor_ptr
= start_xor
;
1064 if(offset
.y
== brush
->height
)
1066 start_and
= bits
->and;
1067 start_xor
= bits
->xor;
1072 start_and
+= brush
->stride
;
1073 start_xor
+= brush
->stride
;
1079 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1081 for (x
= rc
->left
, brush_x
= offset
.x
; x
< rc
->right
; x
+= len
)
1083 len
= min( rc
->right
- x
, brush
->width
- brush_x
);
1084 memcpy( start
+ x
- rc
->left
, start_xor
+ brush_x
, len
);
1088 start_xor
+= brush
->stride
;
1090 if(offset
.y
== brush
->height
)
1092 start_xor
= bits
->xor;
1100 static void pattern_rects_4(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1101 const dib_info
*brush
, const rop_mask_bits
*bits
)
1103 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
1104 int x
, y
, i
, left
, right
;
1107 for(i
= 0; i
< num
; i
++, rc
++)
1109 offset
= calc_brush_offset(rc
, brush
, origin
);
1110 left
= dib
->rect
.left
+ rc
->left
;
1111 right
= dib
->rect
.left
+ rc
->right
;
1113 start
= get_pixel_ptr_4(dib
, rc
->left
, rc
->top
);
1114 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
1118 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
1119 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1121 INT brush_x
= offset
.x
;
1122 BYTE byte_and
, byte_xor
;
1124 and_ptr
= start_and
+ brush_x
/ 2;
1125 xor_ptr
= start_xor
+ brush_x
/ 2;
1127 for(x
= left
, ptr
= start
; x
< right
; x
++)
1129 /* FIXME: Two pixels at a time */
1130 if(x
& 1) /* lower dst nibble */
1132 if(brush_x
& 1) /* lower pat nibble */
1134 byte_and
= *and_ptr
++ | 0xf0;
1135 byte_xor
= *xor_ptr
++ & 0x0f;
1137 else /* upper pat nibble */
1139 byte_and
= (*and_ptr
>> 4) | 0xf0;
1140 byte_xor
= (*xor_ptr
>> 4) & 0x0f;
1143 else /* upper dst nibble */
1145 if(brush_x
& 1) /* lower pat nibble */
1147 byte_and
= (*and_ptr
++ << 4) | 0x0f;
1148 byte_xor
= (*xor_ptr
++ << 4) & 0xf0;
1150 else /* upper pat nibble */
1152 byte_and
= *and_ptr
| 0x0f;
1153 byte_xor
= *xor_ptr
& 0xf0;
1156 do_rop_8(ptr
, byte_and
, byte_xor
);
1160 if(++brush_x
== brush
->width
)
1163 and_ptr
= start_and
;
1164 xor_ptr
= start_xor
;
1169 if(offset
.y
== brush
->height
)
1171 start_and
= bits
->and;
1172 start_xor
= bits
->xor;
1177 start_and
+= brush
->stride
;
1178 start_xor
+= brush
->stride
;
1184 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1186 INT brush_x
= offset
.x
;
1189 xor_ptr
= start_xor
+ brush_x
/ 2;
1191 for(x
= left
, ptr
= start
; x
< right
; x
++)
1193 /* FIXME: Two pixels at a time */
1194 if(x
& 1) /* lower dst nibble */
1196 if(brush_x
& 1) /* lower pat nibble */
1197 byte_xor
= *xor_ptr
++ & 0x0f;
1198 else /* upper pat nibble */
1199 byte_xor
= (*xor_ptr
>> 4) & 0x0f;
1200 do_rop_8(ptr
, 0xf0, byte_xor
);
1202 else /* upper dst nibble */
1204 if(brush_x
& 1) /* lower pat nibble */
1205 byte_xor
= (*xor_ptr
++ << 4) & 0xf0;
1206 else /* upper pat nibble */
1207 byte_xor
= *xor_ptr
& 0xf0;
1208 do_rop_8(ptr
, 0x0f, byte_xor
);
1213 if(++brush_x
== brush
->width
)
1216 xor_ptr
= start_xor
;
1220 start_xor
+= brush
->stride
;
1222 if(offset
.y
== brush
->height
)
1224 start_xor
= bits
->xor;
1232 static void pattern_rects_1(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1233 const dib_info
*brush
, const rop_mask_bits
*bits
)
1235 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
1236 int x
, y
, i
, left
, right
;
1239 for(i
= 0; i
< num
; i
++, rc
++)
1241 offset
= calc_brush_offset(rc
, brush
, origin
);
1242 left
= dib
->rect
.left
+ rc
->left
;
1243 right
= dib
->rect
.left
+ rc
->right
;
1245 start
= get_pixel_ptr_1(dib
, rc
->left
, rc
->top
);
1246 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
1250 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
1251 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1253 INT brush_x
= offset
.x
;
1254 BYTE byte_and
, byte_xor
;
1256 and_ptr
= start_and
+ brush_x
/ 8;
1257 xor_ptr
= start_xor
+ brush_x
/ 8;
1259 for(x
= left
, ptr
= start
; x
< right
; x
++)
1261 byte_and
= (*and_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
1262 byte_and
|= ~pixel_masks_1
[x
% 8];
1263 byte_xor
= (*xor_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
1264 byte_xor
&= pixel_masks_1
[x
% 8];
1266 do_rop_8(ptr
, byte_and
, byte_xor
);
1268 if((x
& 7) == 7) ptr
++;
1270 if((brush_x
& 7) == 7)
1276 if(++brush_x
== brush
->width
)
1279 and_ptr
= start_and
;
1280 xor_ptr
= start_xor
;
1285 if(offset
.y
== brush
->height
)
1287 start_and
= bits
->and;
1288 start_xor
= bits
->xor;
1293 start_and
+= brush
->stride
;
1294 start_xor
+= brush
->stride
;
1300 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1302 INT brush_x
= offset
.x
;
1304 xor_ptr
= start_xor
+ brush_x
/ 8;
1306 for(x
= left
, ptr
= start
; x
< right
; x
++)
1308 BYTE byte_xor
= (*xor_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
1309 byte_xor
&= pixel_masks_1
[x
% 8];
1311 do_rop_8(ptr
, ~pixel_masks_1
[x
% 8], byte_xor
);
1313 if((x
& 7) == 7) ptr
++;
1314 if((brush_x
& 7) == 7) xor_ptr
++;
1316 if(++brush_x
== brush
->width
)
1319 xor_ptr
= start_xor
;
1323 start_xor
+= brush
->stride
;
1325 if(offset
.y
== brush
->height
)
1327 start_xor
= bits
->xor;
1335 static void pattern_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1336 const dib_info
*brush
, const rop_mask_bits
*bits
)
1341 static inline void copy_rect_bits_32( DWORD
*dst_start
, const DWORD
*src_start
, const SIZE
*size
,
1342 int dst_stride
, int src_stride
, int rop2
)
1348 #define LOOP( op ) \
1349 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1350 for (x = 0, src = src_start, dst = dst_start; x < size->cx; x++, src++, dst++) \
1355 ROPS_WITHOUT_COPY( dst
[0], src
[0] )
1360 static inline void copy_rect_bits_rev_32( DWORD
*dst_start
, const DWORD
*src_start
, const SIZE
*size
,
1361 int dst_stride
, int src_stride
, int rop2
)
1367 src_start
+= size
->cx
- 1;
1368 dst_start
+= size
->cx
- 1;
1370 #define LOOP( op ) \
1371 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1372 for (x = 0, src = src_start, dst = dst_start; x < size->cx; x++, src--, dst--) \
1377 ROPS_WITHOUT_COPY( dst
[0], src
[0] )
1382 static void copy_rect_32(const dib_info
*dst
, const RECT
*rc
,
1383 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1385 DWORD
*dst_start
, *src_start
;
1386 int y
, dst_stride
, src_stride
;
1389 if (overlap
& OVERLAP_BELOW
)
1391 dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->bottom
- 1);
1392 src_start
= get_pixel_ptr_32(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1393 dst_stride
= -dst
->stride
/ 4;
1394 src_stride
= -src
->stride
/ 4;
1398 dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->top
);
1399 src_start
= get_pixel_ptr_32(src
, origin
->x
, origin
->y
);
1400 dst_stride
= dst
->stride
/ 4;
1401 src_stride
= src
->stride
/ 4;
1404 if (rop2
== R2_COPYPEN
)
1406 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1407 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 4 );
1411 size
.cx
= rc
->right
- rc
->left
;
1412 size
.cy
= rc
->bottom
- rc
->top
;
1414 if (overlap
& OVERLAP_RIGHT
)
1415 copy_rect_bits_rev_32( dst_start
, src_start
, &size
, dst_stride
, src_stride
, rop2
);
1417 copy_rect_bits_32( dst_start
, src_start
, &size
, dst_stride
, src_stride
, rop2
);
1420 static void copy_rect_24(const dib_info
*dst
, const RECT
*rc
,
1421 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1423 BYTE
*dst_start
, *src_start
;
1424 int y
, dst_stride
, src_stride
;
1425 struct rop_codes codes
;
1427 if (overlap
& OVERLAP_BELOW
)
1429 dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->bottom
- 1);
1430 src_start
= get_pixel_ptr_24(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1431 dst_stride
= -dst
->stride
;
1432 src_stride
= -src
->stride
;
1436 dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->top
);
1437 src_start
= get_pixel_ptr_24(src
, origin
->x
, origin
->y
);
1438 dst_stride
= dst
->stride
;
1439 src_stride
= src
->stride
;
1442 if (rop2
== R2_COPYPEN
)
1444 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1445 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 3 );
1449 get_rop_codes( rop2
, &codes
);
1450 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1452 if (overlap
& OVERLAP_RIGHT
)
1453 do_rop_codes_line_rev_8( dst_start
, src_start
, &codes
, (rc
->right
- rc
->left
) * 3 );
1455 do_rop_codes_line_8( dst_start
, src_start
, &codes
, (rc
->right
- rc
->left
) * 3 );
1459 static void copy_rect_16(const dib_info
*dst
, const RECT
*rc
,
1460 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1462 WORD
*dst_start
, *src_start
;
1463 int y
, dst_stride
, src_stride
;
1464 struct rop_codes codes
;
1466 if (overlap
& OVERLAP_BELOW
)
1468 dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->bottom
- 1);
1469 src_start
= get_pixel_ptr_16(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1470 dst_stride
= -dst
->stride
/ 2;
1471 src_stride
= -src
->stride
/ 2;
1475 dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->top
);
1476 src_start
= get_pixel_ptr_16(src
, origin
->x
, origin
->y
);
1477 dst_stride
= dst
->stride
/ 2;
1478 src_stride
= src
->stride
/ 2;
1481 if (rop2
== R2_COPYPEN
)
1483 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1484 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 2 );
1488 get_rop_codes( rop2
, &codes
);
1489 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1491 if (overlap
& OVERLAP_RIGHT
)
1492 do_rop_codes_line_rev_16( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1494 do_rop_codes_line_16( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1498 static void copy_rect_8(const dib_info
*dst
, const RECT
*rc
,
1499 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1501 BYTE
*dst_start
, *src_start
;
1502 int y
, dst_stride
, src_stride
;
1503 struct rop_codes codes
;
1505 if (overlap
& OVERLAP_BELOW
)
1507 dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->bottom
- 1);
1508 src_start
= get_pixel_ptr_8(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1509 dst_stride
= -dst
->stride
;
1510 src_stride
= -src
->stride
;
1514 dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->top
);
1515 src_start
= get_pixel_ptr_8(src
, origin
->x
, origin
->y
);
1516 dst_stride
= dst
->stride
;
1517 src_stride
= src
->stride
;
1520 if (rop2
== R2_COPYPEN
)
1522 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1523 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) );
1527 get_rop_codes( rop2
, &codes
);
1528 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1530 if (overlap
& OVERLAP_RIGHT
)
1531 do_rop_codes_line_rev_8( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1533 do_rop_codes_line_8( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1537 static void copy_rect_4(const dib_info
*dst
, const RECT
*rc
,
1538 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1540 BYTE
*dst_start
, *src_start
;
1541 int y
, dst_stride
, src_stride
;
1542 struct rop_codes codes
;
1543 int left
= dst
->rect
.left
+ rc
->left
;
1544 int right
= dst
->rect
.left
+ rc
->right
;
1545 int org_x
= src
->rect
.left
+ origin
->x
;
1547 if (overlap
& OVERLAP_BELOW
)
1549 dst_start
= get_pixel_ptr_4(dst
, rc
->left
, rc
->bottom
- 1);
1550 src_start
= get_pixel_ptr_4(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1551 dst_stride
= -dst
->stride
;
1552 src_stride
= -src
->stride
;
1556 dst_start
= get_pixel_ptr_4(dst
, rc
->left
, rc
->top
);
1557 src_start
= get_pixel_ptr_4(src
, origin
->x
, origin
->y
);
1558 dst_stride
= dst
->stride
;
1559 src_stride
= src
->stride
;
1562 if (rop2
== R2_COPYPEN
&& (left
& 1) == 0 && (org_x
& 1) == 0 && (right
& 1) == 0)
1564 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1565 memmove( dst_start
, src_start
, (right
- left
) / 2 );
1569 get_rop_codes( rop2
, &codes
);
1570 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1572 if (overlap
& OVERLAP_RIGHT
)
1573 do_rop_codes_line_rev_4( dst_start
, left
& 1, src_start
, org_x
& 1, &codes
, right
- left
);
1575 do_rop_codes_line_4( dst_start
, left
& 1, src_start
, org_x
& 1, &codes
, right
- left
);
1579 static inline void copy_rect_bits_partial_1( BYTE
*dst_start
, int dst_x
, const BYTE
*src_start
, int src_x
,
1580 const SIZE
*size
, int dst_stride
, int src_stride
, int rop2
)
1583 BYTE
*dst
, src_val
, mask
;
1584 int dst_end
= dst_x
+ size
->cx
, y
;
1585 int off
= (src_x
& 7) - (dst_x
& 7);
1586 struct rop_codes codes
;
1588 get_rop_codes( rop2
, &codes
);
1590 src_start
+= src_x
/ 8;
1591 dst_start
+= dst_x
/ 8;
1593 for (y
= 0; y
< size
->cy
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1601 src_val
= src
[0] << off
;
1602 if ((dst_end
& 7) + off
> 8)
1603 src_val
|= (src
[1] >> (8 - off
));
1606 src_val
= src
[0] >> -off
;
1608 mask
= edge_masks_1
[dst_x
& 7];
1610 mask
&= ~edge_masks_1
[dst_end
& 7];
1611 do_rop_codes_mask_8( dst
, src_val
, &codes
, mask
);
1615 static inline void copy_rect_bits_align_1( BYTE
*dst_start
, int dst_x
, const BYTE
*src_start
, int src_x
,
1616 const SIZE
*size
, int dst_stride
, int src_stride
, int rop2
)
1620 int y
, i
, full_bytes
, dst_end
= dst_x
+ size
->cx
;
1621 struct rop_codes codes
;
1623 get_rop_codes( rop2
, &codes
);
1625 src_start
+= src_x
/ 8;
1626 dst_start
+= dst_x
/ 8;
1627 full_bytes
= (dst_end
- ((dst_x
+ 7) & ~7)) / 8;
1632 for (y
= 0; y
< size
->cy
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1638 mask
= edge_masks_1
[dst_x
& 7];
1639 do_rop_codes_mask_8( dst
, src
[0], &codes
, mask
);
1643 memmove( dst
, src
, full_bytes
);
1648 mask
= ~edge_masks_1
[dst_end
& 7];
1649 do_rop_codes_mask_8( dst
, src
[0], &codes
, mask
);
1654 #define LOOP( op ) \
1655 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1661 mask = edge_masks_1[dst_x & 7]; \
1662 do_rop_codes_mask_8( dst, src[0], &codes, mask ); \
1666 for (i = 0; i < full_bytes; i++, src++, dst++) \
1670 mask = ~edge_masks_1[dst_end & 7]; \
1671 do_rop_codes_mask_8( dst, src[0], &codes, mask ); \
1675 ROPS_WITHOUT_COPY( dst
[0], src
[0] );
1680 static inline void copy_rect_bits_shl_1( BYTE
*dst_start
, int dst_x
, const BYTE
*src_start
, int src_x
,
1681 const SIZE
*size
, int dst_stride
, int src_stride
, int rop2
)
1684 BYTE
*dst
, mask
, src_val
;
1685 int y
, i
, full_bytes
, dst_end
= dst_x
+ size
->cx
;
1686 int off
= (src_x
& 7) - (dst_x
& 7);
1687 struct rop_codes codes
;
1689 get_rop_codes( rop2
, &codes
);
1691 src_start
+= src_x
/ 8;
1692 dst_start
+= dst_x
/ 8;
1693 full_bytes
= (dst_end
- ((dst_x
+ 7) & ~7)) / 8;
1695 #define LOOP( op ) \
1696 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1702 src_val = (src[0] << off) | (src[1] >> (8 - off)); \
1703 mask = edge_masks_1[dst_x & 7]; \
1704 do_rop_codes_mask_8( dst, src_val, &codes, mask ); \
1708 for (i = 0; i < full_bytes; i++, src++, dst++) \
1712 src_val = src[0] << off; \
1713 if ((dst_end & 7) + off > 8) \
1714 src_val |= (src[1] >> (8 - off)); \
1715 mask = ~edge_masks_1[dst_end & 7]; \
1716 do_rop_codes_mask_8( dst, src_val, &codes, mask ); \
1722 ROPS_ALL( dst
[0], ((src
[0] << off
) | (src
[1] >> (8 - off
))) );
1727 static inline void copy_rect_bits_shr_1( BYTE
*dst_start
, int dst_x
, const BYTE
*src_start
, int src_x
,
1728 const SIZE
*size
, int dst_stride
, int src_stride
, int rop2
)
1731 BYTE
*dst
, mask
, src_val
, last_src
;
1732 int y
, i
, full_bytes
, dst_end
= dst_x
+ size
->cx
;
1733 int off
= (src_x
& 7) - (dst_x
& 7);
1734 struct rop_codes codes
;
1736 get_rop_codes( rop2
, &codes
);
1738 src_start
+= src_x
/ 8;
1739 dst_start
+= dst_x
/ 8;
1740 full_bytes
= (dst_end
- ((dst_x
+ 7) & ~7)) / 8;
1742 #define LOOP( op ) \
1743 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1750 last_src = src[0]; \
1751 mask = edge_masks_1[dst_x & 7]; \
1752 do_rop_codes_mask_8( dst, src[0] >> -off, &codes, mask ); \
1756 for (i = 0; i < full_bytes; i++, src++, dst++) \
1758 src_val = (last_src << (8 + off)) | (src[0] >> -off); \
1759 last_src = src[0]; \
1764 src_val = last_src << (8 + off); \
1765 if ((dst_end & 7) + off > 0) \
1766 src_val |= (src[0] >> -off); \
1767 mask = ~edge_masks_1[dst_end & 7]; \
1768 do_rop_codes_mask_8( dst, src_val, &codes, mask ); \
1774 ROPS_ALL( dst
[0], src_val
)
1779 static inline void copy_rect_bits_rev_align_1( BYTE
*dst_start
, int dst_x
, const BYTE
*src_start
, int src_x
,
1780 const SIZE
*size
, int dst_stride
, int src_stride
, int rop2
)
1784 int y
, i
, full_bytes
, dst_end
= dst_x
+ size
->cx
, src_end
= src_x
+ size
->cx
;
1785 struct rop_codes codes
;
1787 get_rop_codes( rop2
, &codes
);
1789 src_start
+= (src_end
- 1) / 8;
1790 dst_start
+= (dst_end
- 1) / 8;
1791 full_bytes
= (dst_end
- ((dst_x
+ 7) & ~7)) / 8;
1796 for (y
= 0; y
< size
->cy
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1802 mask
= ~edge_masks_1
[dst_end
& 7];
1803 do_rop_codes_mask_8( dst
, src
[0], &codes
, mask
);
1807 memmove( dst
, src
, full_bytes
);
1812 mask
= edge_masks_1
[dst_x
& 7];
1813 do_rop_codes_mask_8( dst
, src
[0], &codes
, mask
);
1818 #define LOOP( op ) \
1819 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1825 mask = ~edge_masks_1[dst_end & 7]; \
1826 do_rop_codes_mask_8( dst, src[0], &codes, mask ); \
1830 for (i = 0; i < full_bytes; i++, src--, dst--) \
1834 mask = edge_masks_1[dst_x & 7]; \
1835 do_rop_codes_mask_8( dst, src[0], &codes, mask ); \
1839 ROPS_WITHOUT_COPY( dst
[0], src
[0] );
1844 static inline void copy_rect_bits_rev_shl_1( BYTE
*dst_start
, int dst_x
, const BYTE
*src_start
, int src_x
,
1845 const SIZE
*size
, int dst_stride
, int src_stride
, int rop2
)
1848 BYTE
*dst
, mask
, src_val
, last_src
;
1849 int y
, i
, full_bytes
, dst_end
= dst_x
+ size
->cx
, src_end
= src_x
+ size
->cx
;
1850 int off
= ((src_end
- 1) & 7) - ((dst_end
- 1) & 7);
1851 struct rop_codes codes
;
1853 get_rop_codes( rop2
, &codes
);
1855 src_start
+= (src_end
- 1) / 8;
1856 dst_start
+= (dst_end
- 1) / 8;
1857 full_bytes
= (dst_end
- ((dst_x
+ 7) & ~7)) / 8;
1859 #define LOOP( op ) \
1860 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1867 last_src = src[0]; \
1868 mask = ~edge_masks_1[dst_end & 7]; \
1869 do_rop_codes_mask_8( dst, src[0] << off, &codes, mask ); \
1873 for (i = 0; i < full_bytes; i++, src--, dst--) \
1875 src_val = (src[0] << off) | (last_src >> (8 - off)); \
1876 last_src = src[0]; \
1881 src_val = last_src >> (8 - off); \
1882 if ((dst_x & 7) + off < 8) \
1883 src_val |= (src[0] << off); \
1884 mask = edge_masks_1[dst_x & 7]; \
1885 do_rop_codes_mask_8( dst, src_val, &codes, mask ); \
1891 ROPS_ALL( dst
[0], src_val
);
1896 static inline void copy_rect_bits_rev_shr_1( BYTE
*dst_start
, int dst_x
, const BYTE
*src_start
, int src_x
,
1897 const SIZE
*size
, int dst_stride
, int src_stride
, int rop2
)
1900 BYTE
*dst
, mask
, src_val
;
1901 int y
, i
, full_bytes
, dst_end
= dst_x
+ size
->cx
, src_end
= src_x
+ size
->cx
;
1902 int off
= ((src_end
- 1) & 7) - ((dst_end
- 1) & 7);
1903 struct rop_codes codes
;
1905 get_rop_codes( rop2
, &codes
);
1907 src_start
+= (src_end
- 1) / 8;
1908 dst_start
+= (dst_end
- 1) / 8;
1909 full_bytes
= (dst_end
- ((dst_x
+ 7) & ~7)) / 8;
1911 #define LOOP( op ) \
1912 for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride) \
1918 mask = edge_masks_1[dst_x & 7]; \
1919 do_rop_codes_mask_8( dst, (src[-1] << (8 + off)) | (src[0] >> -off), &codes, mask ); \
1923 for (i = 0; i < full_bytes; i++, src--, dst--) \
1927 src_val = src[0] >> -off; \
1928 if ((dst_x & 7) + off < 0) \
1929 src_val |= (src[-1] << (8 + off)); \
1930 mask = edge_masks_1[dst_x & 7]; \
1931 do_rop_codes_mask_8( dst, src_val, &codes, mask ); \
1937 ROPS_ALL( dst
[0], (src
[-1] << (8 + off
)) | (src
[0] >> -off
) );
1942 static void copy_rect_1(const dib_info
*dst
, const RECT
*rc
,
1943 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1945 BYTE
*dst_start
, *src_start
;
1946 int y
, dst_stride
, src_stride
;
1947 int left
= dst
->rect
.left
+ rc
->left
;
1948 int right
= dst
->rect
.left
+ rc
->right
;
1949 int org_x
= src
->rect
.left
+ origin
->x
;
1952 if (overlap
& OVERLAP_BELOW
)
1954 dst_start
= get_pixel_ptr_1(dst
, rc
->left
, rc
->bottom
- 1);
1955 src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1956 dst_stride
= -dst
->stride
;
1957 src_stride
= -src
->stride
;
1961 dst_start
= get_pixel_ptr_1(dst
, rc
->left
, rc
->top
);
1962 src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
1963 dst_stride
= dst
->stride
;
1964 src_stride
= src
->stride
;
1967 if (rop2
== R2_COPYPEN
&& (left
& 7) == 0 && (org_x
& 7) == 0 && (right
& 7) == 0)
1969 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1970 memmove( dst_start
, src_start
, (right
- left
) / 8 );
1974 size
.cx
= right
- left
;
1975 size
.cy
= rc
->bottom
- rc
->top
;
1977 /* Special case starting and finishing in same byte, neither on byte boundary */
1978 if ((left
& 7) && (right
& 7) && (left
& ~7) == (right
& ~7))
1979 copy_rect_bits_partial_1( dst_start
, left
& 7, src_start
, org_x
& 7, &size
, dst_stride
, src_stride
, rop2
);
1980 else if (overlap
& OVERLAP_RIGHT
)
1982 int off
= ((org_x
+ right
- left
- 1) & 7) - ((right
- 1) & 7);
1985 copy_rect_bits_rev_align_1( dst_start
, left
& 7, src_start
, org_x
& 7, &size
, dst_stride
, src_stride
, rop2
);
1987 copy_rect_bits_rev_shl_1( dst_start
, left
& 7, src_start
, org_x
& 7, &size
, dst_stride
, src_stride
, rop2
);
1989 copy_rect_bits_rev_shr_1( dst_start
, left
& 7, src_start
, org_x
& 7, &size
, dst_stride
, src_stride
, rop2
);
1993 int off
= (org_x
& 7) - (left
& 7);
1996 copy_rect_bits_align_1( dst_start
, left
& 7, src_start
, org_x
& 7, &size
, dst_stride
, src_stride
, rop2
);
1998 copy_rect_bits_shl_1( dst_start
, left
& 7, src_start
, org_x
& 7, &size
, dst_stride
, src_stride
, rop2
);
2000 copy_rect_bits_shr_1( dst_start
, left
& 7, src_start
, org_x
& 7, &size
, dst_stride
, src_stride
, rop2
);
2004 static void copy_rect_null(const dib_info
*dst
, const RECT
*rc
,
2005 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
2010 static DWORD
get_pixel_32(const dib_info
*dib
, int x
, int y
)
2012 DWORD
*ptr
= get_pixel_ptr_32( dib
, x
, y
);
2016 static DWORD
get_pixel_24(const dib_info
*dib
, int x
, int y
)
2018 BYTE
*ptr
= get_pixel_ptr_24( dib
, x
, y
);
2019 return ptr
[0] | ((DWORD
)ptr
[1] << 8) | ((DWORD
)ptr
[2] << 16);
2022 static DWORD
get_pixel_16(const dib_info
*dib
, int x
, int y
)
2024 WORD
*ptr
= get_pixel_ptr_16( dib
, x
, y
);
2028 static DWORD
get_pixel_8(const dib_info
*dib
, int x
, int y
)
2030 BYTE
*ptr
= get_pixel_ptr_8( dib
, x
, y
);
2034 static DWORD
get_pixel_4(const dib_info
*dib
, int x
, int y
)
2036 BYTE
*ptr
= get_pixel_ptr_4( dib
, x
, y
);
2038 if ((dib
->rect
.left
+ x
) & 1)
2041 return (*ptr
>> 4) & 0x0f;
2044 static DWORD
get_pixel_1(const dib_info
*dib
, int x
, int y
)
2046 BYTE
*ptr
= get_pixel_ptr_1( dib
, x
, y
);
2047 return (*ptr
& pixel_masks_1
[(dib
->rect
.left
+ x
) & 7]) ? 1 : 0;
2050 static DWORD
get_pixel_null(const dib_info
*dib
, int x
, int y
)
2055 static DWORD
colorref_to_pixel_888(const dib_info
*dib
, COLORREF color
)
2057 return ( ((color
>> 16) & 0xff) | (color
& 0xff00) | ((color
<< 16) & 0xff0000) );
2060 static const DWORD field_masks
[33] =
2062 0x00, /* should never happen */
2063 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff,
2064 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2065 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2066 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2069 static inline DWORD
get_field(DWORD field
, int shift
, int len
)
2071 shift
= shift
- (8 - len
);
2076 field
&= field_masks
[len
];
2077 field
|= field
>> len
;
2081 static inline DWORD
put_field(DWORD field
, int shift
, int len
)
2083 shift
= shift
- (8 - len
);
2084 field
&= field_masks
[len
];
2092 static DWORD
rgb_to_pixel_masks(const dib_info
*dib
, DWORD r
, DWORD g
, DWORD b
)
2094 return put_field(r
, dib
->red_shift
, dib
->red_len
) |
2095 put_field(g
, dib
->green_shift
, dib
->green_len
) |
2096 put_field(b
, dib
->blue_shift
, dib
->blue_len
);
2099 static DWORD
rgbquad_to_pixel_masks(const dib_info
*dib
, RGBQUAD rgb
)
2101 return rgb_to_pixel_masks(dib
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2104 static DWORD
colorref_to_pixel_masks(const dib_info
*dib
, COLORREF colour
)
2106 return rgb_to_pixel_masks(dib
, GetRValue(colour
), GetGValue(colour
), GetBValue(colour
));
2109 static DWORD
colorref_to_pixel_555(const dib_info
*dib
, COLORREF color
)
2111 return ( ((color
>> 19) & 0x1f) | ((color
>> 6) & 0x03e0) | ((color
<< 7) & 0x7c00) );
2114 static DWORD
rgb_to_pixel_colortable(const dib_info
*dib
, BYTE r
, BYTE g
, BYTE b
)
2116 const RGBQUAD
*color_table
= get_dib_color_table( dib
);
2117 int size
= dib
->color_table
? dib
->color_table_size
: 1 << dib
->bit_count
;
2118 int i
, best_index
= 0;
2119 DWORD diff
, best_diff
= 0xffffffff;
2121 for(i
= 0; i
< size
; i
++)
2123 const RGBQUAD
*cur
= color_table
+ i
;
2124 diff
= (r
- cur
->rgbRed
) * (r
- cur
->rgbRed
)
2125 + (g
- cur
->rgbGreen
) * (g
- cur
->rgbGreen
)
2126 + (b
- cur
->rgbBlue
) * (b
- cur
->rgbBlue
);
2134 if(diff
< best_diff
)
2143 static DWORD
rgb_to_pixel_mono(const dib_info
*dib
, BOOL dither
, int x
, int y
,
2144 DWORD src_pixel
, DWORD bg_pixel
, BYTE r
, BYTE g
, BYTE b
)
2148 if (dib
->color_table_size
!= 1)
2152 if (((30 * r
+ 59 * g
+ 11 * b
) / 100 + bayer_16x16
[y
% 16][x
% 16]) > 255) r
= g
= b
= 255;
2155 ret
= rgb_to_pixel_colortable( dib
, r
, g
, b
);
2157 else ret
= (src_pixel
== bg_pixel
); /* only match raw pixel value */
2159 return ret
? 0xff : 0;
2162 static DWORD
rgbquad_to_pixel_colortable(const dib_info
*dib
, RGBQUAD rgb
)
2164 return rgb_to_pixel_colortable( dib
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
2167 static DWORD
colorref_to_pixel_colortable(const dib_info
*dib
, COLORREF color
)
2169 return rgb_to_pixel_colortable( dib
, GetRValue(color
), GetGValue(color
), GetBValue(color
) );
2172 static DWORD
colorref_to_pixel_null(const dib_info
*dib
, COLORREF color
)
2177 static COLORREF
pixel_to_colorref_888(const dib_info
*dib
, DWORD pixel
)
2179 return ( ((pixel
>> 16) & 0xff) | (pixel
& 0xff00) | ((pixel
<< 16) & 0xff0000) );
2182 static COLORREF
pixel_to_colorref_masks(const dib_info
*dib
, DWORD pixel
)
2184 return RGB( get_field( pixel
, dib
->red_shift
, dib
->red_len
),
2185 get_field( pixel
, dib
->green_shift
, dib
->green_len
),
2186 get_field( pixel
, dib
->blue_shift
, dib
->blue_len
) );
2189 static COLORREF
pixel_to_colorref_555(const dib_info
*dib
, DWORD pixel
)
2191 return RGB( ((pixel
>> 7) & 0xf8) | ((pixel
>> 12) & 0x07),
2192 ((pixel
>> 2) & 0xf8) | ((pixel
>> 7) & 0x07),
2193 ((pixel
<< 3) & 0xf8) | ((pixel
>> 2) & 0x07) );
2196 static COLORREF
pixel_to_colorref_colortable(const dib_info
*dib
, DWORD pixel
)
2198 const RGBQUAD
*color_table
= get_dib_color_table( dib
);
2200 if (!dib
->color_table
|| pixel
< dib
->color_table_size
)
2202 RGBQUAD quad
= color_table
[pixel
];
2203 return RGB( quad
.rgbRed
, quad
.rgbGreen
, quad
.rgbBlue
);
2208 static COLORREF
pixel_to_colorref_null(const dib_info
*dib
, DWORD pixel
)
2213 static inline BOOL
bit_fields_match(const dib_info
*d1
, const dib_info
*d2
)
2215 assert( d1
->bit_count
> 8 && d1
->bit_count
== d2
->bit_count
);
2217 return d1
->red_mask
== d2
->red_mask
&&
2218 d1
->green_mask
== d2
->green_mask
&&
2219 d1
->blue_mask
== d2
->blue_mask
;
2222 static void convert_to_8888(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2224 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
2225 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
2227 switch(src
->bit_count
)
2231 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2232 if(src
->funcs
== &funcs_8888
)
2234 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2235 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2238 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2240 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
2241 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2242 dst_start
+= dst
->stride
/ 4;
2243 src_start
+= src
->stride
/ 4;
2247 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
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
++ = (((src_val
>> src
->red_shift
) & 0xff) << 16) |
2257 (((src_val
>> src
->green_shift
) & 0xff) << 8) |
2258 ((src_val
>> src
->blue_shift
) & 0xff);
2260 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2261 dst_start
+= dst
->stride
/ 4;
2262 src_start
+= src
->stride
/ 4;
2267 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2269 dst_pixel
= dst_start
;
2270 src_pixel
= src_start
;
2271 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2273 src_val
= *src_pixel
++;
2274 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
2275 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
2276 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
2278 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2279 dst_start
+= dst
->stride
/ 4;
2280 src_start
+= src
->stride
/ 4;
2288 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2290 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2292 dst_pixel
= dst_start
;
2293 src_pixel
= src_start
;
2294 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2297 rgb
.rgbBlue
= *src_pixel
++;
2298 rgb
.rgbGreen
= *src_pixel
++;
2299 rgb
.rgbRed
= *src_pixel
++;
2301 *dst_pixel
++ = ((rgb
.rgbRed
<< 16) & 0xff0000) | ((rgb
.rgbGreen
<< 8) & 0x00ff00) | (rgb
.rgbBlue
& 0x0000ff);
2303 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2304 dst_start
+= dst
->stride
/ 4;
2305 src_start
+= src
->stride
;
2312 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2313 if(src
->funcs
== &funcs_555
)
2315 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2317 dst_pixel
= dst_start
;
2318 src_pixel
= src_start
;
2319 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2321 src_val
= *src_pixel
++;
2322 *dst_pixel
++ = ((src_val
<< 9) & 0xf80000) | ((src_val
<< 4) & 0x070000) |
2323 ((src_val
<< 6) & 0x00f800) | ((src_val
<< 1) & 0x000700) |
2324 ((src_val
<< 3) & 0x0000f8) | ((src_val
>> 2) & 0x000007);
2326 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2327 dst_start
+= dst
->stride
/ 4;
2328 src_start
+= src
->stride
/ 2;
2331 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2333 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2335 dst_pixel
= dst_start
;
2336 src_pixel
= src_start
;
2337 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2339 src_val
= *src_pixel
++;
2340 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
2341 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
2342 (((src_val
>> src
->green_shift
) << 11) & 0x00f800) |
2343 (((src_val
>> src
->green_shift
) << 6) & 0x000700) |
2344 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
2345 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
2347 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2348 dst_start
+= dst
->stride
/ 4;
2349 src_start
+= src
->stride
/ 2;
2352 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2354 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2356 dst_pixel
= dst_start
;
2357 src_pixel
= src_start
;
2358 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2360 src_val
= *src_pixel
++;
2361 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
2362 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
2363 (((src_val
>> src
->green_shift
) << 10) & 0x00fc00) |
2364 (((src_val
>> src
->green_shift
) << 4) & 0x000300) |
2365 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
2366 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
2368 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2369 dst_start
+= dst
->stride
/ 4;
2370 src_start
+= src
->stride
/ 2;
2375 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2377 dst_pixel
= dst_start
;
2378 src_pixel
= src_start
;
2379 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2381 src_val
= *src_pixel
++;
2382 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
2383 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
2384 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
2386 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2387 dst_start
+= dst
->stride
/ 4;
2388 src_start
+= src
->stride
/ 2;
2396 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2397 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2398 DWORD dst_colors
[256], i
;
2400 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
2401 dst_colors
[i
] = color_table
[i
].rgbRed
<< 16 | color_table
[i
].rgbGreen
<< 8 |
2402 color_table
[i
].rgbBlue
;
2404 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2406 dst_pixel
= dst_start
;
2407 src_pixel
= src_start
;
2408 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2409 *dst_pixel
++ = dst_colors
[*src_pixel
++];
2411 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2412 dst_start
+= dst
->stride
/ 4;
2413 src_start
+= src
->stride
;
2420 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2421 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2422 DWORD dst_colors
[16], i
;
2424 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
2425 dst_colors
[i
] = color_table
[i
].rgbRed
<< 16 | color_table
[i
].rgbGreen
<< 8 |
2426 color_table
[i
].rgbBlue
;
2428 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2430 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2431 src_pixel
= src_start
;
2432 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2435 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
2437 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
2439 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2440 dst_start
+= dst
->stride
/ 4;
2441 src_start
+= src
->stride
;
2448 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2449 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2450 DWORD dst_colors
[2], i
;
2452 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
2453 dst_colors
[i
] = color_table
[i
].rgbRed
<< 16 | color_table
[i
].rgbGreen
<< 8 |
2454 color_table
[i
].rgbBlue
;
2456 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2458 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2459 for(x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2461 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2462 dst_start
[x
] = dst_colors
[src_val
];
2464 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2465 dst_start
+= dst
->stride
/ 4;
2466 src_start
+= src
->stride
;
2473 static void convert_to_32(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2475 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
2476 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
2478 switch(src
->bit_count
)
2482 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2484 if(src
->funcs
== &funcs_8888
)
2486 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2488 dst_pixel
= dst_start
;
2489 src_pixel
= src_start
;
2490 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2492 src_val
= *src_pixel
++;
2493 *dst_pixel
++ = rgb_to_pixel_masks(dst
, src_val
>> 16, src_val
>> 8, src_val
);
2495 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2496 dst_start
+= dst
->stride
/ 4;
2497 src_start
+= src
->stride
/ 4;
2500 else if(bit_fields_match(src
, dst
))
2502 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2503 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2506 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2508 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
2509 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2510 dst_start
+= dst
->stride
/ 4;
2511 src_start
+= src
->stride
/ 4;
2515 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8 &&
2516 dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
2518 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2520 dst_pixel
= dst_start
;
2521 src_pixel
= src_start
;
2522 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2524 src_val
= *src_pixel
++;
2525 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << dst
->red_shift
) |
2526 (((src_val
>> src
->green_shift
) & 0xff) << dst
->green_shift
) |
2527 (((src_val
>> src
->blue_shift
) & 0xff) << dst
->blue_shift
);
2529 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2530 dst_start
+= dst
->stride
/ 4;
2531 src_start
+= src
->stride
/ 4;
2536 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2538 dst_pixel
= dst_start
;
2539 src_pixel
= src_start
;
2540 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2542 src_val
= *src_pixel
++;
2543 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
2544 get_field(src_val
, src
->red_shift
, src
->red_len
),
2545 get_field(src_val
, src
->green_shift
, src
->green_len
),
2546 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2548 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2549 dst_start
+= dst
->stride
/ 4;
2550 src_start
+= src
->stride
/ 4;
2558 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2560 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2562 dst_pixel
= dst_start
;
2563 src_pixel
= src_start
;
2564 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
2565 *dst_pixel
++ = rgb_to_pixel_masks(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
2566 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2567 dst_start
+= dst
->stride
/ 4;
2568 src_start
+= src
->stride
;
2575 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2576 if(src
->funcs
== &funcs_555
)
2578 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2580 dst_pixel
= dst_start
;
2581 src_pixel
= src_start
;
2582 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2584 src_val
= *src_pixel
++;
2585 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
2586 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
2587 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
2588 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07));
2590 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2591 dst_start
+= dst
->stride
/ 4;
2592 src_start
+= src
->stride
/ 2;
2595 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2597 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2599 dst_pixel
= dst_start
;
2600 src_pixel
= src_start
;
2601 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2603 src_val
= *src_pixel
++;
2604 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
2605 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2606 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2607 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2608 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
2609 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2610 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
2612 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2613 dst_start
+= dst
->stride
/ 4;
2614 src_start
+= src
->stride
/ 2;
2617 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2619 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2621 dst_pixel
= dst_start
;
2622 src_pixel
= src_start
;
2623 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2625 src_val
= *src_pixel
++;
2626 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
2627 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2628 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
2629 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2630 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
2631 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2632 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
2634 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2635 dst_start
+= dst
->stride
/ 4;
2636 src_start
+= src
->stride
/ 2;
2641 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2643 dst_pixel
= dst_start
;
2644 src_pixel
= src_start
;
2645 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2647 src_val
= *src_pixel
++;
2648 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
2649 get_field(src_val
, src
->red_shift
, src
->red_len
),
2650 get_field(src_val
, src
->green_shift
, src
->green_len
),
2651 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
2653 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2654 dst_start
+= dst
->stride
/ 4;
2655 src_start
+= src
->stride
/ 2;
2663 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2664 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2665 DWORD dst_colors
[256], i
;
2667 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
2668 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
2670 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2672 dst_pixel
= dst_start
;
2673 src_pixel
= src_start
;
2674 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2675 *dst_pixel
++ = dst_colors
[*src_pixel
++];
2677 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2678 dst_start
+= dst
->stride
/ 4;
2679 src_start
+= src
->stride
;
2686 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2687 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2688 DWORD dst_colors
[16], i
;
2690 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
2691 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
2693 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2695 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2696 src_pixel
= src_start
;
2697 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2700 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
2702 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
2704 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2705 dst_start
+= dst
->stride
/ 4;
2706 src_start
+= src
->stride
;
2713 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2714 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2715 DWORD dst_colors
[2], i
;
2717 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
2718 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
2720 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2722 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2723 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2725 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2726 dst_start
[x
] = dst_colors
[src_val
];
2728 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2729 dst_start
+= dst
->stride
/ 4;
2730 src_start
+= src
->stride
;
2737 static void convert_to_24(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2739 BYTE
*dst_start
= get_pixel_ptr_24(dst
, 0, 0), *dst_pixel
;
2741 int x
, y
, pad_size
= ((dst
->width
* 3 + 3) & ~3) - (src_rect
->right
- src_rect
->left
) * 3;
2743 switch(src
->bit_count
)
2747 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2748 if(src
->funcs
== &funcs_8888
)
2750 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2752 dst_pixel
= dst_start
;
2753 src_pixel
= src_start
;
2754 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2756 src_val
= *src_pixel
++;
2757 *dst_pixel
++ = src_val
& 0xff;
2758 *dst_pixel
++ = (src_val
>> 8) & 0xff;
2759 *dst_pixel
++ = (src_val
>> 16) & 0xff;
2761 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2762 dst_start
+= dst
->stride
;
2763 src_start
+= src
->stride
/ 4;
2766 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2768 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2770 dst_pixel
= dst_start
;
2771 src_pixel
= src_start
;
2772 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2774 src_val
= *src_pixel
++;
2775 *dst_pixel
++ = (src_val
>> src
->blue_shift
) & 0xff;
2776 *dst_pixel
++ = (src_val
>> src
->green_shift
) & 0xff;
2777 *dst_pixel
++ = (src_val
>> src
->red_shift
) & 0xff;
2779 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2780 dst_start
+= dst
->stride
;
2781 src_start
+= src
->stride
/ 4;
2786 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2788 dst_pixel
= dst_start
;
2789 src_pixel
= src_start
;
2790 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2792 src_val
= *src_pixel
++;
2793 *dst_pixel
++ = get_field( src_val
, src
->blue_shift
, src
->blue_len
);
2794 *dst_pixel
++ = get_field( src_val
, src
->green_shift
, src
->green_len
);
2795 *dst_pixel
++ = get_field( src_val
, src
->red_shift
, src
->red_len
);
2797 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2798 dst_start
+= dst
->stride
;
2799 src_start
+= src
->stride
/ 4;
2807 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
);
2809 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2810 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2813 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2815 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 3);
2816 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
) * 3, 0, pad_size
);
2817 dst_start
+= dst
->stride
;
2818 src_start
+= src
->stride
;
2826 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2827 if(src
->funcs
== &funcs_555
)
2829 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2831 dst_pixel
= dst_start
;
2832 src_pixel
= src_start
;
2833 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2835 src_val
= *src_pixel
++;
2836 *dst_pixel
++ = ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07);
2837 *dst_pixel
++ = ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07);
2838 *dst_pixel
++ = ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07);
2840 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2841 dst_start
+= dst
->stride
;
2842 src_start
+= src
->stride
/ 2;
2845 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2847 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2849 dst_pixel
= dst_start
;
2850 src_pixel
= src_start
;
2851 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2853 src_val
= *src_pixel
++;
2854 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2855 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
2856 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2857 (((src_val
>> src
->green_shift
) >> 2) & 0x07);
2858 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2859 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
2861 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2862 dst_start
+= dst
->stride
;
2863 src_start
+= src
->stride
/ 2;
2866 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2868 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2870 dst_pixel
= dst_start
;
2871 src_pixel
= src_start
;
2872 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2874 src_val
= *src_pixel
++;
2875 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2876 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
2877 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2878 (((src_val
>> src
->green_shift
) >> 4) & 0x03);
2879 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2880 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
2882 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2883 dst_start
+= dst
->stride
;
2884 src_start
+= src
->stride
/ 2;
2889 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2891 dst_pixel
= dst_start
;
2892 src_pixel
= src_start
;
2893 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2895 src_val
= *src_pixel
++;
2896 *dst_pixel
++ = get_field(src_val
, src
->blue_shift
, src
->blue_len
);
2897 *dst_pixel
++ = get_field(src_val
, src
->green_shift
, src
->green_len
);
2898 *dst_pixel
++ = get_field(src_val
, src
->red_shift
, src
->red_len
);
2900 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2901 dst_start
+= dst
->stride
;
2902 src_start
+= src
->stride
/ 2;
2910 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2911 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2912 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2914 dst_pixel
= dst_start
;
2915 src_pixel
= src_start
;
2916 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2918 RGBQUAD rgb
= color_table
[*src_pixel
++];
2919 *dst_pixel
++ = rgb
.rgbBlue
;
2920 *dst_pixel
++ = rgb
.rgbGreen
;
2921 *dst_pixel
++ = rgb
.rgbRed
;
2923 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2924 dst_start
+= dst
->stride
;
2925 src_start
+= src
->stride
;
2932 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2933 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2934 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2936 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2937 src_pixel
= src_start
;
2938 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2942 rgb
= color_table
[*src_pixel
++ & 0xf];
2944 rgb
= color_table
[*src_pixel
>> 4];
2945 dst_start
[x
* 3] = rgb
.rgbBlue
;
2946 dst_start
[x
* 3 + 1] = rgb
.rgbGreen
;
2947 dst_start
[x
* 3 + 2] = rgb
.rgbRed
;
2949 if(pad_size
) memset(dst_start
+ x
* 3, 0, pad_size
);
2950 dst_start
+= dst
->stride
;
2951 src_start
+= src
->stride
;
2958 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2959 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2960 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2962 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2963 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2966 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2967 rgb
= color_table
[src_val
];
2968 dst_start
[x
* 3] = rgb
.rgbBlue
;
2969 dst_start
[x
* 3 + 1] = rgb
.rgbGreen
;
2970 dst_start
[x
* 3 + 2] = rgb
.rgbRed
;
2972 if(pad_size
) memset(dst_start
+ x
* 3, 0, pad_size
);
2973 dst_start
+= dst
->stride
;
2974 src_start
+= src
->stride
;
2981 static void convert_to_555(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2983 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
2984 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
2987 switch(src
->bit_count
)
2991 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2993 if(src
->funcs
== &funcs_8888
)
2995 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2997 dst_pixel
= dst_start
;
2998 src_pixel
= src_start
;
2999 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3001 src_val
= *src_pixel
++;
3002 *dst_pixel
++ = ((src_val
>> 9) & 0x7c00) |
3003 ((src_val
>> 6) & 0x03e0) |
3004 ((src_val
>> 3) & 0x001f);
3006 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3007 dst_start
+= dst
->stride
/ 2;
3008 src_start
+= src
->stride
/ 4;
3011 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3013 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3015 dst_pixel
= dst_start
;
3016 src_pixel
= src_start
;
3017 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3019 src_val
= *src_pixel
++;
3020 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 7) & 0x7c00) |
3021 (((src_val
>> src
->green_shift
) << 2) & 0x03e0) |
3022 (((src_val
>> src
->blue_shift
) >> 3) & 0x001f);
3024 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3025 dst_start
+= dst
->stride
/ 2;
3026 src_start
+= src
->stride
/ 4;
3031 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3033 dst_pixel
= dst_start
;
3034 src_pixel
= src_start
;
3035 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3037 src_val
= *src_pixel
++;
3038 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
3039 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
3040 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
3042 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3043 dst_start
+= dst
->stride
/ 2;
3044 src_start
+= src
->stride
/ 4;
3052 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3054 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3056 dst_pixel
= dst_start
;
3057 src_pixel
= src_start
;
3058 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3061 rgb
.rgbBlue
= *src_pixel
++;
3062 rgb
.rgbGreen
= *src_pixel
++;
3063 rgb
.rgbRed
= *src_pixel
++;
3065 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
3066 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
3067 ((rgb
.rgbBlue
>> 3) & 0x001f);
3069 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3070 dst_start
+= dst
->stride
/ 2;
3071 src_start
+= src
->stride
;
3078 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3079 if(src
->funcs
== &funcs_555
)
3081 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
3082 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3085 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3087 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
3088 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
3089 dst_start
+= dst
->stride
/ 2;
3090 src_start
+= src
->stride
/ 2;
3094 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3096 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3098 dst_pixel
= dst_start
;
3099 src_pixel
= src_start
;
3100 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3102 src_val
= *src_pixel
++;
3103 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
3104 (((src_val
>> src
->green_shift
) << 5) & 0x03e0) |
3105 ( (src_val
>> src
->blue_shift
) & 0x001f);
3107 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3108 dst_start
+= dst
->stride
/ 2;
3109 src_start
+= src
->stride
/ 2;
3112 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3114 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3116 dst_pixel
= dst_start
;
3117 src_pixel
= src_start
;
3118 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3120 src_val
= *src_pixel
++;
3121 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
3122 (((src_val
>> src
->green_shift
) << 4) & 0x03e0) |
3123 ( (src_val
>> src
->blue_shift
) & 0x001f);
3125 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3126 dst_start
+= dst
->stride
/ 2;
3127 src_start
+= src
->stride
/ 2;
3132 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3134 dst_pixel
= dst_start
;
3135 src_pixel
= src_start
;
3136 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3138 src_val
= *src_pixel
++;
3139 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
3140 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
3141 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
3143 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3144 dst_start
+= dst
->stride
/ 2;
3145 src_start
+= src
->stride
/ 2;
3153 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3154 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3155 WORD dst_colors
[256];
3158 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3159 dst_colors
[i
] = ((color_table
[i
].rgbRed
<< 7) & 0x7c00) |
3160 ((color_table
[i
].rgbGreen
<< 2) & 0x03e0) |
3161 ((color_table
[i
].rgbBlue
>> 3) & 0x001f);
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
++)
3168 *dst_pixel
++ = dst_colors
[*src_pixel
++];
3170 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3171 dst_start
+= dst
->stride
/ 2;
3172 src_start
+= src
->stride
;
3179 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3180 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3181 WORD dst_colors
[16];
3184 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3185 dst_colors
[i
] = ((color_table
[i
].rgbRed
<< 7) & 0x7c00) |
3186 ((color_table
[i
].rgbGreen
<< 2) & 0x03e0) |
3187 ((color_table
[i
].rgbBlue
>> 3) & 0x001f);
3189 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3191 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3192 src_pixel
= src_start
;
3193 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3196 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
3198 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
3200 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3201 dst_start
+= dst
->stride
/ 2;
3202 src_start
+= src
->stride
;
3209 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3210 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3214 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3215 dst_colors
[i
] = ((color_table
[i
].rgbRed
<< 7) & 0x7c00) |
3216 ((color_table
[i
].rgbGreen
<< 2) & 0x03e0) |
3217 ((color_table
[i
].rgbBlue
>> 3) & 0x001f);
3219 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3221 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3222 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3224 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3225 dst_start
[x
] = dst_colors
[src_val
];
3227 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3228 dst_start
+= dst
->stride
/ 2;
3229 src_start
+= src
->stride
;
3236 static void convert_to_16(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3238 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
3239 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
3242 switch(src
->bit_count
)
3246 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3248 if(src
->funcs
== &funcs_8888
)
3250 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3252 dst_pixel
= dst_start
;
3253 src_pixel
= src_start
;
3254 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3256 src_val
= *src_pixel
++;
3257 *dst_pixel
++ = rgb_to_pixel_masks(dst
, src_val
>> 16, src_val
>> 8, src_val
);
3259 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3260 dst_start
+= dst
->stride
/ 2;
3261 src_start
+= src
->stride
/ 4;
3264 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3266 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3268 dst_pixel
= dst_start
;
3269 src_pixel
= src_start
;
3270 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3272 src_val
= *src_pixel
++;
3273 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3274 src_val
>> src
->red_shift
,
3275 src_val
>> src
->green_shift
,
3276 src_val
>> src
->blue_shift
);
3278 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3279 dst_start
+= dst
->stride
/ 2;
3280 src_start
+= src
->stride
/ 4;
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
++ = rgb_to_pixel_masks(dst
,
3293 get_field(src_val
, src
->red_shift
, src
->red_len
),
3294 get_field(src_val
, src
->green_shift
, src
->green_len
),
3295 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3297 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3298 dst_start
+= dst
->stride
/ 2;
3299 src_start
+= src
->stride
/ 4;
3307 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3309 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3311 dst_pixel
= dst_start
;
3312 src_pixel
= src_start
;
3313 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3314 *dst_pixel
++ = rgb_to_pixel_masks(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
3315 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3316 dst_start
+= dst
->stride
/ 2;
3317 src_start
+= src
->stride
;
3324 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3325 if(src
->funcs
== &funcs_555
)
3327 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3329 dst_pixel
= dst_start
;
3330 src_pixel
= src_start
;
3331 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3333 src_val
= *src_pixel
++;
3334 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3335 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3336 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3337 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07));
3339 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3340 dst_start
+= dst
->stride
/ 2;
3341 src_start
+= src
->stride
/ 2;
3344 else if(bit_fields_match(src
, dst
))
3346 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
3347 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3350 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3352 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
3353 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
3354 dst_start
+= dst
->stride
/ 2;
3355 src_start
+= src
->stride
/ 2;
3359 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3361 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3363 dst_pixel
= dst_start
;
3364 src_pixel
= src_start
;
3365 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3367 src_val
= *src_pixel
++;
3368 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3369 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3370 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3371 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3372 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3373 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3374 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
3376 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3377 dst_start
+= dst
->stride
/ 2;
3378 src_start
+= src
->stride
/ 2;
3381 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3383 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3385 dst_pixel
= dst_start
;
3386 src_pixel
= src_start
;
3387 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3389 src_val
= *src_pixel
++;
3390 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3391 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3392 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3393 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3394 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3395 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3396 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
3398 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3399 dst_start
+= dst
->stride
/ 2;
3400 src_start
+= src
->stride
/ 2;
3405 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3407 dst_pixel
= dst_start
;
3408 src_pixel
= src_start
;
3409 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3411 src_val
= *src_pixel
++;
3412 *dst_pixel
++ = rgb_to_pixel_masks(dst
,
3413 get_field(src_val
, src
->red_shift
, src
->red_len
),
3414 get_field(src_val
, src
->green_shift
, src
->green_len
),
3415 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3417 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3418 dst_start
+= dst
->stride
/ 2;
3419 src_start
+= src
->stride
/ 2;
3427 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3428 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3429 WORD dst_colors
[256];
3432 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3433 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
3435 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3437 dst_pixel
= dst_start
;
3438 src_pixel
= src_start
;
3439 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3440 *dst_pixel
++ = dst_colors
[*src_pixel
++];
3442 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3443 dst_start
+= dst
->stride
/ 2;
3444 src_start
+= src
->stride
;
3451 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3452 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3453 WORD dst_colors
[16];
3456 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3457 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
3459 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3461 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3462 src_pixel
= src_start
;
3463 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3466 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
3468 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
3470 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3471 dst_start
+= dst
->stride
/ 2;
3472 src_start
+= src
->stride
;
3479 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3480 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3484 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3485 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
3487 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3489 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3490 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3492 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3493 dst_start
[x
] = dst_colors
[src_val
];
3495 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3496 dst_start
+= dst
->stride
/ 2;
3497 src_start
+= src
->stride
;
3504 static inline BOOL
color_tables_match(const dib_info
*d1
, const dib_info
*d2
)
3506 if (!d1
->color_table
|| !d2
->color_table
) return (!d1
->color_table
&& !d2
->color_table
);
3507 return !memcmp(d1
->color_table
, d2
->color_table
, (1 << d1
->bit_count
) * sizeof(d1
->color_table
[0]));
3511 * To translate an RGB value into a colour table index Windows uses the 5 msbs of each component.
3512 * We thus create a lookup table with 32^3 entries.
3514 struct rgb_lookup_colortable_ctx
3516 const dib_info
*dib
;
3517 BYTE map
[32 * 32 * 32];
3518 BYTE valid
[32 * 32 * 32 / 8];
3521 static void rgb_lookup_colortable_init(const dib_info
*dib
, struct rgb_lookup_colortable_ctx
*ctx
)
3524 memset(ctx
->valid
, 0, sizeof(ctx
->valid
));
3527 static inline BYTE
rgb_lookup_colortable(struct rgb_lookup_colortable_ctx
*ctx
, DWORD r
, DWORD g
, DWORD b
)
3529 DWORD pos
= ((r
& 0xf8) >> 3) | ((g
& 0xf8) << 2) | ((b
& 0xf8) << 7);
3531 if (!(ctx
->valid
[pos
/ 8] & pixel_masks_1
[pos
& 7]))
3533 ctx
->valid
[pos
/ 8] |= pixel_masks_1
[pos
& 7];
3534 ctx
->map
[pos
] = rgb_to_pixel_colortable(ctx
->dib
, (r
& 0xf8) | 4, (g
& 0xf8) | 4, (b
& 0xf8) | 4);
3536 return ctx
->map
[pos
];
3539 static void convert_to_8(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3541 BYTE
*dst_start
= get_pixel_ptr_8(dst
, 0, 0), *dst_pixel
;
3542 INT x
, y
, pad_size
= ((dst
->width
+ 3) & ~3) - (src_rect
->right
- src_rect
->left
);
3543 struct rgb_lookup_colortable_ctx lookup_ctx
;
3546 switch(src
->bit_count
)
3550 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3552 rgb_lookup_colortable_init(dst
, &lookup_ctx
);
3553 if(src
->funcs
== &funcs_8888
)
3555 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3557 dst_pixel
= dst_start
;
3558 src_pixel
= src_start
;
3559 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3561 src_val
= *src_pixel
++;
3562 *dst_pixel
++ = rgb_lookup_colortable(&lookup_ctx
, src_val
>> 16, src_val
>> 8, src_val
);
3564 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3565 dst_start
+= dst
->stride
;
3566 src_start
+= src
->stride
/ 4;
3569 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3571 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3573 dst_pixel
= dst_start
;
3574 src_pixel
= src_start
;
3575 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3577 src_val
= *src_pixel
++;
3578 *dst_pixel
++ = rgb_lookup_colortable(&lookup_ctx
,
3579 src_val
>> src
->red_shift
,
3580 src_val
>> src
->green_shift
,
3581 src_val
>> src
->blue_shift
);
3583 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3584 dst_start
+= dst
->stride
;
3585 src_start
+= src
->stride
/ 4;
3590 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3592 dst_pixel
= dst_start
;
3593 src_pixel
= src_start
;
3594 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3596 src_val
= *src_pixel
++;
3597 *dst_pixel
++ = rgb_lookup_colortable(&lookup_ctx
,
3598 get_field(src_val
, src
->red_shift
, src
->red_len
),
3599 get_field(src_val
, src
->green_shift
, src
->green_len
),
3600 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3602 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3603 dst_start
+= dst
->stride
;
3604 src_start
+= src
->stride
/ 4;
3612 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3614 rgb_lookup_colortable_init(dst
, &lookup_ctx
);
3615 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3617 dst_pixel
= dst_start
;
3618 src_pixel
= src_start
;
3619 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3621 *dst_pixel
++ = rgb_lookup_colortable(&lookup_ctx
, src_pixel
[2], src_pixel
[1], src_pixel
[0] );
3623 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3624 dst_start
+= dst
->stride
;
3625 src_start
+= src
->stride
;
3632 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3633 rgb_lookup_colortable_init(dst
, &lookup_ctx
);
3634 if(src
->funcs
== &funcs_555
)
3636 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3638 dst_pixel
= dst_start
;
3639 src_pixel
= src_start
;
3640 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3642 src_val
= *src_pixel
++;
3643 *dst_pixel
++ = rgb_lookup_colortable(&lookup_ctx
,
3644 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3645 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3646 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
3648 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3649 dst_start
+= dst
->stride
;
3650 src_start
+= src
->stride
/ 2;
3653 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3655 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3657 dst_pixel
= dst_start
;
3658 src_pixel
= src_start
;
3659 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3661 src_val
= *src_pixel
++;
3662 *dst_pixel
++ = rgb_lookup_colortable(&lookup_ctx
,
3663 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3664 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3665 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3666 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3667 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3668 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3670 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3671 dst_start
+= dst
->stride
;
3672 src_start
+= src
->stride
/ 2;
3675 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3677 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3679 dst_pixel
= dst_start
;
3680 src_pixel
= src_start
;
3681 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3683 src_val
= *src_pixel
++;
3684 *dst_pixel
++ = rgb_lookup_colortable(&lookup_ctx
,
3685 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3686 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3687 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3688 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3689 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3690 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3692 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3693 dst_start
+= dst
->stride
;
3694 src_start
+= src
->stride
/ 2;
3699 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3701 dst_pixel
= dst_start
;
3702 src_pixel
= src_start
;
3703 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3705 src_val
= *src_pixel
++;
3706 *dst_pixel
++ = rgb_lookup_colortable(&lookup_ctx
,
3707 get_field(src_val
, src
->red_shift
, src
->red_len
),
3708 get_field(src_val
, src
->green_shift
, src
->green_len
),
3709 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3711 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3712 dst_start
+= dst
->stride
;
3713 src_start
+= src
->stride
/ 2;
3721 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3723 if(color_tables_match(dst
, src
))
3725 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
3726 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3729 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3731 memcpy(dst_start
, src_start
, src_rect
->right
- src_rect
->left
);
3732 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
3733 dst_start
+= dst
->stride
;
3734 src_start
+= src
->stride
;
3740 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3741 BYTE dst_colors
[256];
3744 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3745 dst_colors
[i
] = rgbquad_to_pixel_colortable(dst
, color_table
[i
]);
3747 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3749 dst_pixel
= dst_start
;
3750 src_pixel
= src_start
;
3751 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3752 *dst_pixel
++ = dst_colors
[*src_pixel
++];
3754 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3755 dst_start
+= dst
->stride
;
3756 src_start
+= src
->stride
;
3764 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3765 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3766 BYTE dst_colors
[16];
3769 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3770 dst_colors
[i
] = rgbquad_to_pixel_colortable(dst
, color_table
[i
]);
3772 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3774 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3775 src_pixel
= src_start
;
3776 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3779 dst_start
[x
] = dst_colors
[*src_pixel
++ & 0xf];
3781 dst_start
[x
] = dst_colors
[*src_pixel
>> 4];
3783 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3784 dst_start
+= dst
->stride
;
3785 src_start
+= src
->stride
;
3792 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3793 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3797 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
3798 dst_colors
[i
] = FILTER_DIBINDEX(color_table
[i
], rgbquad_to_pixel_colortable(dst
, color_table
[i
]));
3800 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3802 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3803 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3805 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3806 dst_start
[x
] = dst_colors
[src_val
];
3808 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3809 dst_start
+= dst
->stride
;
3810 src_start
+= src
->stride
;
3817 static void convert_to_4(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3819 BYTE
*dst_start
= get_pixel_ptr_4(dst
, 0, 0), *dst_pixel
, dst_val
;
3820 INT x
, y
, pad_size
= ((dst
->width
+ 7) & ~7) / 2 - (src_rect
->right
- src_rect
->left
+ 1) / 2;
3823 switch(src
->bit_count
)
3827 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3829 if(src
->funcs
== &funcs_8888
)
3831 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3833 dst_pixel
= dst_start
;
3834 src_pixel
= src_start
;
3835 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3837 src_val
= *src_pixel
++;
3838 dst_val
= rgb_to_pixel_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
3839 if((x
- src_rect
->left
) & 1)
3841 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3845 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3849 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3850 memset(dst_pixel
, 0, pad_size
);
3852 dst_start
+= dst
->stride
;
3853 src_start
+= src
->stride
/ 4;
3856 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3858 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3860 dst_pixel
= dst_start
;
3861 src_pixel
= src_start
;
3862 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3864 src_val
= *src_pixel
++;
3865 dst_val
= rgb_to_pixel_colortable(dst
,
3866 src_val
>> src
->red_shift
,
3867 src_val
>> src
->green_shift
,
3868 src_val
>> src
->blue_shift
);
3869 if((x
- src_rect
->left
) & 1)
3871 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3875 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3879 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3880 memset(dst_pixel
, 0, pad_size
);
3882 dst_start
+= dst
->stride
;
3883 src_start
+= src
->stride
/ 4;
3888 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3890 dst_pixel
= dst_start
;
3891 src_pixel
= src_start
;
3892 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3894 src_val
= *src_pixel
++;
3895 dst_val
= rgb_to_pixel_colortable(dst
,
3896 get_field(src_val
, src
->red_shift
, src
->red_len
),
3897 get_field(src_val
, src
->green_shift
, src
->green_len
),
3898 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3899 if((x
- src_rect
->left
) & 1)
3901 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3905 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3909 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3910 memset(dst_pixel
, 0, pad_size
);
3912 dst_start
+= dst
->stride
;
3913 src_start
+= src
->stride
/ 4;
3921 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3923 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3925 dst_pixel
= dst_start
;
3926 src_pixel
= src_start
;
3927 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3929 dst_val
= rgb_to_pixel_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
3931 if((x
- src_rect
->left
) & 1)
3933 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3937 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3941 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3942 memset(dst_pixel
, 0, pad_size
);
3944 dst_start
+= dst
->stride
;
3945 src_start
+= src
->stride
;
3952 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3953 if(src
->funcs
== &funcs_555
)
3955 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3957 dst_pixel
= dst_start
;
3958 src_pixel
= src_start
;
3959 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3961 src_val
= *src_pixel
++;
3962 dst_val
= rgb_to_pixel_colortable(dst
,
3963 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3964 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3965 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
3966 if((x
- src_rect
->left
) & 1)
3968 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3972 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3976 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3977 memset(dst_pixel
, 0, pad_size
);
3979 dst_start
+= dst
->stride
;
3980 src_start
+= src
->stride
/ 2;
3983 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3985 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3987 dst_pixel
= dst_start
;
3988 src_pixel
= src_start
;
3989 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3991 src_val
= *src_pixel
++;
3992 dst_val
= rgb_to_pixel_colortable(dst
,
3993 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3994 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3995 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3996 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3997 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3998 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
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
/ 2;
4016 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
4018 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4020 dst_pixel
= dst_start
;
4021 src_pixel
= src_start
;
4022 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
4024 src_val
= *src_pixel
++;
4025 dst_val
= rgb_to_pixel_colortable(dst
,
4026 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
4027 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
4028 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
4029 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
4030 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
4031 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
4032 if((x
- src_rect
->left
) & 1)
4034 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4038 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4042 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4043 memset(dst_pixel
, 0, pad_size
);
4045 dst_start
+= dst
->stride
;
4046 src_start
+= src
->stride
/ 2;
4051 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4053 dst_pixel
= dst_start
;
4054 src_pixel
= src_start
;
4055 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
4057 src_val
= *src_pixel
++;
4058 dst_val
= rgb_to_pixel_colortable(dst
,
4059 get_field(src_val
, src
->red_shift
, src
->red_len
),
4060 get_field(src_val
, src
->green_shift
, src
->green_len
),
4061 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
4062 if((x
- src_rect
->left
) & 1)
4064 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4068 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4072 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4073 memset(dst_pixel
, 0, pad_size
);
4075 dst_start
+= dst
->stride
;
4076 src_start
+= src
->stride
/ 2;
4084 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4085 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4086 BYTE dst_colors
[256];
4089 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
4090 dst_colors
[i
] = rgbquad_to_pixel_colortable(dst
, color_table
[i
]);
4092 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4094 dst_pixel
= dst_start
;
4095 src_pixel
= src_start
;
4096 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
4098 dst_val
= dst_colors
[*src_pixel
++];
4099 if((x
- src_rect
->left
) & 1)
4101 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4105 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4109 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4110 memset(dst_pixel
, 0, pad_size
);
4112 dst_start
+= dst
->stride
;
4113 src_start
+= src
->stride
;
4120 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4122 if(color_tables_match(dst
, src
) && ((src
->rect
.left
+ src_rect
->left
) & 1) == 0)
4124 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
4125 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
4128 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4130 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
+ 1) / 2);
4131 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
+ 1) / 2, 0, pad_size
);
4132 dst_start
+= dst
->stride
;
4133 src_start
+= src
->stride
;
4139 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4140 BYTE dst_colors
[16];
4143 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
4144 dst_colors
[i
] = rgbquad_to_pixel_colortable(dst
, color_table
[i
]);
4146 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4148 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
4149 dst_pixel
= dst_start
;
4150 src_pixel
= src_start
;
4151 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, pos
++)
4154 dst_val
= dst_colors
[*src_pixel
++ & 0xf];
4156 dst_val
= dst_colors
[*src_pixel
>> 4];
4157 if((x
- src_rect
->left
) & 1)
4159 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4163 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4167 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4168 memset(dst_pixel
, 0, pad_size
);
4170 dst_start
+= dst
->stride
;
4171 src_start
+= src
->stride
;
4179 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4180 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
4184 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
4185 dst_colors
[i
] = FILTER_DIBINDEX(color_table
[i
], rgbquad_to_pixel_colortable(dst
, color_table
[i
]));
4187 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4189 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
4190 dst_pixel
= dst_start
;
4191 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, pos
++)
4193 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
4194 dst_val
= dst_colors
[src_val
];
4195 if((x
- src_rect
->left
) & 1)
4197 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
4201 *dst_pixel
= (dst_val
<< 4) & 0xf0;
4205 if((x
- src_rect
->left
) & 1) dst_pixel
++;
4206 memset(dst_pixel
, 0, pad_size
);
4208 dst_start
+= dst
->stride
;
4209 src_start
+= src
->stride
;
4216 static void convert_to_1(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
4218 BYTE
*dst_start
= get_pixel_ptr_1(dst
, 0, 0), *dst_pixel
, dst_val
;
4219 INT x
, y
, pad_size
= ((dst
->width
+ 31) & ~31) / 8 - (src_rect
->right
- src_rect
->left
+ 7) / 8;
4220 RGBQUAD rgb
, bg_entry
= *get_dib_color_table( dst
); /* entry 0 is the background color */
4224 switch(src
->bit_count
)
4228 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4229 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, rgbquad_to_pixel_masks(src
, bg_entry
));
4231 if(src
->funcs
== &funcs_8888
)
4233 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4235 dst_pixel
= dst_start
;
4236 src_pixel
= src_start
;
4237 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4239 src_val
= *src_pixel
++;
4240 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4241 src_val
>> 16, src_val
>> 8, src_val
);
4242 if(bit_pos
== 0) *dst_pixel
= 0;
4243 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4253 if(bit_pos
!= 0) dst_pixel
++;
4254 memset(dst_pixel
, 0, pad_size
);
4256 dst_start
+= dst
->stride
;
4257 src_start
+= src
->stride
/ 4;
4260 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
4262 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4264 dst_pixel
= dst_start
;
4265 src_pixel
= src_start
;
4266 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4268 src_val
= *src_pixel
++;
4269 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4270 src_val
>> src
->red_shift
,
4271 src_val
>> src
->green_shift
,
4272 src_val
>> src
->blue_shift
);
4274 if(bit_pos
== 0) *dst_pixel
= 0;
4275 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4285 if(bit_pos
!= 0) dst_pixel
++;
4286 memset(dst_pixel
, 0, pad_size
);
4288 dst_start
+= dst
->stride
;
4289 src_start
+= src
->stride
/ 4;
4294 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4296 dst_pixel
= dst_start
;
4297 src_pixel
= src_start
;
4298 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4300 src_val
= *src_pixel
++;
4301 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4302 get_field(src_val
, src
->red_shift
, src
->red_len
),
4303 get_field(src_val
, src
->green_shift
, src
->green_len
),
4304 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
4306 if(bit_pos
== 0) *dst_pixel
= 0;
4307 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4317 if(bit_pos
!= 0) dst_pixel
++;
4318 memset(dst_pixel
, 0, pad_size
);
4320 dst_start
+= dst
->stride
;
4321 src_start
+= src
->stride
/ 4;
4329 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4330 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, RGB(bg_entry
.rgbRed
, bg_entry
.rgbGreen
, bg_entry
.rgbBlue
));
4332 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4334 dst_pixel
= dst_start
;
4335 src_pixel
= src_start
;
4336 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, src_pixel
+= 3)
4338 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, RGB(src_pixel
[2], src_pixel
[1], src_pixel
[0]),
4339 bg_pixel
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
4341 if(bit_pos
== 0) *dst_pixel
= 0;
4342 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4352 if(bit_pos
!= 0) dst_pixel
++;
4353 memset(dst_pixel
, 0, pad_size
);
4355 dst_start
+= dst
->stride
;
4356 src_start
+= src
->stride
;
4363 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4364 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, rgbquad_to_pixel_masks(src
, bg_entry
));
4366 if(src
->funcs
== &funcs_555
)
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
, src_val
, bg_pixel
,
4376 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
4377 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
4378 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07));
4380 if(bit_pos
== 0) *dst_pixel
= 0;
4381 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4391 if(bit_pos
!= 0) dst_pixel
++;
4392 memset(dst_pixel
, 0, pad_size
);
4394 dst_start
+= dst
->stride
;
4395 src_start
+= src
->stride
/ 2;
4398 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
4400 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4402 dst_pixel
= dst_start
;
4403 src_pixel
= src_start
;
4404 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4406 src_val
= *src_pixel
++;
4407 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4408 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
4409 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
4410 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
4411 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
4412 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
4413 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
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
/ 2;
4432 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
4434 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4436 dst_pixel
= dst_start
;
4437 src_pixel
= src_start
;
4438 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4440 src_val
= *src_pixel
++;
4441 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4442 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
4443 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
4444 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
4445 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
4446 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
4447 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
4448 if(bit_pos
== 0) *dst_pixel
= 0;
4449 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4459 if(bit_pos
!= 0) dst_pixel
++;
4460 memset(dst_pixel
, 0, pad_size
);
4462 dst_start
+= dst
->stride
;
4463 src_start
+= src
->stride
/ 2;
4468 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4470 dst_pixel
= dst_start
;
4471 src_pixel
= src_start
;
4472 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4474 src_val
= *src_pixel
++;
4475 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4476 get_field(src_val
, src
->red_shift
, src
->red_len
),
4477 get_field(src_val
, src
->green_shift
, src
->green_len
),
4478 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
4479 if(bit_pos
== 0) *dst_pixel
= 0;
4480 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4490 if(bit_pos
!= 0) dst_pixel
++;
4491 memset(dst_pixel
, 0, pad_size
);
4493 dst_start
+= dst
->stride
;
4494 src_start
+= src
->stride
/ 2;
4502 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4503 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4504 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, rgbquad_to_pixel_colortable(src
, bg_entry
));
4506 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4508 dst_pixel
= dst_start
;
4509 src_pixel
= src_start
;
4510 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4512 BYTE src_val
= *src_pixel
++;
4513 rgb
= color_table
[src_val
];
4514 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4515 rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
4517 if(bit_pos
== 0) *dst_pixel
= 0;
4518 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4528 if(bit_pos
!= 0) dst_pixel
++;
4529 memset(dst_pixel
, 0, pad_size
);
4531 dst_start
+= dst
->stride
;
4532 src_start
+= src
->stride
;
4539 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4540 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4541 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, rgbquad_to_pixel_colortable(src
, bg_entry
));
4543 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4545 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
4546 dst_pixel
= dst_start
;
4547 src_pixel
= src_start
;
4548 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, pos
++)
4550 src_val
= (pos
& 1) ? *src_pixel
++ & 0xf : *src_pixel
>> 4;
4551 rgb
= color_table
[src_val
];
4552 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4553 rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
4555 if(bit_pos
== 0) *dst_pixel
= 0;
4556 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4566 if(bit_pos
!= 0) dst_pixel
++;
4567 memset(dst_pixel
, 0, pad_size
);
4569 dst_start
+= dst
->stride
;
4570 src_start
+= src
->stride
;
4575 /* Note that while MSDN states that a 1 bpp dib brush -> mono dc
4576 uses text/bkgnd colours instead of the dib's colour table, this
4577 doesn't appear to be the case for a dc backed by a
4582 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4583 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
4584 DWORD bg_pixel
= FILTER_DIBINDEX(bg_entry
, rgbquad_to_pixel_colortable(src
, bg_entry
));
4586 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4588 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
4589 dst_pixel
= dst_start
;
4590 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, pos
++)
4592 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
4593 rgb
= color_table
[src_val
];
4594 dst_val
= FILTER_DIBINDEX(rgb
, rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
, bg_pixel
,
4595 rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
));
4596 if(bit_pos
== 0) *dst_pixel
= 0;
4597 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4607 if(bit_pos
!= 0) dst_pixel
++;
4608 memset(dst_pixel
, 0, pad_size
);
4610 dst_start
+= dst
->stride
;
4611 src_start
+= src
->stride
;
4618 static void convert_to_null(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
4622 static inline BYTE
blend_color(BYTE dst
, BYTE src
, DWORD alpha
)
4624 return (src
* alpha
+ dst
* (255 - alpha
) + 127) / 255;
4627 static inline DWORD
blend_argb_constant_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
4629 return (blend_color( dst
, src
, alpha
) |
4630 blend_color( dst
>> 8, src
>> 8, alpha
) << 8 |
4631 blend_color( dst
>> 16, src
>> 16, alpha
) << 16 |
4632 blend_color( dst
>> 24, src
>> 24, alpha
) << 24);
4635 static inline DWORD
blend_argb_no_src_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
4637 return (blend_color( dst
, src
, alpha
) |
4638 blend_color( dst
>> 8, src
>> 8, alpha
) << 8 |
4639 blend_color( dst
>> 16, src
>> 16, alpha
) << 16 |
4640 blend_color( dst
>> 24, 255, alpha
) << 24);
4643 static inline DWORD
blend_argb( DWORD dst
, DWORD src
)
4646 BYTE g
= (BYTE
)(src
>> 8);
4647 BYTE r
= (BYTE
)(src
>> 16);
4648 DWORD alpha
= (BYTE
)(src
>> 24);
4649 return ((b
+ ((BYTE
)dst
* (255 - alpha
) + 127) / 255) |
4650 (g
+ ((BYTE
)(dst
>> 8) * (255 - alpha
) + 127) / 255) << 8 |
4651 (r
+ ((BYTE
)(dst
>> 16) * (255 - alpha
) + 127) / 255) << 16 |
4652 (alpha
+ ((BYTE
)(dst
>> 24) * (255 - alpha
) + 127) / 255) << 24);
4655 static inline DWORD
blend_argb_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
4657 BYTE b
= ((BYTE
)src
* alpha
+ 127) / 255;
4658 BYTE g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
4659 BYTE r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
4660 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
4661 return ((b
+ ((BYTE
)dst
* (255 - alpha
) + 127) / 255) |
4662 (g
+ ((BYTE
)(dst
>> 8) * (255 - alpha
) + 127) / 255) << 8 |
4663 (r
+ ((BYTE
)(dst
>> 16) * (255 - alpha
) + 127) / 255) << 16 |
4664 (alpha
+ ((BYTE
)(dst
>> 24) * (255 - alpha
) + 127) / 255) << 24);
4667 static inline DWORD
blend_rgb( BYTE dst_r
, BYTE dst_g
, BYTE dst_b
, DWORD src
, BLENDFUNCTION blend
)
4669 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
4671 DWORD alpha
= blend
.SourceConstantAlpha
;
4672 BYTE src_b
= ((BYTE
)src
* alpha
+ 127) / 255;
4673 BYTE src_g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
4674 BYTE src_r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
4675 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
4676 return ((src_b
+ (dst_b
* (255 - alpha
) + 127) / 255) |
4677 (src_g
+ (dst_g
* (255 - alpha
) + 127) / 255) << 8 |
4678 (src_r
+ (dst_r
* (255 - alpha
) + 127) / 255) << 16);
4680 return (blend_color( dst_b
, src
, blend
.SourceConstantAlpha
) |
4681 blend_color( dst_g
, src
>> 8, blend
.SourceConstantAlpha
) << 8 |
4682 blend_color( dst_r
, src
>> 16, blend
.SourceConstantAlpha
) << 16);
4685 static void blend_rects_8888(const dib_info
*dst
, int num
, const RECT
*rc
,
4686 const dib_info
*src
, const POINT
*offset
, BLENDFUNCTION blend
)
4690 for (i
= 0; i
< num
; i
++, rc
++)
4692 DWORD
*src_ptr
= get_pixel_ptr_32( src
, rc
->left
+ offset
->x
, rc
->top
+ offset
->y
);
4693 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
4695 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
4697 if (blend
.SourceConstantAlpha
== 255)
4698 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4699 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4700 dst_ptr
[x
] = blend_argb( dst_ptr
[x
], src_ptr
[x
] );
4702 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4703 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4704 dst_ptr
[x
] = blend_argb_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
4706 else if (src
->compression
== BI_RGB
)
4707 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4708 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4709 dst_ptr
[x
] = blend_argb_constant_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
4711 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4712 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4713 dst_ptr
[x
] = blend_argb_no_src_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
4717 static void blend_rects_32(const dib_info
*dst
, int num
, const RECT
*rc
,
4718 const dib_info
*src
, const POINT
*offset
, BLENDFUNCTION blend
)
4722 for (i
= 0; i
< num
; i
++, rc
++)
4724 DWORD
*src_ptr
= get_pixel_ptr_32( src
, rc
->left
+ offset
->x
, rc
->top
+ offset
->y
);
4725 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
4727 if (dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
4729 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4731 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4733 DWORD val
= blend_rgb( dst_ptr
[x
] >> dst
->red_shift
,
4734 dst_ptr
[x
] >> dst
->green_shift
,
4735 dst_ptr
[x
] >> dst
->blue_shift
,
4736 src_ptr
[x
], blend
);
4737 dst_ptr
[x
] = ((( val
& 0xff) << dst
->blue_shift
) |
4738 (((val
>> 8) & 0xff) << dst
->green_shift
) |
4739 (((val
>> 16) & 0xff) << dst
->red_shift
));
4745 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4747 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4749 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
4750 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
4751 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
4752 src_ptr
[x
], blend
);
4753 dst_ptr
[x
] = rgb_to_pixel_masks( dst
, val
>> 16, val
>> 8, val
);
4760 static void blend_rects_24(const dib_info
*dst
, int num
, const RECT
*rc
,
4761 const dib_info
*src
, const POINT
*offset
, BLENDFUNCTION blend
)
4765 for (i
= 0; i
< num
; i
++, rc
++)
4767 DWORD
*src_ptr
= get_pixel_ptr_32( src
, rc
->left
+ offset
->x
, rc
->top
+ offset
->y
);
4768 BYTE
*dst_ptr
= get_pixel_ptr_24( dst
, rc
->left
, rc
->top
);
4770 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4772 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4774 DWORD val
= blend_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
4775 src_ptr
[x
], blend
);
4776 dst_ptr
[x
* 3] = val
;
4777 dst_ptr
[x
* 3 + 1] = val
>> 8;
4778 dst_ptr
[x
* 3 + 2] = val
>> 16;
4784 static void blend_rects_555(const dib_info
*dst
, int num
, const RECT
*rc
,
4785 const dib_info
*src
, const POINT
*offset
, BLENDFUNCTION blend
)
4789 for (i
= 0; i
< num
; i
++, rc
++)
4791 DWORD
*src_ptr
= get_pixel_ptr_32( src
, rc
->left
+ offset
->x
, rc
->top
+ offset
->y
);
4792 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
4794 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
4796 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4798 DWORD val
= blend_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
4799 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
4800 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
4801 src_ptr
[x
], blend
);
4802 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
4808 static void blend_rects_16(const dib_info
*dst
, int num
, const RECT
*rc
,
4809 const dib_info
*src
, const POINT
*offset
, BLENDFUNCTION blend
)
4813 for (i
= 0; i
< num
; i
++, rc
++)
4815 DWORD
*src_ptr
= get_pixel_ptr_32( src
, rc
->left
+ offset
->x
, rc
->top
+ offset
->y
);
4816 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
4818 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
4820 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4822 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
4823 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
4824 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
4825 src_ptr
[x
], blend
);
4826 dst_ptr
[x
] = rgb_to_pixel_masks( dst
, val
>> 16, val
>> 8, val
);
4832 static void blend_rects_8(const dib_info
*dst
, int num
, const RECT
*rc
,
4833 const dib_info
*src
, const POINT
*offset
, BLENDFUNCTION blend
)
4835 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4836 struct rgb_lookup_colortable_ctx lookup_ctx
;
4839 rgb_lookup_colortable_init( dst
, &lookup_ctx
);
4840 for (i
= 0; i
< num
; i
++, rc
++)
4842 DWORD
*src_ptr
= get_pixel_ptr_32( src
, rc
->left
+ offset
->x
, rc
->top
+ offset
->y
);
4843 BYTE
*dst_ptr
= get_pixel_ptr_8( dst
, rc
->left
, rc
->top
);
4845 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4847 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4849 RGBQUAD rgb
= color_table
[dst_ptr
[x
]];
4850 DWORD val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[x
], blend
);
4851 dst_ptr
[x
] = rgb_lookup_colortable( &lookup_ctx
, val
>> 16, val
>> 8, val
);
4857 static void blend_rects_4(const dib_info
*dst
, int num
, const RECT
*rc
,
4858 const dib_info
*src
, const POINT
*offset
, BLENDFUNCTION blend
)
4860 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4861 struct rgb_lookup_colortable_ctx lookup_ctx
;
4864 rgb_lookup_colortable_init( dst
, &lookup_ctx
);
4865 for (i
= 0; i
< num
; i
++, rc
++)
4867 DWORD
*src_ptr
= get_pixel_ptr_32( src
, rc
->left
+ offset
->x
, rc
->top
+ offset
->y
);
4868 BYTE
*dst_ptr
= get_pixel_ptr_4( dst
, rc
->left
, rc
->top
);
4870 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4872 for (j
= 0, x
= (dst
->rect
.left
+ rc
->left
) & 1; j
< rc
->right
- rc
->left
; j
++, x
++)
4874 DWORD val
= ((x
& 1) ? dst_ptr
[x
/ 2] : (dst_ptr
[x
/ 2] >> 4)) & 0x0f;
4875 RGBQUAD rgb
= color_table
[val
];
4876 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[j
], blend
);
4877 val
= rgb_lookup_colortable( &lookup_ctx
, val
>> 16, val
>> 8, val
);
4879 dst_ptr
[x
/ 2] = val
| (dst_ptr
[x
/ 2] & 0xf0);
4881 dst_ptr
[x
/ 2] = (val
<< 4) | (dst_ptr
[x
/ 2] & 0x0f);
4887 static void blend_rects_1(const dib_info
*dst
, int num
, const RECT
*rc
,
4888 const dib_info
*src
, const POINT
*offset
, BLENDFUNCTION blend
)
4890 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4893 for (i
= 0; i
< num
; i
++, rc
++)
4895 DWORD
*src_ptr
= get_pixel_ptr_32( src
, rc
->left
+ offset
->x
, rc
->top
+ offset
->y
);
4896 BYTE
*dst_ptr
= get_pixel_ptr_1( dst
, rc
->left
, rc
->top
);
4898 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4900 for (j
= 0, x
= (dst
->rect
.left
+ rc
->left
) & 7; j
< rc
->right
- rc
->left
; j
++, x
++)
4902 DWORD val
= (dst_ptr
[x
/ 8] & pixel_masks_1
[x
% 8]) ? 1 : 0;
4903 RGBQUAD rgb
= color_table
[val
];
4904 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[j
], blend
);
4905 val
= rgb_to_pixel_colortable(dst
, val
>> 16, val
>> 8, val
) ? 0xff : 0;
4906 dst_ptr
[x
/ 8] = (dst_ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (val
& pixel_masks_1
[x
% 8]);
4912 static void blend_rects_null(const dib_info
*dst
, int num
, const RECT
*rc
,
4913 const dib_info
*src
, const POINT
*offset
, BLENDFUNCTION blend
)
4917 static inline DWORD
gradient_rgb_8888( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
)
4920 r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 256;
4921 g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 256;
4922 b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 256;
4923 a
= (v
[0].Alpha
* (len
- pos
) + v
[1].Alpha
* pos
) / len
/ 256;
4924 return a
<< 24 | r
<< 16 | g
<< 8 | b
;
4927 static inline DWORD
gradient_rgb_24( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
)
4930 r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 256;
4931 g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 256;
4932 b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 256;
4933 return r
<< 16 | g
<< 8 | b
;
4936 static inline WORD
gradient_rgb_555( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
,
4937 unsigned int x
, unsigned int y
)
4939 int r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4940 int g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4941 int b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4942 r
= min( 31, max( 0, r
/ 16 ));
4943 g
= min( 31, max( 0, g
/ 16 ));
4944 b
= min( 31, max( 0, b
/ 16 ));
4945 return (r
<< 10) | (g
<< 5) | b
;
4948 static inline BYTE
gradient_rgb_8( const dib_info
*dib
, const TRIVERTEX
*v
,
4949 unsigned int pos
, unsigned int len
, unsigned int x
, unsigned int y
)
4951 BYTE r
= ((v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4952 BYTE g
= ((v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4953 BYTE b
= ((v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4954 return rgb_to_pixel_colortable( dib
, r
* 127, g
* 127, b
* 127 );
4957 /* compute the left/right triangle limit for row y */
4958 static inline void triangle_coords( const TRIVERTEX
*v
, const RECT
*rc
, int y
, int *left
, int *right
)
4962 if (y
< v
[1].y
) x1
= edge_coord( y
, v
[0].x
, v
[0].y
, v
[1].x
, v
[1].y
);
4963 else x1
= edge_coord( y
, v
[1].x
, v
[1].y
, v
[2].x
, v
[2].y
);
4965 x2
= edge_coord( y
, v
[0].x
, v
[0].y
, v
[2].x
, v
[2].y
);
4967 *left
= max( rc
->left
, min( x1
, x2
) );
4968 *right
= min( rc
->right
, max( x1
, x2
) );
4971 /* compute the matrix determinant for triangular barycentric coordinates (constant across the triangle) */
4972 static inline int triangle_det( const TRIVERTEX
*v
)
4974 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
);
4977 /* compute the barycentric weights for a given point inside the triangle */
4978 static inline void triangle_weights( const TRIVERTEX
*v
, int x
, int y
, INT64
*l1
, INT64
*l2
)
4980 *l1
= (v
[1].y
- v
[2].y
) * (x
- v
[2].x
) - (v
[1].x
- v
[2].x
) * (y
- v
[2].y
);
4981 *l2
= (v
[2].y
- v
[0].y
) * (x
- v
[2].x
) - (v
[2].x
- v
[0].x
) * (y
- v
[2].y
);
4984 static inline DWORD
gradient_triangle_8888( const TRIVERTEX
*v
, int x
, int y
, int det
)
4989 triangle_weights( v
, x
, y
, &l1
, &l2
);
4990 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 256;
4991 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 256;
4992 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 256;
4993 a
= (v
[0].Alpha
* l1
+ v
[1].Alpha
* l2
+ v
[2].Alpha
* (det
- l1
- l2
)) / det
/ 256;
4994 return a
<< 24 | r
<< 16 | g
<< 8 | b
;
4997 static inline DWORD
gradient_triangle_24( const TRIVERTEX
*v
, int x
, int y
, int det
)
5002 triangle_weights( v
, x
, y
, &l1
, &l2
);
5003 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 256;
5004 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 256;
5005 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 256;
5006 return r
<< 16 | g
<< 8 | b
;
5009 static inline DWORD
gradient_triangle_555( const TRIVERTEX
*v
, int x
, int y
, int det
)
5014 triangle_weights( v
, x
, y
, &l1
, &l2
);
5015 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
5016 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
5017 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
5018 r
= min( 31, max( 0, r
/ 16 ));
5019 g
= min( 31, max( 0, g
/ 16 ));
5020 b
= min( 31, max( 0, b
/ 16 ));
5021 return (r
<< 10) | (g
<< 5) | b
;
5024 static inline DWORD
gradient_triangle_8( const dib_info
*dib
, const TRIVERTEX
*v
, int x
, int y
, int det
)
5029 triangle_weights( v
, x
, y
, &l1
, &l2
);
5030 r
= ((v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
5031 g
= ((v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
5032 b
= ((v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
5033 return rgb_to_pixel_colortable( dib
, r
* 127, g
* 127, b
* 127 );
5036 static BOOL
gradient_rect_8888( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5038 DWORD
*ptr
= get_pixel_ptr_32( dib
, rc
->left
, rc
->top
);
5039 int x
, y
, left
, right
, det
;
5043 case GRADIENT_FILL_RECT_H
:
5044 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
5045 ptr
[x
] = gradient_rgb_8888( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
5047 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
5048 memcpy( ptr
+ dib
->stride
/ 4, ptr
, (rc
->right
- rc
->left
) * 4 );
5051 case GRADIENT_FILL_RECT_V
:
5052 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
5054 DWORD val
= gradient_rgb_8888( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
5055 memset_32( ptr
, val
, rc
->right
- rc
->left
);
5059 case GRADIENT_FILL_TRIANGLE
:
5060 if (!(det
= triangle_det( v
))) return FALSE
;
5061 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
5063 triangle_coords( v
, rc
, y
, &left
, &right
);
5064 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_8888( v
, x
, y
, det
);
5071 static BOOL
gradient_rect_32( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5073 DWORD
*ptr
= get_pixel_ptr_32( dib
, rc
->left
, rc
->top
);
5074 int x
, y
, left
, right
, det
;
5078 case GRADIENT_FILL_RECT_H
:
5079 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
5081 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
5083 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
5084 ptr
[x
] = ((( val
& 0xff) << dib
->blue_shift
) |
5085 (((val
>> 8) & 0xff) << dib
->green_shift
) |
5086 (((val
>> 16) & 0xff) << dib
->red_shift
));
5091 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
5093 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
5094 ptr
[x
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
5098 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
5099 memcpy( ptr
+ dib
->stride
/ 4, ptr
, (rc
->right
- rc
->left
) * 4 );
5102 case GRADIENT_FILL_RECT_V
:
5103 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
5105 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
5106 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
5107 val
= ((( val
& 0xff) << dib
->blue_shift
) |
5108 (((val
>> 8) & 0xff) << dib
->green_shift
) |
5109 (((val
>> 16) & 0xff) << dib
->red_shift
));
5111 val
= rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
5113 memset_32( ptr
, val
, rc
->right
- rc
->left
);
5117 case GRADIENT_FILL_TRIANGLE
:
5118 if (!(det
= triangle_det( v
))) return FALSE
;
5119 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
5121 triangle_coords( v
, rc
, y
, &left
, &right
);
5123 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
5124 for (x
= left
; x
< right
; x
++)
5126 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
5127 ptr
[x
- rc
->left
] = ((( val
& 0xff) << dib
->blue_shift
) |
5128 (((val
>> 8) & 0xff) << dib
->green_shift
) |
5129 (((val
>> 16) & 0xff) << dib
->red_shift
));
5132 for (x
= left
; x
< right
; x
++)
5134 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
5135 ptr
[x
- rc
->left
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
5143 static BOOL
gradient_rect_24( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5145 BYTE
*ptr
= get_pixel_ptr_24( dib
, rc
->left
, rc
->top
);
5146 int x
, y
, left
, right
, det
;
5150 case GRADIENT_FILL_RECT_H
:
5151 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
5153 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
5155 ptr
[x
* 3 + 1] = val
>> 8;
5156 ptr
[x
* 3 + 2] = val
>> 16;
5159 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5160 memcpy( ptr
+ dib
->stride
, ptr
, (rc
->right
- rc
->left
) * 3 );
5163 case GRADIENT_FILL_RECT_V
:
5164 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5166 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
5167 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
5170 ptr
[x
* 3 + 1] = val
>> 8;
5171 ptr
[x
* 3 + 2] = val
>> 16;
5176 case GRADIENT_FILL_TRIANGLE
:
5177 if (!(det
= triangle_det( v
))) return FALSE
;
5178 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5180 triangle_coords( v
, rc
, y
, &left
, &right
);
5181 for (x
= left
; x
< right
; x
++)
5183 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
5184 ptr
[(x
- rc
->left
) * 3] = val
;
5185 ptr
[(x
- rc
->left
) * 3 + 1] = val
>> 8;
5186 ptr
[(x
- rc
->left
) * 3 + 2] = val
>> 16;
5194 static BOOL
gradient_rect_555( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5196 WORD
*ptr
= get_pixel_ptr_16( dib
, rc
->left
, rc
->top
);
5197 int x
, y
, left
, right
, det
;
5201 case GRADIENT_FILL_RECT_H
:
5202 for (y
= rc
->top
; y
< min( rc
->top
+ 4, rc
->bottom
); y
++, ptr
+= dib
->stride
/ 2)
5203 for (x
= rc
->left
; x
< rc
->right
; x
++)
5204 ptr
[x
- rc
->left
] = gradient_rgb_555( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
5205 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5206 memcpy( ptr
, ptr
- dib
->stride
* 2, (rc
->right
- rc
->left
) * 2 );
5209 case GRADIENT_FILL_RECT_V
:
5210 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5213 for (x
= 0; x
< 4; x
++) values
[x
] = gradient_rgb_555( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
5214 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 4];
5218 case GRADIENT_FILL_TRIANGLE
:
5219 if (!(det
= triangle_det( v
))) return FALSE
;
5220 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5222 triangle_coords( v
, rc
, y
, &left
, &right
);
5223 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_555( v
, x
, y
, det
);
5230 static BOOL
gradient_rect_16( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5232 WORD
*ptr
= get_pixel_ptr_16( dib
, rc
->left
, rc
->top
);
5233 int x
, y
, left
, right
, det
;
5237 case GRADIENT_FILL_RECT_H
:
5238 for (y
= rc
->top
; y
< min( rc
->top
+ 4, rc
->bottom
); y
++, ptr
+= dib
->stride
/ 2)
5239 for (x
= rc
->left
; x
< rc
->right
; x
++)
5241 WORD val
= gradient_rgb_555( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
5242 ptr
[x
- rc
->left
] = rgb_to_pixel_masks( dib
,
5243 ((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07),
5244 ((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07),
5245 ((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07) );
5247 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5248 memcpy( ptr
, ptr
- dib
->stride
* 2, (rc
->right
- rc
->left
) * 2 );
5251 case GRADIENT_FILL_RECT_V
:
5252 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5255 for (x
= 0; x
< 4; x
++)
5257 WORD val
= gradient_rgb_555( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
5258 values
[x
] = rgb_to_pixel_masks( dib
,
5259 ((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07),
5260 ((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07),
5261 ((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07) );
5263 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 4];
5267 case GRADIENT_FILL_TRIANGLE
:
5268 if (!(det
= triangle_det( v
))) return FALSE
;
5269 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
5271 triangle_coords( v
, rc
, y
, &left
, &right
);
5272 for (x
= left
; x
< right
; x
++)
5274 WORD val
= gradient_triangle_555( v
, x
, y
, det
);
5275 ptr
[x
- rc
->left
] = rgb_to_pixel_masks( dib
,
5276 ((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07),
5277 ((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07),
5278 ((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07) );
5286 static BOOL
gradient_rect_8( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5288 BYTE
*ptr
= get_pixel_ptr_8( dib
, rc
->left
, rc
->top
);
5289 int x
, y
, left
, right
, det
;
5293 case GRADIENT_FILL_RECT_H
:
5294 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
5295 for (x
= rc
->left
; x
< rc
->right
; x
++)
5296 ptr
[x
- rc
->left
] = gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
5297 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5298 memcpy( ptr
, ptr
- dib
->stride
* 16, rc
->right
- rc
->left
);
5301 case GRADIENT_FILL_RECT_V
:
5302 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5305 for (x
= 0; x
< 16; x
++)
5306 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
5307 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 16];
5311 case GRADIENT_FILL_TRIANGLE
:
5312 if (!(det
= triangle_det( v
))) return FALSE
;
5313 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5315 triangle_coords( v
, rc
, y
, &left
, &right
);
5316 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_8( dib
, v
, x
, y
, det
);
5323 static BOOL
gradient_rect_4( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5325 BYTE
*ptr
= get_pixel_ptr_4( dib
, rc
->left
, rc
->top
);
5326 int x
, y
, left
, right
, det
, pos
;
5330 case GRADIENT_FILL_RECT_H
:
5331 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
5333 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 1; x
< rc
->right
; x
++, pos
++)
5335 BYTE val
= gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
5337 ptr
[pos
/ 2] = val
| (ptr
[pos
/ 2] & 0xf0);
5339 ptr
[pos
/ 2] = (val
<< 4) | (ptr
[pos
/ 2] & 0x0f);
5342 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5345 pos
= (dib
->rect
.left
+ rc
->left
) & 1;
5348 ptr
[0] = (ptr
[-16 * dib
->stride
] & 0x0f) | (ptr
[0] & 0xf0);
5352 for (; x
< rc
->right
- 1; x
+= 2, pos
+= 2) ptr
[pos
/ 2] = ptr
[pos
/ 2 - 16 * dib
->stride
];
5354 ptr
[pos
/ 2] = (ptr
[pos
/ 2] & 0x0f) | (ptr
[pos
/ 2 - 16 * dib
->stride
] & 0xf0);
5358 case GRADIENT_FILL_RECT_V
:
5359 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5362 for (x
= 0; x
< 16; x
++)
5363 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
5364 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 1; x
< rc
->right
; x
++, pos
++)
5366 ptr
[pos
/ 2] = values
[x
% 16] | (ptr
[pos
/ 2] & 0xf0);
5368 ptr
[pos
/ 2] = (values
[x
% 16] << 4) | (ptr
[pos
/ 2] & 0x0f);
5372 case GRADIENT_FILL_TRIANGLE
:
5373 if (!(det
= triangle_det( v
))) return FALSE
;
5374 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5376 triangle_coords( v
, rc
, y
, &left
, &right
);
5377 for (x
= left
, pos
= left
- rc
->left
+ ((dib
->rect
.left
+ rc
->left
) & 1); x
< right
; x
++, pos
++)
5379 BYTE val
= gradient_triangle_8( dib
, v
, x
, y
, det
);
5381 ptr
[pos
/ 2] = val
| (ptr
[pos
/ 2] & 0xf0);
5383 ptr
[pos
/ 2] = (val
<< 4) | (ptr
[pos
/ 2] & 0x0f);
5391 static BOOL
gradient_rect_1( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5393 BYTE
*ptr
= get_pixel_ptr_1( dib
, rc
->left
, rc
->top
);
5394 int x
, y
, left
, right
, det
, pos
;
5398 case GRADIENT_FILL_RECT_H
:
5399 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
5401 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
5403 BYTE val
= gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
) ? 0xff : 0;
5404 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) | (val
& pixel_masks_1
[pos
% 8]);
5407 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5408 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
5409 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
5410 (ptr
[pos
/ 8 - 16 * dib
->stride
] & pixel_masks_1
[pos
% 8]);
5413 case GRADIENT_FILL_RECT_V
:
5414 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5417 for (x
= 0; x
< 16; x
++)
5418 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
) ? 0xff : 0;
5419 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
5420 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
5421 (values
[x
% 16] & pixel_masks_1
[pos
% 8]);
5425 case GRADIENT_FILL_TRIANGLE
:
5426 if (!(det
= triangle_det( v
))) return FALSE
;
5427 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
5429 triangle_coords( v
, rc
, y
, &left
, &right
);
5430 for (x
= left
, pos
= left
- rc
->left
+ ((dib
->rect
.left
+ rc
->left
) & 7); x
< right
; x
++, pos
++)
5432 BYTE val
= gradient_triangle_8( dib
, v
, x
, y
, det
) ? 0xff : 0;
5433 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) | (val
& pixel_masks_1
[pos
% 8]);
5441 static BOOL
gradient_rect_null( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
5446 static void mask_rect_32( const dib_info
*dst
, const RECT
*rc
,
5447 const dib_info
*src
, const POINT
*origin
, int rop2
)
5449 DWORD
*dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->top
), dst_colors
[256];
5450 DWORD src_val
, bit_val
, i
, full
, pos
;
5451 int x
, y
, origin_end
= origin
->x
+ rc
->right
- rc
->left
;
5452 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5453 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5455 if (dst
->funcs
== &funcs_8888
)
5456 for (i
= 0; i
< 2; i
++)
5457 dst_colors
[i
] = color_table
[i
].rgbRed
<< 16 | color_table
[i
].rgbGreen
<< 8 |
5458 color_table
[i
].rgbBlue
;
5460 for (i
= 0; i
< 2; i
++)
5461 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
5463 /* Creating a BYTE-sized table so we don't need to mask the lsb of bit_val */
5464 for (i
= 2; i
< ARRAY_SIZE(dst_colors
); i
++)
5465 dst_colors
[i
] = dst_colors
[i
& 1];
5467 /* Special case starting and finishing in same byte, neither on byte boundary */
5468 if ((origin
->x
& 7) && (origin_end
& 7) && (origin
->x
& ~7) == (origin_end
& ~7))
5470 struct rop_codes codes
;
5472 get_rop_codes( rop2
, &codes
);
5474 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5476 pos
= origin
->x
& 7;
5477 for (x
= 0; x
< rc
->right
- rc
->left
; x
++, pos
++)
5479 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5480 do_rop_codes_32( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5482 dst_start
+= dst
->stride
/ 4;
5483 src_start
+= src
->stride
;
5488 full
= ((rc
->right
- rc
->left
) - ((8 - (origin
->x
& 7)) & 7)) / 8;
5490 #define LOOP( op ) \
5491 for (y = rc->top; y < rc->bottom; y++) \
5493 pos = origin->x & 7; \
5494 src_val = src_start[pos / 8]; \
5498 case 1: bit_val = src_val >> 6; op; x++; \
5499 /* fall through */ \
5500 case 2: bit_val = src_val >> 5; op; x++; \
5501 /* fall through */ \
5502 case 3: bit_val = src_val >> 4; op; x++; \
5503 /* fall through */ \
5504 case 4: bit_val = src_val >> 3; op; x++; \
5505 /* fall through */ \
5506 case 5: bit_val = src_val >> 2; op; x++; \
5507 /* fall through */ \
5508 case 6: bit_val = src_val >> 1; op; x++; \
5509 /* fall through */ \
5510 case 7: bit_val = src_val; op; x++; \
5511 pos = (pos + 7) & ~7; \
5513 for (i = 0; i < full; i++, pos += 8) \
5515 src_val = src_start[pos / 8]; \
5516 bit_val = src_val >> 7; op; x++; \
5517 bit_val = src_val >> 6; op; x++; \
5518 bit_val = src_val >> 5; op; x++; \
5519 bit_val = src_val >> 4; op; x++; \
5520 bit_val = src_val >> 3; op; x++; \
5521 bit_val = src_val >> 2; op; x++; \
5522 bit_val = src_val >> 1; op; x++; \
5523 bit_val = src_val; op; x++; \
5525 if (origin_end & 7) \
5527 src_val = src_start[pos / 8]; \
5528 x += (origin_end & 7) - 1; \
5529 switch (origin_end & 7) \
5531 case 7: bit_val = src_val >> 1; op; x--; \
5532 /* fall through */ \
5533 case 6: bit_val = src_val >> 2; op; x--; \
5534 /* fall through */ \
5535 case 5: bit_val = src_val >> 3; op; x--; \
5536 /* fall through */ \
5537 case 4: bit_val = src_val >> 4; op; x--; \
5538 /* fall through */ \
5539 case 3: bit_val = src_val >> 5; op; x--; \
5540 /* fall through */ \
5541 case 2: bit_val = src_val >> 6; op; x--; \
5542 /* fall through */ \
5543 case 1: bit_val = src_val >> 7; op; \
5546 dst_start += dst->stride / 4; \
5547 src_start += src->stride; \
5552 ROPS_ALL( dst_start
[x
], dst_colors
[bit_val
] )
5557 static void mask_rect_24( const dib_info
*dst
, const RECT
*rc
,
5558 const dib_info
*src
, const POINT
*origin
, int rop2
)
5560 BYTE
*dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->top
);
5561 DWORD src_val
, bit_val
, i
, full
, pos
;
5562 struct rop_codes codes
;
5563 int x
, y
, origin_end
= origin
->x
+ rc
->right
- rc
->left
;
5564 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5565 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5568 get_rop_codes( rop2
, &codes
);
5570 /* Special case starting and finishing in same byte, neither on byte boundary */
5571 if ((origin
->x
& 7) && (origin_end
& 7) && (origin
->x
& ~7) == (origin_end
& ~7))
5573 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5575 pos
= origin
->x
& 7;
5576 for (x
= 0; x
< rc
->right
- rc
->left
; x
++, pos
++)
5578 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5579 rgb
= color_table
[bit_val
];
5580 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5581 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5582 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5584 dst_start
+= dst
->stride
;
5585 src_start
+= src
->stride
;
5590 full
= ((rc
->right
- rc
->left
) - ((8 - (origin
->x
& 7)) & 7)) / 8;
5592 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5594 pos
= origin
->x
& 7;
5595 src_val
= src_start
[pos
/ 8];
5601 bit_val
= (src_val
>> 6) & 1;
5602 rgb
= color_table
[bit_val
];
5603 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5604 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5605 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5609 bit_val
= (src_val
>> 5) & 1;
5610 rgb
= color_table
[bit_val
];
5611 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5612 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5613 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5617 bit_val
= (src_val
>> 4) & 1;
5618 rgb
= color_table
[bit_val
];
5619 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5620 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5621 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5625 bit_val
= (src_val
>> 3) & 1;
5626 rgb
= color_table
[bit_val
];
5627 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5628 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5629 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5633 bit_val
= (src_val
>> 2) & 1;
5634 rgb
= color_table
[bit_val
];
5635 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5636 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5637 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5641 bit_val
= (src_val
>> 1) & 1;
5642 rgb
= color_table
[bit_val
];
5643 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5644 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5645 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5649 bit_val
= src_val
& 1;
5650 rgb
= color_table
[bit_val
];
5651 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5652 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5653 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5655 pos
= (pos
+ 7) & ~7;
5658 for (i
= 0; i
< full
; i
++, pos
+= 8)
5660 src_val
= src_start
[pos
/ 8];
5662 bit_val
= (src_val
>> 7) & 1;
5663 rgb
= color_table
[bit_val
];
5664 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5665 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5666 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5669 bit_val
= (src_val
>> 6) & 1;
5670 rgb
= color_table
[bit_val
];
5671 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5672 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5673 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5676 bit_val
= (src_val
>> 5) & 1;
5677 rgb
= color_table
[bit_val
];
5678 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5679 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5680 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5683 bit_val
= (src_val
>> 4) & 1;
5684 rgb
= color_table
[bit_val
];
5685 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5686 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5687 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5690 bit_val
= (src_val
>> 3) & 1;
5691 rgb
= color_table
[bit_val
];
5692 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5693 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5694 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5697 bit_val
= (src_val
>> 2) & 1;
5698 rgb
= color_table
[bit_val
];
5699 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5700 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5701 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5704 bit_val
= (src_val
>> 1) & 1;
5705 rgb
= color_table
[bit_val
];
5706 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5707 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5708 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5711 bit_val
= src_val
& 1;
5712 rgb
= color_table
[bit_val
];
5713 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5714 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5715 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5721 src_val
= src_start
[pos
/ 8];
5722 x
+= (origin_end
& 7) - 1;
5724 switch (origin_end
& 7)
5727 bit_val
= (src_val
>> 1) & 1;
5728 rgb
= color_table
[bit_val
];
5729 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5730 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5731 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5735 bit_val
= (src_val
>> 2) & 1;
5736 rgb
= color_table
[bit_val
];
5737 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5738 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5739 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5743 bit_val
= (src_val
>> 3) & 1;
5744 rgb
= color_table
[bit_val
];
5745 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5746 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5747 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5751 bit_val
= (src_val
>> 4) & 1;
5752 rgb
= color_table
[bit_val
];
5753 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5754 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5755 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5759 bit_val
= (src_val
>> 5) & 1;
5760 rgb
= color_table
[bit_val
];
5761 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5762 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5763 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5767 bit_val
= (src_val
>> 6) & 1;
5768 rgb
= color_table
[bit_val
];
5769 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5770 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5771 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5775 bit_val
= (src_val
>> 7) & 1;
5776 rgb
= color_table
[bit_val
];
5777 do_rop_codes_8( dst_start
+ x
* 3, rgb
.rgbBlue
, &codes
);
5778 do_rop_codes_8( dst_start
+ x
* 3 + 1, rgb
.rgbGreen
, &codes
);
5779 do_rop_codes_8( dst_start
+ x
* 3 + 2, rgb
.rgbRed
, &codes
);
5783 dst_start
+= dst
->stride
;
5784 src_start
+= src
->stride
;
5788 static void mask_rect_16( const dib_info
*dst
, const RECT
*rc
,
5789 const dib_info
*src
, const POINT
*origin
, int rop2
)
5791 WORD
*dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->top
), dst_colors
[2];
5792 DWORD src_val
, bit_val
, i
, full
, pos
;
5793 struct rop_codes codes
;
5794 int x
, y
, origin_end
= origin
->x
+ rc
->right
- rc
->left
;
5795 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5796 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5798 get_rop_codes( rop2
, &codes
);
5800 if (dst
->funcs
== &funcs_555
)
5801 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
5802 dst_colors
[i
] = ((color_table
[i
].rgbRed
<< 7) & 0x7c00) |
5803 ((color_table
[i
].rgbGreen
<< 2) & 0x03e0) |
5804 ((color_table
[i
].rgbBlue
>> 3) & 0x001f);
5806 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
5807 dst_colors
[i
] = rgbquad_to_pixel_masks(dst
, color_table
[i
]);
5809 /* Special case starting and finishing in same byte, neither on byte boundary */
5810 if ((origin
->x
& 7) && (origin_end
& 7) && (origin
->x
& ~7) == (origin_end
& ~7))
5812 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5814 pos
= origin
->x
& 7;
5815 for (x
= 0; x
< rc
->right
- rc
->left
; x
++, pos
++)
5817 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5818 do_rop_codes_16( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5820 dst_start
+= dst
->stride
/ 2;
5821 src_start
+= src
->stride
;
5826 full
= ((rc
->right
- rc
->left
) - ((8 - (origin
->x
& 7)) & 7)) / 8;
5828 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5830 pos
= origin
->x
& 7;
5831 src_val
= src_start
[pos
/ 8];
5837 bit_val
= (src_val
>> 6) & 1;
5838 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5841 bit_val
= (src_val
>> 5) & 1;
5842 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5845 bit_val
= (src_val
>> 4) & 1;
5846 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5849 bit_val
= (src_val
>> 3) & 1;
5850 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5853 bit_val
= (src_val
>> 2) & 1;
5854 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5857 bit_val
= (src_val
>> 1) & 1;
5858 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5861 bit_val
= src_val
& 1;
5862 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5863 pos
= (pos
+ 7) & ~7;
5866 for (i
= 0; i
< full
; i
++, pos
+= 8)
5868 src_val
= src_start
[pos
/ 8];
5870 bit_val
= (src_val
>> 7) & 1;
5871 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5872 bit_val
= (src_val
>> 6) & 1;
5873 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5874 bit_val
= (src_val
>> 5) & 1;
5875 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5876 bit_val
= (src_val
>> 4) & 1;
5877 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5878 bit_val
= (src_val
>> 3) & 1;
5879 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5880 bit_val
= (src_val
>> 2) & 1;
5881 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5882 bit_val
= (src_val
>> 1) & 1;
5883 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5884 bit_val
= src_val
& 1;
5885 do_rop_codes_16( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5890 src_val
= src_start
[pos
/ 8];
5891 x
+= (origin_end
& 7) - 1;
5893 switch (origin_end
& 7)
5896 bit_val
= (src_val
>> 1) & 1;
5897 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5900 bit_val
= (src_val
>> 2) & 1;
5901 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5904 bit_val
= (src_val
>> 3) & 1;
5905 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5908 bit_val
= (src_val
>> 4) & 1;
5909 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5912 bit_val
= (src_val
>> 5) & 1;
5913 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5916 bit_val
= (src_val
>> 6) & 1;
5917 do_rop_codes_16( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
5920 bit_val
= (src_val
>> 7) & 1;
5921 do_rop_codes_16( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5925 dst_start
+= dst
->stride
/ 2;
5926 src_start
+= src
->stride
;
5930 static void mask_rect_8( const dib_info
*dst
, const RECT
*rc
,
5931 const dib_info
*src
, const POINT
*origin
, int rop2
)
5933 BYTE
*dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->top
), dst_colors
[2];
5934 DWORD src_val
, bit_val
, i
, full
, pos
;
5935 struct rop_codes codes
;
5936 int x
, y
, origin_end
= origin
->x
+ rc
->right
- rc
->left
;
5937 const RGBQUAD
*color_table
= get_dib_color_table( src
);
5938 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
5940 get_rop_codes( rop2
, &codes
);
5942 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
5943 dst_colors
[i
] = FILTER_DIBINDEX(color_table
[i
], rgbquad_to_pixel_colortable(dst
, color_table
[i
]));
5945 /* Special case starting and finishing in same byte, neither on byte boundary */
5946 if ((origin
->x
& 7) && (origin_end
& 7) && (origin
->x
& ~7) == (origin_end
& ~7))
5948 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5950 pos
= origin
->x
& 7;
5951 for (x
= 0; x
< rc
->right
- rc
->left
; x
++, pos
++)
5953 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
5954 do_rop_codes_8( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
5956 dst_start
+= dst
->stride
;
5957 src_start
+= src
->stride
;
5962 full
= ((rc
->right
- rc
->left
) - ((8 - (origin
->x
& 7)) & 7)) / 8;
5964 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
5966 pos
= origin
->x
& 7;
5967 src_val
= src_start
[pos
/ 8];
5973 bit_val
= (src_val
>> 6) & 1;
5974 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5977 bit_val
= (src_val
>> 5) & 1;
5978 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5981 bit_val
= (src_val
>> 4) & 1;
5982 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5985 bit_val
= (src_val
>> 3) & 1;
5986 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5989 bit_val
= (src_val
>> 2) & 1;
5990 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5993 bit_val
= (src_val
>> 1) & 1;
5994 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5997 bit_val
= src_val
& 1;
5998 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
5999 pos
= (pos
+ 7) & ~7;
6002 for (i
= 0; i
< full
; i
++, pos
+= 8)
6004 src_val
= src_start
[pos
/ 8];
6006 bit_val
= (src_val
>> 7) & 1;
6007 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
6008 bit_val
= (src_val
>> 6) & 1;
6009 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
6010 bit_val
= (src_val
>> 5) & 1;
6011 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
6012 bit_val
= (src_val
>> 4) & 1;
6013 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
6014 bit_val
= (src_val
>> 3) & 1;
6015 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
6016 bit_val
= (src_val
>> 2) & 1;
6017 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
6018 bit_val
= (src_val
>> 1) & 1;
6019 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
6020 bit_val
= src_val
& 1;
6021 do_rop_codes_8( dst_start
+ x
++, dst_colors
[bit_val
], &codes
);
6026 src_val
= src_start
[pos
/ 8];
6027 x
+= (origin_end
& 7) - 1;
6029 switch (origin_end
& 7)
6032 bit_val
= (src_val
>> 1) & 1;
6033 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
6036 bit_val
= (src_val
>> 2) & 1;
6037 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
6040 bit_val
= (src_val
>> 3) & 1;
6041 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
6044 bit_val
= (src_val
>> 4) & 1;
6045 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
6048 bit_val
= (src_val
>> 5) & 1;
6049 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
6052 bit_val
= (src_val
>> 6) & 1;
6053 do_rop_codes_8( dst_start
+ x
--, dst_colors
[bit_val
], &codes
);
6056 bit_val
= (src_val
>> 7) & 1;
6057 do_rop_codes_8( dst_start
+ x
, dst_colors
[bit_val
], &codes
);
6061 dst_start
+= dst
->stride
;
6062 src_start
+= src
->stride
;
6066 static void mask_rect_4( const dib_info
*dst
, const RECT
*rc
,
6067 const dib_info
*src
, const POINT
*origin
, int rop2
)
6069 BYTE
*dst_start
= get_pixel_ptr_4(dst
, rc
->left
, rc
->top
), dst_colors
[2], *dst_ptr
;
6070 DWORD bit_val
, i
, pos
;
6071 struct rop_codes codes
;
6073 int left
= dst
->rect
.left
+ rc
->left
;
6074 int right
= dst
->rect
.left
+ rc
->right
;
6075 const RGBQUAD
*color_table
= get_dib_color_table( src
);
6076 BYTE
*src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
6078 get_rop_codes( rop2
, &codes
);
6080 for (i
= 0; i
< ARRAY_SIZE(dst_colors
); i
++)
6082 dst_colors
[i
] = FILTER_DIBINDEX(color_table
[i
],rgbquad_to_pixel_colortable(dst
, color_table
[i
]));
6083 /* Set high nibble to match so we don't need to shift it later. */
6084 dst_colors
[i
] |= dst_colors
[i
] << 4;
6087 for (y
= rc
->top
; y
< rc
->bottom
; y
++)
6089 pos
= origin
->x
& 7;
6091 for (x
= left
, dst_ptr
= dst_start
; x
< right
; x
++, pos
++)
6093 bit_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
6095 do_rop_codes_mask_8( dst_ptr
++, dst_colors
[bit_val
], &codes
, 0x0f );
6097 do_rop_codes_mask_8( dst_ptr
, dst_colors
[bit_val
], &codes
, 0xf0 );
6099 dst_start
+= dst
->stride
;
6100 src_start
+= src
->stride
;
6104 static void mask_rect_null( const dib_info
*dst
, const RECT
*rc
,
6105 const dib_info
*src
, const POINT
*origin
, int rop2
)
6109 static inline BYTE
aa_color( BYTE dst
, BYTE text
, BYTE min_comp
, BYTE max_comp
)
6111 if (dst
== text
) return dst
;
6115 DWORD diff
= dst
- text
;
6116 DWORD range
= max_comp
- text
;
6117 dst
= text
+ (diff
* range
) / (0xff - text
);
6122 DWORD diff
= text
- dst
;
6123 DWORD range
= text
- min_comp
;
6124 dst
= text
- (diff
* range
) / text
;
6129 static inline DWORD
aa_rgb( BYTE r_dst
, BYTE g_dst
, BYTE b_dst
, DWORD text
, const struct intensity_range
*range
)
6131 return (aa_color( b_dst
, text
, range
->b_min
, range
->b_max
) |
6132 aa_color( g_dst
, text
>> 8, range
->g_min
, range
->g_max
) << 8 |
6133 aa_color( r_dst
, text
>> 16, range
->r_min
, range
->r_max
) << 16);
6136 static void draw_glyph_8888( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6137 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6139 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
6140 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6143 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6145 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6147 if (glyph_ptr
[x
] <= 1) continue;
6148 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
6149 dst_ptr
[x
] = aa_rgb( dst_ptr
[x
] >> 16, dst_ptr
[x
] >> 8, dst_ptr
[x
], text_pixel
, ranges
+ glyph_ptr
[x
] );
6151 dst_ptr
+= dib
->stride
/ 4;
6152 glyph_ptr
+= glyph
->stride
;
6156 static void draw_glyph_32( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6157 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6159 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
6160 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6164 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
6165 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
6166 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
6168 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6170 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6172 if (glyph_ptr
[x
] <= 1) continue;
6173 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
6174 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
6175 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
6176 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
6177 text
, ranges
+ glyph_ptr
[x
] );
6178 dst_ptr
[x
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
6180 dst_ptr
+= dib
->stride
/ 4;
6181 glyph_ptr
+= glyph
->stride
;
6185 static void draw_glyph_24( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6186 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6188 BYTE
*dst_ptr
= get_pixel_ptr_24( dib
, rect
->left
, rect
->top
);
6189 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6193 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6195 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6197 if (glyph_ptr
[x
] <= 1) continue;
6198 if (glyph_ptr
[x
] >= 16)
6201 val
= aa_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
6202 text_pixel
, ranges
+ glyph_ptr
[x
] );
6203 dst_ptr
[x
* 3] = val
;
6204 dst_ptr
[x
* 3 + 1] = val
>> 8;
6205 dst_ptr
[x
* 3 + 2] = val
>> 16;
6207 dst_ptr
+= dib
->stride
;
6208 glyph_ptr
+= glyph
->stride
;
6212 static void draw_glyph_555( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6213 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6215 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
6216 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6220 text
= ((text_pixel
<< 9) & 0xf80000) | ((text_pixel
<< 4) & 0x070000) |
6221 ((text_pixel
<< 6) & 0x00f800) | ((text_pixel
<< 1) & 0x000700) |
6222 ((text_pixel
<< 3) & 0x0000f8) | ((text_pixel
>> 2) & 0x000007);
6224 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6226 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6228 if (glyph_ptr
[x
] <= 1) continue;
6229 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
6230 val
= aa_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
6231 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
6232 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
6233 text
, ranges
+ glyph_ptr
[x
] );
6234 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
6236 dst_ptr
+= dib
->stride
/ 2;
6237 glyph_ptr
+= glyph
->stride
;
6241 static void draw_glyph_16( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6242 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6244 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
6245 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6249 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
6250 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
6251 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
6253 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6255 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6257 if (glyph_ptr
[x
] <= 1) continue;
6258 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
6259 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
6260 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
6261 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
6262 text
, ranges
+ glyph_ptr
[x
] );
6263 dst_ptr
[x
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
6265 dst_ptr
+= dib
->stride
/ 2;
6266 glyph_ptr
+= glyph
->stride
;
6270 static void draw_glyph_8( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6271 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6273 BYTE
*dst_ptr
= get_pixel_ptr_8( dib
, rect
->left
, rect
->top
);
6274 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6277 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6279 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6281 /* no antialiasing, glyph should only contain 0 or 16. */
6282 if (glyph_ptr
[x
] >= 16)
6283 dst_ptr
[x
] = text_pixel
;
6285 dst_ptr
+= dib
->stride
;
6286 glyph_ptr
+= glyph
->stride
;
6290 static void draw_glyph_4( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6291 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6293 BYTE
*dst_ptr
= get_pixel_ptr_4( dib
, rect
->left
, rect
->top
);
6294 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6297 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6299 for (x
= 0, pos
= (dib
->rect
.left
+ rect
->left
) & 1; x
< rect
->right
- rect
->left
; x
++, pos
++)
6301 /* no antialiasing, glyph should only contain 0 or 16. */
6302 if (glyph_ptr
[x
] >= 16)
6305 dst_ptr
[pos
/ 2] = text_pixel
| (dst_ptr
[pos
/ 2] & 0xf0);
6307 dst_ptr
[pos
/ 2] = (text_pixel
<< 4) | (dst_ptr
[pos
/ 2] & 0x0f);
6310 dst_ptr
+= dib
->stride
;
6311 glyph_ptr
+= glyph
->stride
;
6315 static void draw_glyph_1( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6316 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6318 BYTE
*dst_ptr
= get_pixel_ptr_1( dib
, rect
->left
, rect
->top
);
6319 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
6321 BYTE text
= (text_pixel
& 1) ? 0xff : 0;
6323 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6325 for (x
= 0, pos
= (dib
->rect
.left
+ rect
->left
) & 7; x
< rect
->right
- rect
->left
; x
++, pos
++)
6327 /* no antialiasing, glyph should only contain 0 or 16. */
6328 if (glyph_ptr
[x
] >= 16)
6329 dst_ptr
[pos
/ 8] = (dst_ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
6330 (text
& pixel_masks_1
[pos
% 8]);
6332 dst_ptr
+= dib
->stride
;
6333 glyph_ptr
+= glyph
->stride
;
6337 static void draw_glyph_null( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6338 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
6342 static inline BYTE
blend_color_gamma( BYTE dst
, BYTE text
, BYTE alpha
,
6343 const struct font_gamma_ramp
*gamma_ramp
)
6345 if (alpha
== 0) return dst
;
6346 if (alpha
== 255) return text
;
6347 if (dst
== text
) return dst
;
6349 return gamma_ramp
->encode
[ blend_color( gamma_ramp
->decode
[dst
],
6350 gamma_ramp
->decode
[text
],
6354 static inline DWORD
blend_subpixel( BYTE r
, BYTE g
, BYTE b
, DWORD text
, DWORD alpha
,
6355 const struct font_gamma_ramp
*gamma_ramp
)
6357 if (gamma_ramp
!= NULL
&& gamma_ramp
->gamma
!= 1000)
6359 return blend_color_gamma( r
, text
>> 16, (BYTE
)(alpha
>> 16), gamma_ramp
) << 16 |
6360 blend_color_gamma( g
, text
>> 8, (BYTE
)(alpha
>> 8), gamma_ramp
) << 8 |
6361 blend_color_gamma( b
, text
, (BYTE
) alpha
, gamma_ramp
);
6363 return blend_color( r
, text
>> 16, (BYTE
)(alpha
>> 16) ) << 16 |
6364 blend_color( g
, text
>> 8, (BYTE
)(alpha
>> 8) ) << 8 |
6365 blend_color( b
, text
, (BYTE
) alpha
);
6368 static void draw_subpixel_glyph_8888( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6369 const POINT
*origin
, DWORD text_pixel
,
6370 const struct font_gamma_ramp
*gamma_ramp
)
6372 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
6373 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6376 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6378 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6380 if (glyph_ptr
[x
] == 0) continue;
6381 dst_ptr
[x
] = blend_subpixel( dst_ptr
[x
] >> 16, dst_ptr
[x
] >> 8, dst_ptr
[x
],
6382 text_pixel
, glyph_ptr
[x
], gamma_ramp
);
6384 dst_ptr
+= dib
->stride
/ 4;
6385 glyph_ptr
+= glyph
->stride
/ 4;
6389 static void draw_subpixel_glyph_32( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6390 const POINT
*origin
, DWORD text_pixel
,
6391 const struct font_gamma_ramp
*gamma_ramp
)
6393 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
6394 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6398 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
6399 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
6400 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
6402 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6404 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6406 if (glyph_ptr
[x
] == 0) continue;
6407 val
= blend_subpixel( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
6408 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
6409 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
6410 text
, glyph_ptr
[x
], gamma_ramp
);
6411 dst_ptr
[x
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
6413 dst_ptr
+= dib
->stride
/ 4;
6414 glyph_ptr
+= glyph
->stride
/ 4;
6418 static void draw_subpixel_glyph_24( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6419 const POINT
*origin
, DWORD text_pixel
,
6420 const struct font_gamma_ramp
*gamma_ramp
)
6422 BYTE
*dst_ptr
= get_pixel_ptr_24( dib
, rect
->left
, rect
->top
);
6423 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6427 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6429 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6431 if (glyph_ptr
[x
] == 0) continue;
6432 val
= blend_subpixel( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
6433 text_pixel
, glyph_ptr
[x
], gamma_ramp
);
6434 dst_ptr
[x
* 3] = val
;
6435 dst_ptr
[x
* 3 + 1] = val
>> 8;
6436 dst_ptr
[x
* 3 + 2] = val
>> 16;
6438 dst_ptr
+= dib
->stride
;
6439 glyph_ptr
+= glyph
->stride
/ 4;
6443 static void draw_subpixel_glyph_555( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6444 const POINT
*origin
, DWORD text_pixel
,
6445 const struct font_gamma_ramp
*gamma_ramp
)
6447 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
6448 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6452 text
= ((text_pixel
<< 9) & 0xf80000) | ((text_pixel
<< 4) & 0x070000) |
6453 ((text_pixel
<< 6) & 0x00f800) | ((text_pixel
<< 1) & 0x000700) |
6454 ((text_pixel
<< 3) & 0x0000f8) | ((text_pixel
>> 2) & 0x000007);
6456 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6458 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6460 if (glyph_ptr
[x
] == 0) continue;
6461 val
= blend_subpixel( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
6462 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
6463 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
6464 text
, glyph_ptr
[x
], NULL
);
6465 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
6467 dst_ptr
+= dib
->stride
/ 2;
6468 glyph_ptr
+= glyph
->stride
/ 4;
6472 static void draw_subpixel_glyph_16( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6473 const POINT
*origin
, DWORD text_pixel
,
6474 const struct font_gamma_ramp
*gamma_ramp
)
6476 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
6477 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
6481 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
6482 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
6483 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
6485 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
6487 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
6489 if (glyph_ptr
[x
] == 0) continue;
6490 val
= blend_subpixel( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
6491 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
6492 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
6493 text
, glyph_ptr
[x
], NULL
);
6494 dst_ptr
[x
] = rgb_to_pixel_masks( dib
, val
>> 16, val
>> 8, val
);
6496 dst_ptr
+= dib
->stride
/ 2;
6497 glyph_ptr
+= glyph
->stride
/ 4;
6501 static void draw_subpixel_glyph_null( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
6502 const POINT
*origin
, DWORD text_pixel
,
6503 const struct font_gamma_ramp
*gamma_ramp
)
6508 static void create_rop_masks_32(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6509 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6511 DWORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6514 /* masks are always 8x8 */
6515 assert( dib
->width
== 8 );
6516 assert( dib
->height
== 8 );
6518 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6520 for(x
= 0; x
< 8; x
++)
6522 if(*hatch_ptr
& pixel_masks_1
[x
])
6524 and_bits
[x
] = fg
->and;
6525 xor_bits
[x
] = fg
->xor;
6529 and_bits
[x
] = bg
->and;
6530 xor_bits
[x
] = bg
->xor;
6533 and_bits
+= dib
->stride
/ 4;
6534 xor_bits
+= dib
->stride
/ 4;
6538 static void create_rop_masks_24(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6539 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6541 DWORD mask_start
= 0, mask_offset
;
6542 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6545 /* masks are always 8x8 */
6546 assert( dib
->width
== 8 );
6547 assert( dib
->height
== 8 );
6549 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6551 mask_offset
= mask_start
;
6552 for(x
= 0; x
< 8; x
++)
6554 if(*hatch_ptr
& pixel_masks_1
[x
])
6556 and_bits
[mask_offset
] = fg
->and & 0xff;
6557 xor_bits
[mask_offset
++] = fg
->xor & 0xff;
6558 and_bits
[mask_offset
] = (fg
->and >> 8) & 0xff;
6559 xor_bits
[mask_offset
++] = (fg
->xor >> 8) & 0xff;
6560 and_bits
[mask_offset
] = (fg
->and >> 16) & 0xff;
6561 xor_bits
[mask_offset
++] = (fg
->xor >> 16) & 0xff;
6565 and_bits
[mask_offset
] = bg
->and & 0xff;
6566 xor_bits
[mask_offset
++] = bg
->xor & 0xff;
6567 and_bits
[mask_offset
] = (bg
->and >> 8) & 0xff;
6568 xor_bits
[mask_offset
++] = (bg
->xor >> 8) & 0xff;
6569 and_bits
[mask_offset
] = (bg
->and >> 16) & 0xff;
6570 xor_bits
[mask_offset
++] = (bg
->xor >> 16) & 0xff;
6573 mask_start
+= dib
->stride
;
6577 static void create_rop_masks_16(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6578 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6580 WORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6583 /* masks are always 8x8 */
6584 assert( dib
->width
== 8 );
6585 assert( dib
->height
== 8 );
6587 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6589 for(x
= 0; x
< 8; x
++)
6591 if(*hatch_ptr
& pixel_masks_1
[x
])
6593 and_bits
[x
] = fg
->and;
6594 xor_bits
[x
] = fg
->xor;
6598 and_bits
[x
] = bg
->and;
6599 xor_bits
[x
] = bg
->xor;
6602 and_bits
+= dib
->stride
/ 2;
6603 xor_bits
+= dib
->stride
/ 2;
6607 static void create_rop_masks_8(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6608 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6610 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6613 /* masks are always 8x8 */
6614 assert( dib
->width
== 8 );
6615 assert( dib
->height
== 8 );
6617 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6619 for(x
= 0; x
< 8; x
++)
6621 if(*hatch_ptr
& pixel_masks_1
[x
])
6623 and_bits
[x
] = fg
->and;
6624 xor_bits
[x
] = fg
->xor;
6628 and_bits
[x
] = bg
->and;
6629 xor_bits
[x
] = bg
->xor;
6632 and_bits
+= dib
->stride
;
6633 xor_bits
+= dib
->stride
;
6637 static void create_rop_masks_4(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6638 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6641 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6642 const rop_mask
*rop_mask
;
6645 /* masks are always 8x8 */
6646 assert( dib
->width
== 8 );
6647 assert( dib
->height
== 8 );
6649 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6651 for(x
= mask_offset
= 0; x
< 8; x
++)
6653 if(*hatch_ptr
& pixel_masks_1
[x
])
6660 and_bits
[mask_offset
] |= (rop_mask
->and & 0x0f);
6661 xor_bits
[mask_offset
] |= (rop_mask
->xor & 0x0f);
6666 and_bits
[mask_offset
] = (rop_mask
->and << 4) & 0xf0;
6667 xor_bits
[mask_offset
] = (rop_mask
->xor << 4) & 0xf0;
6670 and_bits
+= dib
->stride
;
6671 xor_bits
+= dib
->stride
;
6675 static void create_rop_masks_1(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6676 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6678 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6682 /* masks are always 8x8 */
6683 assert( dib
->width
== 8 );
6684 assert( dib
->height
== 8 );
6686 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
6688 *and_bits
= *xor_bits
= 0;
6689 for(x
= 0; x
< 8; x
++)
6691 if(*hatch_ptr
& pixel_masks_1
[x
])
6693 rop_mask
.and = (fg
->and & 1) ? 0xff : 0;
6694 rop_mask
.xor = (fg
->xor & 1) ? 0xff : 0;
6698 rop_mask
.and = (bg
->and & 1) ? 0xff : 0;
6699 rop_mask
.xor = (bg
->xor & 1) ? 0xff : 0;
6701 *and_bits
|= (rop_mask
.and & pixel_masks_1
[x
]);
6702 *xor_bits
|= (rop_mask
.xor & pixel_masks_1
[x
]);
6704 and_bits
+= dib
->stride
;
6705 xor_bits
+= dib
->stride
;
6709 static void create_rop_masks_null(const dib_info
*dib
, const BYTE
*hatch_ptr
,
6710 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
6714 static void create_dither_masks_8(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
6716 /* mapping between RGB triples and the default color table */
6717 static const BYTE mapping
[27] =
6719 0, /* 000000 -> 000000 */
6720 4, /* 00007f -> 000080 */
6721 252, /* 0000ff -> 0000ff */
6722 2, /* 007f00 -> 008000 */
6723 6, /* 007f7f -> 008080 */
6724 224, /* 007fff -> 0080c0 */
6725 250, /* 00ff00 -> 00ff00 */
6726 184, /* 00ff7f -> 00e080 */
6727 254, /* 00ffff -> 00ffff */
6728 1, /* 7f0000 -> 800000 */
6729 5, /* 7f007f -> 800080 */
6730 196, /* 7f00ff -> 8000c0 */
6731 3, /* 7f7f00 -> 808000 */
6732 248, /* 7f7f7f -> 808080 */
6733 228, /* 7f7fff -> 8080c0 */
6734 60, /* 7fff00 -> 80e000 */
6735 188, /* 7fff7f -> 80e080 */
6736 244, /* 7fffff -> 80c0c0 */
6737 249, /* ff0000 -> ff0000 */
6738 135, /* ff007f -> e00080 */
6739 253, /* ff00ff -> ff00ff */
6740 39, /* ff7f00 -> e08000 */
6741 167, /* ff7f7f -> e08080 */
6742 231, /* ff7fff -> e080c0 */
6743 251, /* ffff00 -> ffff00 */
6744 191, /* ffff7f -> e0e080 */
6745 255 /* ffffff -> ffffff */
6748 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6749 struct rop_codes codes
;
6752 /* masks are always 8x8 */
6753 assert( dib
->width
== 8 );
6754 assert( dib
->height
== 8 );
6756 get_rop_codes( rop2
, &codes
);
6758 for (y
= 0; y
< 8; y
++)
6760 for (x
= 0; x
< 8; x
++)
6762 DWORD r
= ((GetRValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6763 DWORD g
= ((GetGValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6764 DWORD b
= ((GetBValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6765 DWORD pixel
= mapping
[r
* 9 + g
* 3 + b
];
6766 and_bits
[x
] = (pixel
& codes
.a1
) ^ codes
.a2
;
6767 xor_bits
[x
] = (pixel
& codes
.x1
) ^ codes
.x2
;
6769 and_bits
+= dib
->stride
;
6770 xor_bits
+= dib
->stride
;
6774 static void create_dither_masks_4(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
6776 /* mapping between RGB triples and the default color table */
6777 static const BYTE mapping
[27] =
6779 0, /* 000000 -> 000000 */
6780 4, /* 00007f -> 000080 */
6781 12, /* 0000ff -> 0000ff */
6782 2, /* 007f00 -> 008000 */
6783 6, /* 007f7f -> 008080 */
6784 6, /* 007fff -> 008080 */
6785 10, /* 00ff00 -> 00ff00 */
6786 6, /* 00ff7f -> 008080 */
6787 14, /* 00ffff -> 00ffff */
6788 1, /* 7f0000 -> 800000 */
6789 5, /* 7f007f -> 800080 */
6790 5, /* 7f00ff -> 800080 */
6791 3, /* 7f7f00 -> 808000 */
6792 7, /* 7f7f7f -> 808080 */
6793 8, /* 7f7fff -> c0c0c0 */
6794 3, /* 7fff00 -> 808000 */
6795 8, /* 7fff7f -> c0c0c0 */
6796 8, /* 7fffff -> c0c0c0 */
6797 9, /* ff0000 -> ff0000 */
6798 5, /* ff007f -> 800080 */
6799 13, /* ff00ff -> ff00ff */
6800 3, /* ff7f00 -> 808000 */
6801 8, /* ff7f7f -> c0c0c0 */
6802 8, /* ff7fff -> c0c0c0 */
6803 11, /* ffff00 -> ffff00 */
6804 8, /* ffff7f -> c0c0c0 */
6805 15 /* ffffff -> ffffff */
6808 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6809 struct rop_codes codes
;
6812 /* masks are always 8x8 */
6813 assert( dib
->width
== 8 );
6814 assert( dib
->height
== 8 );
6816 get_rop_codes( rop2
, &codes
);
6818 for (y
= 0; y
< 8; y
++)
6820 for (x
= 0; x
< 8; x
++)
6822 DWORD r
= ((GetRValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6823 DWORD g
= ((GetGValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6824 DWORD b
= ((GetBValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
6825 DWORD pixel
= mapping
[r
* 9 + g
* 3 + b
];
6828 and_bits
[x
/ 2] |= (pixel
& codes
.a1
) ^ codes
.a2
;
6829 xor_bits
[x
/ 2] |= (pixel
& codes
.x1
) ^ codes
.x2
;
6833 and_bits
[x
/ 2] = ((pixel
& codes
.a1
) ^ codes
.a2
) << 4;
6834 xor_bits
[x
/ 2] = ((pixel
& codes
.x1
) ^ codes
.x2
) << 4;
6837 and_bits
+= dib
->stride
;
6838 xor_bits
+= dib
->stride
;
6842 static void create_dither_masks_1(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
6844 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
6845 struct rop_codes codes
;
6847 int x
, y
, grey
= (30 * GetRValue(color
) + 59 * GetGValue(color
) + 11 * GetBValue(color
) + 200) / 400;
6849 /* masks are always 8x8 */
6850 assert( dib
->width
== 8 );
6851 assert( dib
->height
== 8 );
6853 get_rop_codes( rop2
, &codes
);
6855 for (y
= 0; y
< 8; y
++)
6857 *and_bits
= *xor_bits
= 0;
6858 for (x
= 0; x
< 8; x
++)
6860 if (grey
+ bayer_8x8
[y
][x
] > 63)
6862 rop_mask
.and = (0xff & codes
.a1
) ^ codes
.a2
;
6863 rop_mask
.xor = (0xff & codes
.x1
) ^ codes
.x2
;
6867 rop_mask
.and = (0x00 & codes
.a1
) ^ codes
.a2
;
6868 rop_mask
.xor = (0x00 & codes
.x1
) ^ codes
.x2
;
6870 *and_bits
|= (rop_mask
.and & pixel_masks_1
[x
]);
6871 *xor_bits
|= (rop_mask
.xor & pixel_masks_1
[x
]);
6873 and_bits
+= dib
->stride
;
6874 xor_bits
+= dib
->stride
;
6878 static void create_dither_masks_null(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
6882 static inline void rop_codes_from_stretch_mode( int mode
, struct rop_codes
*codes
)
6887 case STRETCH_DELETESCANS
:
6888 get_rop_codes( R2_COPYPEN
, codes
);
6890 case STRETCH_ORSCANS
:
6891 get_rop_codes( R2_MERGEPEN
, codes
);
6893 case STRETCH_ANDSCANS
:
6894 get_rop_codes( R2_MASKPEN
, codes
);
6900 static void stretch_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
6901 const dib_info
*src_dib
, const POINT
*src_start
,
6902 const struct stretch_params
*params
, int mode
,
6905 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
6906 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
6907 int err
= params
->err_start
;
6910 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
6912 for (width
= params
->length
; width
; width
--)
6914 *dst_ptr
= *src_ptr
;
6915 dst_ptr
+= params
->dst_inc
;
6918 src_ptr
+= params
->src_inc
;
6919 err
+= params
->err_add_1
;
6921 else err
+= params
->err_add_2
;
6926 struct rop_codes codes
;
6928 rop_codes_from_stretch_mode( mode
, &codes
);
6929 for (width
= params
->length
; width
; width
--)
6931 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
6932 dst_ptr
+= params
->dst_inc
;
6935 src_ptr
+= params
->src_inc
;
6936 err
+= params
->err_add_1
;
6938 else err
+= params
->err_add_2
;
6943 static void stretch_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
6944 const dib_info
*src_dib
, const POINT
*src_start
,
6945 const struct stretch_params
*params
, int mode
,
6948 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
6949 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
6950 int err
= params
->err_start
;
6953 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
6955 for (width
= params
->length
; width
; width
--)
6957 dst_ptr
[0] = src_ptr
[0];
6958 dst_ptr
[1] = src_ptr
[1];
6959 dst_ptr
[2] = src_ptr
[2];
6960 dst_ptr
+= 3 * params
->dst_inc
;
6963 src_ptr
+= 3 * params
->src_inc
;
6964 err
+= params
->err_add_1
;
6966 else err
+= params
->err_add_2
;
6971 struct rop_codes codes
;
6973 rop_codes_from_stretch_mode( mode
, &codes
);
6974 for (width
= params
->length
; width
; width
--)
6976 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
6977 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
6978 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
6979 dst_ptr
+= 3 * params
->dst_inc
;
6982 src_ptr
+= 3 * params
->src_inc
;
6983 err
+= params
->err_add_1
;
6985 else err
+= params
->err_add_2
;
6990 static void stretch_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
6991 const dib_info
*src_dib
, const POINT
*src_start
,
6992 const struct stretch_params
*params
, int mode
,
6995 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
6996 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
6997 int err
= params
->err_start
;
7000 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
7002 for (width
= params
->length
; width
; width
--)
7004 *dst_ptr
= *src_ptr
;
7005 dst_ptr
+= params
->dst_inc
;
7008 src_ptr
+= params
->src_inc
;
7009 err
+= params
->err_add_1
;
7011 else err
+= params
->err_add_2
;
7016 struct rop_codes codes
;
7018 rop_codes_from_stretch_mode( mode
, &codes
);
7019 for (width
= params
->length
; width
; width
--)
7021 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
7022 dst_ptr
+= params
->dst_inc
;
7025 src_ptr
+= params
->src_inc
;
7026 err
+= params
->err_add_1
;
7028 else err
+= params
->err_add_2
;
7033 static void stretch_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
7034 const dib_info
*src_dib
, const POINT
*src_start
,
7035 const struct stretch_params
*params
, int mode
,
7038 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
7039 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
7040 int err
= params
->err_start
;
7043 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
7045 for (width
= params
->length
; width
; width
--)
7047 *dst_ptr
= *src_ptr
;
7048 dst_ptr
+= params
->dst_inc
;
7051 src_ptr
+= params
->src_inc
;
7052 err
+= params
->err_add_1
;
7054 else err
+= params
->err_add_2
;
7059 struct rop_codes codes
;
7061 rop_codes_from_stretch_mode( mode
, &codes
);
7062 for (width
= params
->length
; width
; width
--)
7064 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
7065 dst_ptr
+= params
->dst_inc
;
7068 src_ptr
+= params
->src_inc
;
7069 err
+= params
->err_add_1
;
7071 else err
+= params
->err_add_2
;
7076 static void stretch_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
7077 const dib_info
*src_dib
, const POINT
*src_start
,
7078 const struct stretch_params
*params
, int mode
,
7081 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
7082 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
7083 int err
= params
->err_start
;
7084 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
7085 struct rop_codes codes
;
7088 if (!keep_dst
) mode
= STRETCH_DELETESCANS
;
7089 rop_codes_from_stretch_mode( mode
, &codes
);
7090 for (width
= params
->length
; width
; width
--)
7092 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
7093 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
7095 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
7097 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
7098 dst_ptr
+= params
->dst_inc
;
7099 dst_x
+= params
->dst_inc
;
7103 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
7104 src_ptr
+= params
->src_inc
;
7105 src_x
+= params
->src_inc
;
7106 err
+= params
->err_add_1
;
7108 else err
+= params
->err_add_2
;
7112 static void stretch_row_1(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 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
7118 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
7119 int err
= params
->err_start
;
7120 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
7121 struct rop_codes codes
;
7124 if (!keep_dst
) mode
= STRETCH_DELETESCANS
;
7125 rop_codes_from_stretch_mode( mode
, &codes
);
7126 for (width
= params
->length
; width
; width
--)
7128 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
7129 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
7131 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
7132 dst_ptr
+= params
->dst_inc
;
7133 dst_x
+= params
->dst_inc
;
7137 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
7138 src_ptr
+= params
->src_inc
;
7139 src_x
+= params
->src_inc
;
7140 err
+= params
->err_add_1
;
7142 else err
+= params
->err_add_2
;
7146 static void stretch_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
7147 const dib_info
*src_dib
, const POINT
*src_start
,
7148 const struct stretch_params
*params
, int mode
,
7151 FIXME("bit count %d\n", dst_dib
->bit_count
);
7155 static void shrink_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
7156 const dib_info
*src_dib
, const POINT
*src_start
,
7157 const struct stretch_params
*params
, int mode
,
7160 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
7161 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
7162 int err
= params
->err_start
;
7165 if (mode
== STRETCH_DELETESCANS
)
7167 for (width
= params
->length
; width
; width
--)
7169 *dst_ptr
= *src_ptr
;
7170 src_ptr
+= params
->src_inc
;
7173 dst_ptr
+= params
->dst_inc
;
7174 err
+= params
->err_add_1
;
7176 else err
+= params
->err_add_2
;
7181 struct rop_codes codes
;
7182 DWORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
7183 BOOL new_pix
= TRUE
;
7185 rop_codes_from_stretch_mode( mode
, &codes
);
7186 for (width
= params
->length
; width
; width
--)
7188 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
7189 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
7191 src_ptr
+= params
->src_inc
;
7194 dst_ptr
+= params
->dst_inc
;
7196 err
+= params
->err_add_1
;
7198 else err
+= params
->err_add_2
;
7203 static void shrink_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
7204 const dib_info
*src_dib
, const POINT
*src_start
,
7205 const struct stretch_params
*params
, int mode
,
7208 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
7209 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
7210 int err
= params
->err_start
;
7213 if (mode
== STRETCH_DELETESCANS
)
7215 for (width
= params
->length
; width
; width
--)
7217 dst_ptr
[0] = src_ptr
[0];
7218 dst_ptr
[1] = src_ptr
[1];
7219 dst_ptr
[2] = src_ptr
[2];
7220 src_ptr
+= 3 * params
->src_inc
;
7223 dst_ptr
+= 3 * params
->dst_inc
;
7224 err
+= params
->err_add_1
;
7226 else err
+= params
->err_add_2
;
7231 struct rop_codes codes
;
7232 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
7233 BOOL new_pix
= TRUE
;
7235 rop_codes_from_stretch_mode( mode
, &codes
);
7236 for (width
= params
->length
; width
; width
--)
7238 if (new_pix
&& !keep_dst
) memset( dst_ptr
, init_val
, 3 );
7239 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
7240 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
7241 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
7243 src_ptr
+= 3 * params
->src_inc
;
7246 dst_ptr
+= 3 * params
->dst_inc
;
7248 err
+= params
->err_add_1
;
7250 else err
+= params
->err_add_2
;
7255 static void shrink_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
7256 const dib_info
*src_dib
, const POINT
*src_start
,
7257 const struct stretch_params
*params
, int mode
,
7260 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
7261 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
7262 int err
= params
->err_start
;
7265 if (mode
== STRETCH_DELETESCANS
)
7267 for (width
= params
->length
; width
; width
--)
7269 *dst_ptr
= *src_ptr
;
7270 src_ptr
+= params
->src_inc
;
7273 dst_ptr
+= params
->dst_inc
;
7274 err
+= params
->err_add_1
;
7276 else err
+= params
->err_add_2
;
7281 struct rop_codes codes
;
7282 WORD init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xffff : 0;
7283 BOOL new_pix
= TRUE
;
7285 rop_codes_from_stretch_mode( mode
, &codes
);
7286 for (width
= params
->length
; width
; width
--)
7288 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
7289 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
7291 src_ptr
+= params
->src_inc
;
7294 dst_ptr
+= params
->dst_inc
;
7296 err
+= params
->err_add_1
;
7298 else err
+= params
->err_add_2
;
7303 static void shrink_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
7304 const dib_info
*src_dib
, const POINT
*src_start
,
7305 const struct stretch_params
*params
, int mode
,
7308 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
7309 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
7310 int err
= params
->err_start
;
7313 if (mode
== STRETCH_DELETESCANS
)
7315 for (width
= params
->length
; width
; width
--)
7317 *dst_ptr
= *src_ptr
;
7318 src_ptr
+= params
->src_inc
;
7321 dst_ptr
+= params
->dst_inc
;
7322 err
+= params
->err_add_1
;
7324 else err
+= params
->err_add_2
;
7329 struct rop_codes codes
;
7330 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
7331 BOOL new_pix
= TRUE
;
7333 rop_codes_from_stretch_mode( mode
, &codes
);
7334 for (width
= params
->length
; width
; width
--)
7336 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
7337 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
7339 src_ptr
+= params
->src_inc
;
7342 dst_ptr
+= params
->dst_inc
;
7344 err
+= params
->err_add_1
;
7346 else err
+= params
->err_add_2
;
7351 static void shrink_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
7352 const dib_info
*src_dib
, const POINT
*src_start
,
7353 const struct stretch_params
*params
, int mode
,
7356 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
7357 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
7358 int err
= params
->err_start
;
7359 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
7360 struct rop_codes codes
;
7361 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
7362 BOOL new_pix
= TRUE
;
7364 rop_codes_from_stretch_mode( mode
, &codes
);
7365 for (width
= params
->length
; width
; width
--)
7367 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, (dst_x
& 1) ? 0x0f : 0xf0 );
7369 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
7370 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
7372 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
7375 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
7376 src_ptr
+= params
->src_inc
;
7377 src_x
+= params
->src_inc
;
7381 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
7382 dst_ptr
+= params
->dst_inc
;
7383 dst_x
+= params
->dst_inc
;
7385 err
+= params
->err_add_1
;
7387 else err
+= params
->err_add_2
;
7391 static void shrink_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
7392 const dib_info
*src_dib
, const POINT
*src_start
,
7393 const struct stretch_params
*params
, int mode
,
7396 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
7397 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
7398 int err
= params
->err_start
;
7399 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
7400 struct rop_codes codes
;
7401 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
7402 BOOL new_pix
= TRUE
;
7404 rop_codes_from_stretch_mode( mode
, &codes
);
7405 for (width
= params
->length
; width
; width
--)
7407 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, pixel_masks_1
[dst_x
% 8] );
7408 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
7409 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
7412 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
7413 src_ptr
+= params
->src_inc
;
7414 src_x
+= params
->src_inc
;
7418 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
7419 dst_ptr
+= params
->dst_inc
;
7420 dst_x
+= params
->dst_inc
;
7422 err
+= params
->err_add_1
;
7424 else err
+= params
->err_add_2
;
7428 static void shrink_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
7429 const dib_info
*src_dib
, const POINT
*src_start
,
7430 const struct stretch_params
*params
, int mode
,
7433 FIXME("bit count %d\n", dst_dib
->bit_count
);
7437 static float clampf( float value
, float min
, float max
)
7439 return max( min
, min( value
, max
) );
7442 static int clamp( int value
, int min
, int max
)
7444 return max( min
, min( value
, max
) );
7447 static BYTE
linear_interpolate( BYTE start
, BYTE end
, float delta
)
7449 return start
+ (end
- start
) * delta
+ 0.5f
;
7452 static BYTE
bilinear_interpolate( BYTE c00
, BYTE c01
, BYTE c10
, BYTE c11
, float dx
, float dy
)
7454 return linear_interpolate( linear_interpolate( c00
, c01
, dx
),
7455 linear_interpolate( c10
, c11
, dx
), dy
);
7458 static void calc_halftone_params( const struct bitblt_coords
*dst
, const struct bitblt_coords
*src
,
7459 RECT
*dst_rect
, RECT
*src_rect
, int *src_start_x
,
7460 int *src_start_y
, float *src_inc_x
, float *src_inc_y
)
7462 int src_width
, src_height
, dst_width
, dst_height
;
7463 BOOL mirrored_x
, mirrored_y
;
7465 get_bounding_rect( src_rect
, src
->x
, src
->y
, src
->width
, src
->height
);
7466 get_bounding_rect( dst_rect
, dst
->x
, dst
->y
, dst
->width
, dst
->height
);
7467 intersect_rect( src_rect
, &src
->visrect
, src_rect
);
7468 intersect_rect( dst_rect
, &dst
->visrect
, dst_rect
);
7469 OffsetRect( dst_rect
, -dst_rect
->left
, -dst_rect
->top
);
7471 src_width
= src_rect
->right
- src_rect
->left
;
7472 src_height
= src_rect
->bottom
- src_rect
->top
;
7473 dst_width
= dst_rect
->right
- dst_rect
->left
;
7474 dst_height
= dst_rect
->bottom
- dst_rect
->top
;
7476 mirrored_x
= (dst
->width
< 0) != (src
->width
< 0);
7477 mirrored_y
= (dst
->height
< 0) != (src
->height
< 0);
7478 *src_start_x
= mirrored_x
? src_rect
->right
- 1 : src_rect
->left
;
7479 *src_start_y
= mirrored_y
? src_rect
->bottom
- 1 : src_rect
->top
;
7480 *src_inc_x
= mirrored_x
? -(float)src_width
/ dst_width
: (float)src_width
/ dst_width
;
7481 *src_inc_y
= mirrored_y
? -(float)src_height
/ dst_height
: (float)src_height
/ dst_height
;
7484 static void halftone_888( const dib_info
*dst_dib
, const struct bitblt_coords
*dst
,
7485 const dib_info
*src_dib
, const struct bitblt_coords
*src
)
7487 int src_start_x
, src_start_y
, src_ptr_dy
, dst_x
, dst_y
, x0
, x1
, y0
, y1
;
7488 DWORD
*dst_ptr
, *src_ptr
, *c00_ptr
, *c01_ptr
, *c10_ptr
, *c11_ptr
;
7489 float src_inc_x
, src_inc_y
, float_x
, float_y
, dx
, dy
;
7490 BYTE c00_r
, c01_r
, c10_r
, c11_r
;
7491 BYTE c00_g
, c01_g
, c10_g
, c11_g
;
7492 BYTE c00_b
, c01_b
, c10_b
, c11_b
;
7493 RECT dst_rect
, src_rect
;
7496 calc_halftone_params( dst
, src
, &dst_rect
, &src_rect
, &src_start_x
, &src_start_y
, &src_inc_x
,
7499 float_y
= src_start_y
;
7500 dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_rect
.left
, dst_rect
.top
);
7501 for (dst_y
= 0; dst_y
< dst_rect
.bottom
- dst_rect
.top
; ++dst_y
)
7503 float_y
= clampf( float_y
, src_rect
.top
, src_rect
.bottom
- 1 );
7505 y1
= clamp( y0
+ 1, src_rect
.top
, src_rect
.bottom
- 1 );
7508 float_x
= src_start_x
;
7509 src_ptr
= get_pixel_ptr_32( src_dib
, 0, y0
);
7510 src_ptr_dy
= (y1
- y0
) * src_dib
->stride
/ 4;
7511 for (dst_x
= 0; dst_x
< dst_rect
.right
- dst_rect
.left
; ++dst_x
)
7513 float_x
= clampf( float_x
, src_rect
.left
, src_rect
.right
- 1 );
7515 x1
= clamp( x0
+ 1, src_rect
.left
, src_rect
.right
- 1 );
7518 c00_ptr
= src_ptr
+ x0
;
7519 c01_ptr
= src_ptr
+ x1
;
7520 c10_ptr
= c00_ptr
+ src_ptr_dy
;
7521 c11_ptr
= c01_ptr
+ src_ptr_dy
;
7522 c00_r
= (*c00_ptr
>> 16) & 0xff;
7523 c01_r
= (*c01_ptr
>> 16) & 0xff;
7524 c10_r
= (*c10_ptr
>> 16) & 0xff;
7525 c11_r
= (*c11_ptr
>> 16) & 0xff;
7526 c00_g
= (*c00_ptr
>> 8) & 0xff;
7527 c01_g
= (*c01_ptr
>> 8) & 0xff;
7528 c10_g
= (*c10_ptr
>> 8) & 0xff;
7529 c11_g
= (*c11_ptr
>> 8) & 0xff;
7530 c00_b
= *c00_ptr
& 0xff;
7531 c01_b
= *c01_ptr
& 0xff;
7532 c10_b
= *c10_ptr
& 0xff;
7533 c11_b
= *c11_ptr
& 0xff;
7534 r
= bilinear_interpolate( c00_r
, c01_r
, c10_r
, c11_r
, dx
, dy
);
7535 g
= bilinear_interpolate( c00_g
, c01_g
, c10_g
, c11_g
, dx
, dy
);
7536 b
= bilinear_interpolate( c00_b
, c01_b
, c10_b
, c11_b
, dx
, dy
);
7537 dst_ptr
[dst_x
] = ((r
<< 16) & 0xff0000) | ((g
<< 8) & 0x00ff00) | (b
& 0x0000ff);
7539 float_x
+= src_inc_x
;
7542 dst_ptr
+= dst_dib
->stride
/ 4;
7543 float_y
+= src_inc_y
;
7547 static void halftone_32( const dib_info
*dst_dib
, const struct bitblt_coords
*dst
,
7548 const dib_info
*src_dib
, const struct bitblt_coords
*src
)
7550 int src_start_x
, src_start_y
, src_ptr_dy
, dst_x
, dst_y
, x0
, x1
, y0
, y1
;
7551 DWORD
*dst_ptr
, *src_ptr
, *c00_ptr
, *c01_ptr
, *c10_ptr
, *c11_ptr
;
7552 float src_inc_x
, src_inc_y
, float_x
, float_y
, dx
, dy
;
7553 BYTE c00_r
, c01_r
, c10_r
, c11_r
;
7554 BYTE c00_g
, c01_g
, c10_g
, c11_g
;
7555 BYTE c00_b
, c01_b
, c10_b
, c11_b
;
7556 RECT dst_rect
, src_rect
;
7559 calc_halftone_params( dst
, src
, &dst_rect
, &src_rect
, &src_start_x
, &src_start_y
, &src_inc_x
,
7562 float_y
= src_start_y
;
7563 dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_rect
.left
, dst_rect
.top
);
7564 for (dst_y
= 0; dst_y
< dst_rect
.bottom
- dst_rect
.top
; ++dst_y
)
7566 float_y
= clampf( float_y
, src_rect
.top
, src_rect
.bottom
- 1 );
7568 y1
= clamp( y0
+ 1, src_rect
.top
, src_rect
.bottom
- 1 );
7571 float_x
= src_start_x
;
7572 src_ptr
= get_pixel_ptr_32( src_dib
, 0, y0
);
7573 src_ptr_dy
= (y1
- y0
) * src_dib
->stride
/ 4;
7574 for (dst_x
= 0; dst_x
< dst_rect
.right
- dst_rect
.left
; ++dst_x
)
7576 float_x
= clampf( float_x
, src_rect
.left
, src_rect
.right
- 1 );
7578 x1
= clamp( x0
+ 1, src_rect
.left
, src_rect
.right
- 1 );
7581 c00_ptr
= src_ptr
+ x0
;
7582 c01_ptr
= src_ptr
+ x1
;
7583 c10_ptr
= c00_ptr
+ src_ptr_dy
;
7584 c11_ptr
= c01_ptr
+ src_ptr_dy
;
7585 c00_r
= get_field( *c00_ptr
, src_dib
->red_shift
, src_dib
->red_len
);
7586 c01_r
= get_field( *c01_ptr
, src_dib
->red_shift
, src_dib
->red_len
);
7587 c10_r
= get_field( *c10_ptr
, src_dib
->red_shift
, src_dib
->red_len
);
7588 c11_r
= get_field( *c11_ptr
, src_dib
->red_shift
, src_dib
->red_len
);
7589 c00_g
= get_field( *c00_ptr
, src_dib
->green_shift
, src_dib
->green_len
);
7590 c01_g
= get_field( *c01_ptr
, src_dib
->green_shift
, src_dib
->green_len
);
7591 c10_g
= get_field( *c10_ptr
, src_dib
->green_shift
, src_dib
->green_len
);
7592 c11_g
= get_field( *c11_ptr
, src_dib
->green_shift
, src_dib
->green_len
);
7593 c00_b
= get_field( *c00_ptr
, src_dib
->blue_shift
, src_dib
->blue_len
);
7594 c01_b
= get_field( *c01_ptr
, src_dib
->blue_shift
, src_dib
->blue_len
);
7595 c10_b
= get_field( *c10_ptr
, src_dib
->blue_shift
, src_dib
->blue_len
);
7596 c11_b
= get_field( *c11_ptr
, src_dib
->blue_shift
, src_dib
->blue_len
);
7597 r
= bilinear_interpolate( c00_r
, c01_r
, c10_r
, c11_r
, dx
, dy
);
7598 g
= bilinear_interpolate( c00_g
, c01_g
, c10_g
, c11_g
, dx
, dy
);
7599 b
= bilinear_interpolate( c00_b
, c01_b
, c10_b
, c11_b
, dx
, dy
);
7600 dst_ptr
[dst_x
] = rgb_to_pixel_masks( dst_dib
, r
, g
, b
);
7602 float_x
+= src_inc_x
;
7605 dst_ptr
+= dst_dib
->stride
/ 4;
7606 float_y
+= src_inc_y
;
7610 static void halftone_24( const dib_info
*dst_dib
, const struct bitblt_coords
*dst
,
7611 const dib_info
*src_dib
, const struct bitblt_coords
*src
)
7613 int src_start_x
, src_start_y
, src_ptr_dy
, dst_x
, dst_y
, x0
, x1
, y0
, y1
;
7614 BYTE
*dst_ptr
, *src_ptr
, *c00_ptr
, *c01_ptr
, *c10_ptr
, *c11_ptr
;
7615 float src_inc_x
, src_inc_y
, float_x
, float_y
, dx
, dy
;
7616 BYTE c00_r
, c01_r
, c10_r
, c11_r
;
7617 BYTE c00_g
, c01_g
, c10_g
, c11_g
;
7618 BYTE c00_b
, c01_b
, c10_b
, c11_b
;
7619 RECT dst_rect
, src_rect
;
7622 calc_halftone_params( dst
, src
, &dst_rect
, &src_rect
, &src_start_x
, &src_start_y
, &src_inc_x
,
7625 float_y
= src_start_y
;
7626 dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_rect
.left
, dst_rect
.top
);
7627 for (dst_y
= 0; dst_y
< dst_rect
.bottom
- dst_rect
.top
; ++dst_y
)
7629 float_y
= clampf( float_y
, src_rect
.top
, src_rect
.bottom
- 1 );
7631 y1
= clamp( y0
+ 1, src_rect
.top
, src_rect
.bottom
- 1 );
7634 float_x
= src_start_x
;
7635 src_ptr
= get_pixel_ptr_24( src_dib
, 0, y0
);
7636 src_ptr_dy
= (y1
- y0
) * src_dib
->stride
;
7637 for (dst_x
= 0; dst_x
< dst_rect
.right
- dst_rect
.left
; ++dst_x
)
7639 float_x
= clampf( float_x
, src_rect
.left
, src_rect
.right
- 1 );
7641 x1
= clamp( x0
+ 1, src_rect
.left
, src_rect
.right
- 1 );
7644 c00_ptr
= src_ptr
+ x0
* 3;
7645 c01_ptr
= src_ptr
+ x1
* 3;
7646 c10_ptr
= c00_ptr
+ src_ptr_dy
;
7647 c11_ptr
= c01_ptr
+ src_ptr_dy
;
7660 r
= bilinear_interpolate( c00_r
, c01_r
, c10_r
, c11_r
, dx
, dy
);
7661 g
= bilinear_interpolate( c00_g
, c01_g
, c10_g
, c11_g
, dx
, dy
);
7662 b
= bilinear_interpolate( c00_b
, c01_b
, c10_b
, c11_b
, dx
, dy
);
7663 dst_ptr
[dst_x
* 3] = b
;
7664 dst_ptr
[dst_x
* 3 + 1] = g
;
7665 dst_ptr
[dst_x
* 3 + 2] = r
;
7667 float_x
+= src_inc_x
;
7670 dst_ptr
+= dst_dib
->stride
;
7671 float_y
+= src_inc_y
;
7675 static void halftone_555( const dib_info
*dst_dib
, const struct bitblt_coords
*dst
,
7676 const dib_info
*src_dib
, const struct bitblt_coords
*src
)
7678 int src_start_x
, src_start_y
, src_ptr_dy
, dst_x
, dst_y
, x0
, x1
, y0
, y1
;
7679 WORD
*dst_ptr
, *src_ptr
, *c00_ptr
, *c01_ptr
, *c10_ptr
, *c11_ptr
;
7680 float src_inc_x
, src_inc_y
, float_x
, float_y
, dx
, dy
;
7681 BYTE c00_r
, c01_r
, c10_r
, c11_r
;
7682 BYTE c00_g
, c01_g
, c10_g
, c11_g
;
7683 BYTE c00_b
, c01_b
, c10_b
, c11_b
;
7684 RECT dst_rect
, src_rect
;
7687 calc_halftone_params( dst
, src
, &dst_rect
, &src_rect
, &src_start_x
, &src_start_y
, &src_inc_x
,
7690 float_y
= src_start_y
;
7691 dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_rect
.left
, dst_rect
.top
);
7692 for (dst_y
= 0; dst_y
< dst_rect
.bottom
- dst_rect
.top
; ++dst_y
)
7694 float_y
= clampf( float_y
, src_rect
.top
, src_rect
.bottom
- 1 );
7696 y1
= clamp( y0
+ 1, src_rect
.top
, src_rect
.bottom
- 1 );
7699 float_x
= src_start_x
;
7700 src_ptr
= get_pixel_ptr_16( src_dib
, 0, y0
);
7701 src_ptr_dy
= (y1
- y0
) * src_dib
->stride
/ 2;
7702 for (dst_x
= 0; dst_x
< dst_rect
.right
- dst_rect
.left
; ++dst_x
)
7704 float_x
= clampf( float_x
, src_rect
.left
, src_rect
.right
- 1 );
7706 x1
= clamp( x0
+ 1, src_rect
.left
, src_rect
.right
- 1 );
7709 c00_ptr
= src_ptr
+ x0
;
7710 c01_ptr
= src_ptr
+ x1
;
7711 c10_ptr
= c00_ptr
+ src_ptr_dy
;
7712 c11_ptr
= c01_ptr
+ src_ptr_dy
;
7713 c00_r
= ((*c00_ptr
>> 7) & 0xf8) | ((*c00_ptr
>> 12) & 0x07);
7714 c01_r
= ((*c01_ptr
>> 7) & 0xf8) | ((*c01_ptr
>> 12) & 0x07);
7715 c10_r
= ((*c10_ptr
>> 7) & 0xf8) | ((*c10_ptr
>> 12) & 0x07);
7716 c11_r
= ((*c11_ptr
>> 7) & 0xf8) | ((*c11_ptr
>> 12) & 0x07);
7717 c00_g
= ((*c00_ptr
>> 2) & 0xf8) | ((*c00_ptr
>> 7) & 0x07);
7718 c01_g
= ((*c01_ptr
>> 2) & 0xf8) | ((*c01_ptr
>> 7) & 0x07);
7719 c10_g
= ((*c10_ptr
>> 2) & 0xf8) | ((*c10_ptr
>> 7) & 0x07);
7720 c11_g
= ((*c11_ptr
>> 2) & 0xf8) | ((*c11_ptr
>> 7) & 0x07);
7721 c00_b
= ((*c00_ptr
<< 3) & 0xf8) | ((*c00_ptr
>> 2) & 0x07);
7722 c01_b
= ((*c01_ptr
<< 3) & 0xf8) | ((*c01_ptr
>> 2) & 0x07);
7723 c10_b
= ((*c10_ptr
<< 3) & 0xf8) | ((*c10_ptr
>> 2) & 0x07);
7724 c11_b
= ((*c11_ptr
<< 3) & 0xf8) | ((*c11_ptr
>> 2) & 0x07);
7725 r
= bilinear_interpolate( c00_r
, c01_r
, c10_r
, c11_r
, dx
, dy
);
7726 g
= bilinear_interpolate( c00_g
, c01_g
, c10_g
, c11_g
, dx
, dy
);
7727 b
= bilinear_interpolate( c00_b
, c01_b
, c10_b
, c11_b
, dx
, dy
);
7728 dst_ptr
[dst_x
] = ((r
<< 7) & 0x7c00) | ((g
<< 2) & 0x03e0) | ((b
>> 3) & 0x001f);
7730 float_x
+= src_inc_x
;
7733 dst_ptr
+= dst_dib
->stride
/ 2;
7734 float_y
+= src_inc_y
;
7738 static void halftone_16( const dib_info
*dst_dib
, const struct bitblt_coords
*dst
,
7739 const dib_info
*src_dib
, const struct bitblt_coords
*src
)
7741 int src_start_x
, src_start_y
, src_ptr_dy
, dst_x
, dst_y
, x0
, x1
, y0
, y1
;
7742 WORD
*dst_ptr
, *src_ptr
, *c00_ptr
, *c01_ptr
, *c10_ptr
, *c11_ptr
;
7743 float src_inc_x
, src_inc_y
, float_x
, float_y
, dx
, dy
;
7744 BYTE c00_r
, c01_r
, c10_r
, c11_r
;
7745 BYTE c00_g
, c01_g
, c10_g
, c11_g
;
7746 BYTE c00_b
, c01_b
, c10_b
, c11_b
;
7747 RECT dst_rect
, src_rect
;
7750 calc_halftone_params( dst
, src
, &dst_rect
, &src_rect
, &src_start_x
, &src_start_y
, &src_inc_x
,
7753 float_y
= src_start_y
;
7754 dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_rect
.left
, dst_rect
.top
);
7755 for (dst_y
= 0; dst_y
< dst_rect
.bottom
- dst_rect
.top
; ++dst_y
)
7757 float_y
= clampf( float_y
, src_rect
.top
, src_rect
.bottom
- 1 );
7759 y1
= clamp( y0
+ 1, src_rect
.top
, src_rect
.bottom
- 1 );
7762 float_x
= src_start_x
;
7763 src_ptr
= get_pixel_ptr_16( src_dib
, 0, y0
);
7764 src_ptr_dy
= (y1
- y0
) * src_dib
->stride
/ 2;
7765 for (dst_x
= 0; dst_x
< dst_rect
.right
- dst_rect
.left
; ++dst_x
)
7767 float_x
= clampf( float_x
, src_rect
.left
, src_rect
.right
- 1 );
7769 x1
= clamp( x0
+ 1, src_rect
.left
, src_rect
.right
- 1 );
7772 c00_ptr
= src_ptr
+ x0
;
7773 c01_ptr
= src_ptr
+ x1
;
7774 c10_ptr
= c00_ptr
+ src_ptr_dy
;
7775 c11_ptr
= c01_ptr
+ src_ptr_dy
;
7776 c00_r
= get_field( *c00_ptr
, src_dib
->red_shift
, src_dib
->red_len
);
7777 c01_r
= get_field( *c01_ptr
, src_dib
->red_shift
, src_dib
->red_len
);
7778 c10_r
= get_field( *c10_ptr
, src_dib
->red_shift
, src_dib
->red_len
);
7779 c11_r
= get_field( *c11_ptr
, src_dib
->red_shift
, src_dib
->red_len
);
7780 c00_g
= get_field( *c00_ptr
, src_dib
->green_shift
, src_dib
->green_len
);
7781 c01_g
= get_field( *c01_ptr
, src_dib
->green_shift
, src_dib
->green_len
);
7782 c10_g
= get_field( *c10_ptr
, src_dib
->green_shift
, src_dib
->green_len
);
7783 c11_g
= get_field( *c11_ptr
, src_dib
->green_shift
, src_dib
->green_len
);
7784 c00_b
= get_field( *c00_ptr
, src_dib
->blue_shift
, src_dib
->blue_len
);
7785 c01_b
= get_field( *c01_ptr
, src_dib
->blue_shift
, src_dib
->blue_len
);
7786 c10_b
= get_field( *c10_ptr
, src_dib
->blue_shift
, src_dib
->blue_len
);
7787 c11_b
= get_field( *c11_ptr
, src_dib
->blue_shift
, src_dib
->blue_len
);
7788 r
= bilinear_interpolate( c00_r
, c01_r
, c10_r
, c11_r
, dx
, dy
);
7789 g
= bilinear_interpolate( c00_g
, c01_g
, c10_g
, c11_g
, dx
, dy
);
7790 b
= bilinear_interpolate( c00_b
, c01_b
, c10_b
, c11_b
, dx
, dy
);
7791 dst_ptr
[dst_x
] = rgb_to_pixel_masks( dst_dib
, r
, g
, b
);
7793 float_x
+= src_inc_x
;
7796 dst_ptr
+= dst_dib
->stride
/ 2;
7797 float_y
+= src_inc_y
;
7801 static void halftone_8( const dib_info
*dst_dib
, const struct bitblt_coords
*dst
,
7802 const dib_info
*src_dib
, const struct bitblt_coords
*src
)
7804 int src_start_x
, src_start_y
, src_ptr_dy
, dst_x
, dst_y
, x0
, x1
, y0
, y1
;
7805 BYTE
*dst_ptr
, *src_ptr
, *c00_ptr
, *c01_ptr
, *c10_ptr
, *c11_ptr
;
7806 RGBQUAD c00_rgb
, c01_rgb
, c10_rgb
, c11_rgb
, zero_rgb
= {0};
7807 float src_inc_x
, src_inc_y
, float_x
, float_y
, dx
, dy
;
7808 const RGBQUAD
*src_clr_table
;
7809 RECT dst_rect
, src_rect
;
7812 calc_halftone_params( dst
, src
, &dst_rect
, &src_rect
, &src_start_x
, &src_start_y
, &src_inc_x
,
7815 float_y
= src_start_y
;
7816 src_clr_table
= get_dib_color_table( src_dib
);
7817 dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_rect
.left
, dst_rect
.top
);
7818 for (dst_y
= 0; dst_y
< dst_rect
.bottom
- dst_rect
.top
; ++dst_y
)
7820 float_y
= clampf( float_y
, src_rect
.top
, src_rect
.bottom
- 1 );
7822 y1
= clamp( y0
+ 1, src_rect
.top
, src_rect
.bottom
- 1 );
7825 float_x
= src_start_x
;
7826 src_ptr
= get_pixel_ptr_8( src_dib
, 0, y0
);
7827 src_ptr_dy
= (y1
- y0
) * src_dib
->stride
;
7828 for (dst_x
= 0; dst_x
< dst_rect
.right
- dst_rect
.left
; ++dst_x
)
7830 float_x
= clampf( float_x
, src_rect
.left
, src_rect
.right
- 1 );
7832 x1
= clamp( x0
+ 1, src_rect
.left
, src_rect
.right
- 1 );
7835 c00_ptr
= src_ptr
+ x0
;
7836 c01_ptr
= src_ptr
+ x1
;
7837 c10_ptr
= c00_ptr
+ src_ptr_dy
;
7838 c11_ptr
= c01_ptr
+ src_ptr_dy
;
7841 c00_rgb
= *c00_ptr
< src_dib
->color_table_size
? src_clr_table
[*c00_ptr
] : zero_rgb
;
7842 c01_rgb
= *c01_ptr
< src_dib
->color_table_size
? src_clr_table
[*c01_ptr
] : zero_rgb
;
7843 c10_rgb
= *c10_ptr
< src_dib
->color_table_size
? src_clr_table
[*c10_ptr
] : zero_rgb
;
7844 c11_rgb
= *c11_ptr
< src_dib
->color_table_size
? src_clr_table
[*c11_ptr
] : zero_rgb
;
7845 r
= bilinear_interpolate( c00_rgb
.rgbRed
, c01_rgb
.rgbRed
, c10_rgb
.rgbRed
, c11_rgb
.rgbRed
, dx
, dy
);
7846 g
= bilinear_interpolate( c00_rgb
.rgbGreen
, c01_rgb
.rgbGreen
, c10_rgb
.rgbGreen
, c11_rgb
.rgbGreen
, dx
, dy
);
7847 b
= bilinear_interpolate( c00_rgb
.rgbBlue
, c01_rgb
.rgbBlue
, c10_rgb
.rgbBlue
, c11_rgb
.rgbBlue
, dx
, dy
);
7855 dst_ptr
[dst_x
] = rgb_to_pixel_colortable( dst_dib
, r
, g
, b
);
7857 float_x
+= src_inc_x
;
7860 dst_ptr
+= dst_dib
->stride
;
7861 float_y
+= src_inc_y
;
7865 static void halftone_4( const dib_info
*dst_dib
, const struct bitblt_coords
*dst
,
7866 const dib_info
*src_dib
, const struct bitblt_coords
*src
)
7868 BYTE
*dst_col_ptr
, *dst_ptr
, *src_ptr
, *c00_ptr
, *c01_ptr
, *c10_ptr
, *c11_ptr
;
7869 int src_start_x
, src_start_y
, src_ptr_dy
, dst_x
, dst_y
, x0
, x1
, y0
, y1
;
7870 RGBQUAD c00_rgb
, c01_rgb
, c10_rgb
, c11_rgb
, zero_rgb
= {0};
7871 float src_inc_x
, src_inc_y
, float_x
, float_y
, dx
, dy
;
7872 BYTE r
, g
, b
, val
, c00
, c01
, c10
, c11
;
7873 const RGBQUAD
*src_clr_table
;
7874 RECT dst_rect
, src_rect
;
7876 calc_halftone_params( dst
, src
, &dst_rect
, &src_rect
, &src_start_x
, &src_start_y
, &src_inc_x
,
7879 float_y
= src_start_y
;
7880 src_clr_table
= get_dib_color_table( src_dib
);
7881 dst_col_ptr
= (BYTE
*)dst_dib
->bits
.ptr
+ (dst_dib
->rect
.top
+ dst_rect
.top
) * dst_dib
->stride
;
7882 for (dst_y
= 0; dst_y
< dst_rect
.bottom
- dst_rect
.top
; ++dst_y
)
7884 float_y
= clampf( float_y
, src_rect
.top
, src_rect
.bottom
- 1 );
7886 y1
= clamp( y0
+ 1, src_rect
.top
, src_rect
.bottom
- 1 );
7889 float_x
= src_start_x
;
7890 src_ptr
= (BYTE
*)src_dib
->bits
.ptr
+ (src_dib
->rect
.top
+ y0
) * src_dib
->stride
;
7891 src_ptr_dy
= (y1
- y0
) * src_dib
->stride
;
7892 for (dst_x
= dst_rect
.left
; dst_x
< dst_rect
.right
; ++dst_x
)
7894 float_x
= clampf( float_x
, src_rect
.left
, src_rect
.right
- 1 );
7896 x1
= clamp( x0
+ 1, src_rect
.left
, src_rect
.right
- 1 );
7899 c00_ptr
= src_ptr
+ (src_dib
->rect
.left
+ x0
) / 2;
7900 c01_ptr
= src_ptr
+ (src_dib
->rect
.left
+ x1
) / 2;
7901 c10_ptr
= c00_ptr
+ src_ptr_dy
;
7902 c11_ptr
= c01_ptr
+ src_ptr_dy
;
7903 if ((src_dib
->rect
.left
+ x0
) & 1)
7905 c00
= *c00_ptr
& 0x0f;
7906 c10
= *c10_ptr
& 0x0f;
7910 c00
= (*c00_ptr
>> 4) & 0x0f;
7911 c10
= (*c10_ptr
>> 4) & 0x0f;
7913 if ((src_dib
->rect
.left
+ x1
) & 1)
7915 c01
= *c01_ptr
& 0x0f;
7916 c11
= *c11_ptr
& 0x0f;
7920 c01
= (*c01_ptr
>> 4) & 0x0f;
7921 c11
= (*c11_ptr
>> 4) & 0x0f;
7926 c00_rgb
= c00
< src_dib
->color_table_size
? src_clr_table
[c00
] : zero_rgb
;
7927 c01_rgb
= c01
< src_dib
->color_table_size
? src_clr_table
[c01
] : zero_rgb
;
7928 c10_rgb
= c10
< src_dib
->color_table_size
? src_clr_table
[c10
] : zero_rgb
;
7929 c11_rgb
= c11
< src_dib
->color_table_size
? src_clr_table
[c11
] : zero_rgb
;
7930 r
= bilinear_interpolate( c00_rgb
.rgbRed
, c01_rgb
.rgbRed
, c10_rgb
.rgbRed
, c11_rgb
.rgbRed
, dx
, dy
);
7931 g
= bilinear_interpolate( c00_rgb
.rgbGreen
, c01_rgb
.rgbGreen
, c10_rgb
.rgbGreen
, c11_rgb
.rgbGreen
, dx
, dy
);
7932 b
= bilinear_interpolate( c00_rgb
.rgbBlue
, c01_rgb
.rgbBlue
, c10_rgb
.rgbBlue
, c11_rgb
.rgbBlue
, dx
, dy
);
7941 dst_ptr
= dst_col_ptr
+ (dst_dib
->rect
.left
+ dst_x
) / 2;
7942 val
= rgb_to_pixel_colortable( dst_dib
, r
, g
, b
);
7943 if ((dst_x
+ dst_dib
->rect
.left
) & 1)
7944 *dst_ptr
= (val
& 0x0f) | (*dst_ptr
& 0xf0);
7946 *dst_ptr
= (val
<< 4) & 0xf0;
7948 float_x
+= src_inc_x
;
7951 dst_col_ptr
+= dst_dib
->stride
;
7952 float_y
+= src_inc_y
;
7956 static void halftone_1( const dib_info
*dst_dib
, const struct bitblt_coords
*dst
,
7957 const dib_info
*src_dib
, const struct bitblt_coords
*src
)
7959 int src_start_x
, src_start_y
, src_ptr_dy
, dst_x
, dst_y
, x0
, x1
, y0
, y1
, bit_pos
;
7960 BYTE
*dst_col_ptr
, *dst_ptr
, *src_ptr
, *c00_ptr
, *c01_ptr
, *c10_ptr
, *c11_ptr
;
7961 RGBQUAD c00_rgb
, c01_rgb
, c10_rgb
, c11_rgb
, zero_rgb
= {0};
7962 float src_inc_x
, src_inc_y
, float_x
, float_y
, dx
, dy
;
7963 BYTE r
, g
, b
, val
, c00
, c01
, c10
, c11
;
7964 const RGBQUAD
*src_clr_table
;
7965 RECT dst_rect
, src_rect
;
7969 calc_halftone_params( dst
, src
, &dst_rect
, &src_rect
, &src_start_x
, &src_start_y
, &src_inc_x
,
7972 float_y
= src_start_y
;
7973 bg_entry
= *get_dib_color_table( dst_dib
);
7974 src_clr_table
= get_dib_color_table( src_dib
);
7975 dst_col_ptr
= (BYTE
*)dst_dib
->bits
.ptr
+ (dst_dib
->rect
.top
+ dst_rect
.top
) * dst_dib
->stride
;
7976 for (dst_y
= dst_rect
.top
; dst_y
< dst_rect
.bottom
; ++dst_y
)
7978 float_y
= clampf( float_y
, src_rect
.top
, src_rect
.bottom
- 1 );
7980 y1
= clamp( y0
+ 1, src_rect
.top
, src_rect
.bottom
- 1 );
7983 float_x
= src_start_x
;
7984 src_ptr
= (BYTE
*)src_dib
->bits
.ptr
+ (src_dib
->rect
.top
+ y0
) * src_dib
->stride
;
7985 src_ptr_dy
= (y1
- y0
) * src_dib
->stride
;
7986 for (dst_x
= dst_rect
.left
; dst_x
< dst_rect
.right
; ++dst_x
)
7988 float_x
= clampf( float_x
, src_rect
.left
, src_rect
.right
- 1 );
7990 x1
= clamp( x0
+ 1, src_rect
.left
, src_rect
.right
- 1 );
7993 c00_ptr
= src_ptr
+ (src_dib
->rect
.left
+ x0
) / 8;
7994 c01_ptr
= src_ptr
+ (src_dib
->rect
.left
+ x1
) / 8;
7995 c10_ptr
= c00_ptr
+ src_ptr_dy
;
7996 c11_ptr
= c01_ptr
+ src_ptr_dy
;
7997 c00
= (*c00_ptr
& pixel_masks_1
[(src_dib
->rect
.left
+ x0
) & 7]) ? 1 : 0;
7998 c01
= (*c01_ptr
& pixel_masks_1
[(src_dib
->rect
.left
+ x1
) & 7]) ? 1 : 0;
7999 c10
= (*c10_ptr
& pixel_masks_1
[(src_dib
->rect
.left
+ x0
) & 7]) ? 1 : 0;
8000 c11
= (*c11_ptr
& pixel_masks_1
[(src_dib
->rect
.left
+ x1
) & 7]) ? 1 : 0;
8004 c00_rgb
= c00
< src_dib
->color_table_size
? src_clr_table
[c00
] : zero_rgb
;
8005 c01_rgb
= c01
< src_dib
->color_table_size
? src_clr_table
[c01
] : zero_rgb
;
8006 c10_rgb
= c10
< src_dib
->color_table_size
? src_clr_table
[c10
] : zero_rgb
;
8007 c11_rgb
= c11
< src_dib
->color_table_size
? src_clr_table
[c11
] : zero_rgb
;
8008 r
= bilinear_interpolate( c00_rgb
.rgbRed
, c01_rgb
.rgbRed
, c10_rgb
.rgbRed
, c11_rgb
.rgbRed
, dx
, dy
);
8009 g
= bilinear_interpolate( c00_rgb
.rgbGreen
, c01_rgb
.rgbGreen
, c10_rgb
.rgbGreen
, c11_rgb
.rgbGreen
, dx
, dy
);
8010 b
= bilinear_interpolate( c00_rgb
.rgbBlue
, c01_rgb
.rgbBlue
, c10_rgb
.rgbBlue
, c11_rgb
.rgbBlue
, dx
, dy
);
8019 dst_ptr
= dst_col_ptr
+ (dst_dib
->rect
.left
+ dst_x
) / 8;
8020 bit_pos
= (dst_x
+ dst_dib
->rect
.left
) & 7;
8021 bg_pixel
= FILTER_DIBINDEX(bg_entry
, RGB(bg_entry
.rgbRed
, bg_entry
.rgbGreen
, bg_entry
.rgbBlue
));
8022 val
= rgb_to_pixel_mono( dst_dib
, FALSE
, dst_x
, dst_y
, RGB(r
, g
, b
), bg_pixel
, r
, g
, b
);
8025 *dst_ptr
= (*dst_ptr
& ~pixel_masks_1
[bit_pos
]) | (val
& pixel_masks_1
[bit_pos
]);
8027 float_x
+= src_inc_x
;
8030 dst_col_ptr
+= dst_dib
->stride
;
8031 float_y
+= src_inc_y
;
8035 static void halftone_null( const dib_info
*dst_dib
, const struct bitblt_coords
*dst
,
8036 const dib_info
*src_dib
, const struct bitblt_coords
*src
)
8039 const primitive_funcs funcs_8888
=
8049 draw_subpixel_glyph_8888
,
8051 colorref_to_pixel_888
,
8052 pixel_to_colorref_888
,
8054 create_rop_masks_32
,
8055 create_dither_masks_null
,
8061 const primitive_funcs funcs_32
=
8071 draw_subpixel_glyph_32
,
8073 colorref_to_pixel_masks
,
8074 pixel_to_colorref_masks
,
8076 create_rop_masks_32
,
8077 create_dither_masks_null
,
8083 const primitive_funcs funcs_24
=
8093 draw_subpixel_glyph_24
,
8095 colorref_to_pixel_888
,
8096 pixel_to_colorref_888
,
8098 create_rop_masks_24
,
8099 create_dither_masks_null
,
8105 const primitive_funcs funcs_555
=
8115 draw_subpixel_glyph_555
,
8117 colorref_to_pixel_555
,
8118 pixel_to_colorref_555
,
8120 create_rop_masks_16
,
8121 create_dither_masks_null
,
8127 const primitive_funcs funcs_16
=
8137 draw_subpixel_glyph_16
,
8139 colorref_to_pixel_masks
,
8140 pixel_to_colorref_masks
,
8142 create_rop_masks_16
,
8143 create_dither_masks_null
,
8149 const primitive_funcs funcs_8
=
8159 draw_subpixel_glyph_null
,
8161 colorref_to_pixel_colortable
,
8162 pixel_to_colorref_colortable
,
8165 create_dither_masks_8
,
8171 const primitive_funcs funcs_4
=
8181 draw_subpixel_glyph_null
,
8183 colorref_to_pixel_colortable
,
8184 pixel_to_colorref_colortable
,
8187 create_dither_masks_4
,
8193 const primitive_funcs funcs_1
=
8203 draw_subpixel_glyph_null
,
8205 colorref_to_pixel_colortable
,
8206 pixel_to_colorref_colortable
,
8209 create_dither_masks_1
,
8215 const primitive_funcs funcs_null
=
8225 draw_subpixel_glyph_null
,
8227 colorref_to_pixel_null
,
8228 pixel_to_colorref_null
,
8230 create_rop_masks_null
,
8231 create_dither_masks_null
,