2 * DIB driver primitives.
4 * Copyright 2011 Huw Davies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "gdi_private.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(dib
);
30 /* Bayer matrices for dithering */
32 static const BYTE bayer_4x4
[4][4] =
40 static const BYTE bayer_8x8
[8][8] =
42 { 0, 32, 8, 40, 2, 34, 10, 42 },
43 { 48, 16, 56, 24, 50, 18, 58, 26 },
44 { 12, 44, 4, 36, 14, 46, 6, 38 },
45 { 60, 28, 52, 20, 62, 30, 54, 22 },
46 { 3, 35, 11, 43, 1, 33, 9, 41 },
47 { 51, 19, 59, 27, 49, 17, 57, 25 },
48 { 15, 47, 7, 39, 13, 45, 5, 37 },
49 { 63, 31, 55, 23, 61, 29, 53, 21 }
52 static const BYTE bayer_16x16
[16][16] =
54 { 0, 128, 32, 160, 8, 136, 40, 168, 2, 130, 34, 162, 10, 138, 42, 170 },
55 { 192, 64, 224, 96, 200, 72, 232, 104, 194, 66, 226, 98, 202, 74, 234, 106 },
56 { 48, 176, 16, 144, 56, 184, 24, 152, 50, 178, 18, 146, 58, 186, 26, 154 },
57 { 240, 112, 208, 80, 248, 120, 216, 88, 242, 114, 210, 82, 250, 122, 218, 90 },
58 { 12, 140, 44, 172, 4, 132, 36, 164, 14, 142, 46, 174, 6, 134, 38, 166 },
59 { 204, 76, 236, 108, 196, 68, 228, 100, 206, 78, 238, 110, 198, 70, 230, 102 },
60 { 60, 188, 28, 156, 52, 180, 20, 148, 62, 190, 30, 158, 54, 182, 22, 150 },
61 { 252, 124, 220, 92, 244, 116, 212, 84, 254, 126, 222, 94, 246, 118, 214, 86 },
62 { 3, 131, 35, 163, 11, 139, 43, 171, 1, 129, 33, 161, 9, 137, 41, 169 },
63 { 195, 67, 227, 99, 203, 75, 235, 107, 193, 65, 225, 97, 201, 73, 233, 105 },
64 { 51, 179, 19, 147, 59, 187, 27, 155, 49, 177, 17, 145, 57, 185, 25, 153 },
65 { 243, 115, 211, 83, 251, 123, 219, 91, 241, 113, 209, 81, 249, 121, 217, 89 },
66 { 15, 143, 47, 175, 7, 135, 39, 167, 13, 141, 45, 173, 5, 133, 37, 165 },
67 { 207, 79, 239, 111, 199, 71, 231, 103, 205, 77, 237, 109, 197, 69, 229, 101 },
68 { 63, 191, 31, 159, 55, 183, 23, 151, 61, 189, 29, 157, 53, 181, 21, 149 },
69 { 255, 127, 223, 95, 247, 119, 215, 87, 253, 125, 221, 93, 245, 117, 213, 85 },
72 static inline DWORD
*get_pixel_ptr_32(const dib_info
*dib
, int x
, int y
)
74 return (DWORD
*)((BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) * 4);
77 static inline DWORD
*get_pixel_ptr_24_dword(const dib_info
*dib
, int x
, int y
)
79 return (DWORD
*)((BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
) + (dib
->rect
.left
+ x
) * 3 / 4;
82 static inline BYTE
*get_pixel_ptr_24(const dib_info
*dib
, int x
, int y
)
84 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) * 3;
87 static inline WORD
*get_pixel_ptr_16(const dib_info
*dib
, int x
, int y
)
89 return (WORD
*)((BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) * 2);
92 static inline BYTE
*get_pixel_ptr_8(const dib_info
*dib
, int x
, int y
)
94 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ dib
->rect
.left
+ x
;
97 static inline BYTE
*get_pixel_ptr_4(const dib_info
*dib
, int x
, int y
)
99 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) / 2;
102 static inline BYTE
*get_pixel_ptr_1(const dib_info
*dib
, int x
, int y
)
104 return (BYTE
*)dib
->bits
.ptr
+ (dib
->rect
.top
+ y
) * dib
->stride
+ (dib
->rect
.left
+ x
) / 8;
107 static const BYTE pixel_masks_4
[2] = {0xf0, 0x0f};
108 static const BYTE pixel_masks_1
[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
110 static inline void do_rop_32(DWORD
*ptr
, DWORD
and, DWORD
xor)
112 *ptr
= (*ptr
& and) ^ xor;
115 static inline void do_rop_16(WORD
*ptr
, WORD
and, WORD
xor)
117 *ptr
= (*ptr
& and) ^ xor;
120 static inline void do_rop_8(BYTE
*ptr
, BYTE
and, BYTE
xor)
122 *ptr
= (*ptr
& and) ^ xor;
125 static inline void do_rop_mask_8(BYTE
*ptr
, BYTE
and, BYTE
xor, BYTE mask
)
127 *ptr
= (*ptr
& (and | ~mask
)) ^ (xor & mask
);
130 static inline void do_rop_codes_32(DWORD
*dst
, DWORD src
, struct rop_codes
*codes
)
132 do_rop_32( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
135 static inline void do_rop_codes_16(WORD
*dst
, WORD src
, struct rop_codes
*codes
)
137 do_rop_16( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
140 static inline void do_rop_codes_8(BYTE
*dst
, BYTE src
, struct rop_codes
*codes
)
142 do_rop_8( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
);
145 static inline void do_rop_codes_mask_8(BYTE
*dst
, BYTE src
, struct rop_codes
*codes
, BYTE mask
)
147 do_rop_mask_8( dst
, (src
& codes
->a1
) ^ codes
->a2
, (src
& codes
->x1
) ^ codes
->x2
, mask
);
150 static inline void do_rop_codes_line_32(DWORD
*dst
, const DWORD
*src
, struct rop_codes
*codes
, int len
)
152 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_32( dst
, *src
, codes
);
155 static inline void do_rop_codes_line_rev_32(DWORD
*dst
, const DWORD
*src
, struct rop_codes
*codes
, int len
)
157 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
158 do_rop_codes_32( dst
, *src
, codes
);
161 static inline void do_rop_codes_line_16(WORD
*dst
, const WORD
*src
, struct rop_codes
*codes
, int len
)
163 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_16( dst
, *src
, codes
);
166 static inline void do_rop_codes_line_rev_16(WORD
*dst
, const WORD
*src
, struct rop_codes
*codes
, int len
)
168 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
169 do_rop_codes_16( dst
, *src
, codes
);
172 static inline void do_rop_codes_line_8(BYTE
*dst
, const BYTE
*src
, struct rop_codes
*codes
, int len
)
174 for (; len
> 0; len
--, src
++, dst
++) do_rop_codes_8( dst
, *src
, codes
);
177 static inline void do_rop_codes_line_rev_8(BYTE
*dst
, const BYTE
*src
, struct rop_codes
*codes
, int len
)
179 for (src
+= len
- 1, dst
+= len
- 1; len
> 0; len
--, src
--, dst
--)
180 do_rop_codes_8( dst
, *src
, codes
);
183 static inline void do_rop_codes_line_4(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
184 struct rop_codes
*codes
, int len
)
188 for (src
+= src_x
/ 2, dst
+= dst_x
/ 2; len
> 0; len
--, dst_x
++, src_x
++)
192 if (src_x
& 1) src_val
= *src
++;
193 else src_val
= *src
>> 4;
194 do_rop_codes_mask_8( dst
++, src_val
, codes
, 0x0f );
198 if (src_x
& 1) src_val
= *src
++ << 4;
200 do_rop_codes_mask_8( dst
, src_val
, codes
, 0xf0 );
205 static inline void do_rop_codes_line_rev_4(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
206 struct rop_codes
*codes
, int len
)
212 for (src
+= src_x
/ 2, dst
+= dst_x
/ 2; len
> 0; len
--, dst_x
--, src_x
--)
216 if (src_x
& 1) src_val
= *src
;
217 else src_val
= *src
-- >> 4;
218 do_rop_codes_mask_8( dst
, src_val
, codes
, 0x0f );
222 if (src_x
& 1) src_val
= *src
<< 4;
223 else src_val
= *src
--;
224 do_rop_codes_mask_8( dst
--, src_val
, codes
, 0xf0 );
229 static inline void do_rop_codes_line_1(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
230 struct rop_codes
*codes
, int len
)
234 for (src
+= src_x
/ 8, dst
+= dst_x
/ 8; len
> 0; len
--, dst_x
++, src_x
++)
236 src_val
= *src
& pixel_masks_1
[src_x
& 7] ? 0xff : 0;
237 do_rop_codes_mask_8( dst
, src_val
, codes
, pixel_masks_1
[dst_x
& 7] );
238 if ((src_x
& 7) == 7) src
++;
239 if ((dst_x
& 7) == 7) dst
++;
243 static inline void do_rop_codes_line_rev_1(BYTE
*dst
, int dst_x
, const BYTE
*src
, int src_x
,
244 struct rop_codes
*codes
, int len
)
250 for (src
+= src_x
/ 8, dst
+= dst_x
/ 8; len
> 0; len
--, dst_x
--, src_x
--)
252 src_val
= *src
& pixel_masks_1
[src_x
& 7] ? 0xff : 0;
253 do_rop_codes_mask_8( dst
, src_val
, codes
, pixel_masks_1
[dst_x
& 7] );
254 if ((src_x
& 7) == 0) src
--;
255 if ((dst_x
& 7) == 0) dst
--;
259 static inline void memset_32( DWORD
*start
, DWORD val
, DWORD size
)
261 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
263 __asm__
__volatile__( "cld; rep; stosl"
264 : "=c" (dummy
), "=D" (dummy
)
265 : "a" (val
), "0" (size
), "1" (start
) );
267 while (size
--) *start
++ = val
;
271 static inline void memset_16( WORD
*start
, WORD val
, DWORD size
)
273 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
275 __asm__
__volatile__( "cld; rep; stosw"
276 : "=c" (dummy
), "=D" (dummy
)
277 : "a" (val
), "0" (size
), "1" (start
) );
279 while (size
--) *start
++ = val
;
283 static void solid_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
288 for(i
= 0; i
< num
; i
++, rc
++)
290 assert( !is_rect_empty( rc
));
292 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
294 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
295 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
296 do_rop_32(ptr
++, and, xor);
298 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
299 memset_32( start
, xor, rc
->right
- rc
->left
);
303 static void solid_rects_24(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
306 BYTE
*byte_ptr
, *byte_start
;
308 DWORD and_masks
[3], xor_masks
[3];
310 and_masks
[0] = ( and & 0x00ffffff) | ((and << 24) & 0xff000000);
311 and_masks
[1] = ((and >> 8) & 0x0000ffff) | ((and << 16) & 0xffff0000);
312 and_masks
[2] = ((and >> 16) & 0x000000ff) | ((and << 8) & 0xffffff00);
313 xor_masks
[0] = ( xor & 0x00ffffff) | ((xor << 24) & 0xff000000);
314 xor_masks
[1] = ((xor >> 8) & 0x0000ffff) | ((xor << 16) & 0xffff0000);
315 xor_masks
[2] = ((xor >> 16) & 0x000000ff) | ((xor << 8) & 0xffffff00);
317 for(i
= 0; i
< num
; i
++, rc
++)
319 int left
= dib
->rect
.left
+ rc
->left
;
320 int right
= dib
->rect
.left
+ rc
->right
;
322 assert( !is_rect_empty( rc
));
324 if ((left
& ~3) == (right
& ~3)) /* Special case for lines that start and end in the same DWORD triplet */
326 byte_start
= get_pixel_ptr_24(dib
, rc
->left
, rc
->top
);
327 for(y
= rc
->top
; y
< rc
->bottom
; y
++, byte_start
+= dib
->stride
)
329 for(x
= left
, byte_ptr
= byte_start
; x
< right
; x
++)
331 do_rop_8(byte_ptr
++, and_masks
[0] & 0xff, xor_masks
[0] & 0xff);
332 do_rop_8(byte_ptr
++, and_masks
[1] & 0xff, xor_masks
[1] & 0xff);
333 do_rop_8(byte_ptr
++, and_masks
[2] & 0xff, xor_masks
[2] & 0xff);
339 start
= get_pixel_ptr_24_dword(dib
, rc
->left
, rc
->top
);
340 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
347 do_rop_32(ptr
++, and_masks
[0] | 0x00ffffff, xor_masks
[0] & 0xff000000);
348 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
349 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
352 do_rop_32(ptr
++, and_masks
[1] | 0x0000ffff, xor_masks
[1] & 0xffff0000);
353 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
356 do_rop_32(ptr
++, and_masks
[2] | 0x000000ff, xor_masks
[2] & 0xffffff00);
360 for(x
= (left
+ 3) & ~3; x
< (right
& ~3); x
+= 4)
362 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
363 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
364 do_rop_32(ptr
++, and_masks
[2], xor_masks
[2]);
370 do_rop_32(ptr
, and_masks
[0] | 0xff000000, xor_masks
[0] & 0x00ffffff);
373 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
374 do_rop_32(ptr
, and_masks
[1] | 0xffff0000, xor_masks
[1] & 0x0000ffff);
377 do_rop_32(ptr
++, and_masks
[0], xor_masks
[0]);
378 do_rop_32(ptr
++, and_masks
[1], xor_masks
[1]);
379 do_rop_32(ptr
, and_masks
[2] | 0xffffff00, xor_masks
[2] & 0x000000ff);
386 start
= get_pixel_ptr_24_dword(dib
, rc
->left
, rc
->top
);
387 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
394 do_rop_32(ptr
++, 0x00ffffff, xor_masks
[0] & 0xff000000);
395 *ptr
++ = xor_masks
[1];
396 *ptr
++ = xor_masks
[2];
399 do_rop_32(ptr
++, 0x0000ffff, xor_masks
[1] & 0xffff0000);
400 *ptr
++ = xor_masks
[2];
403 do_rop_32(ptr
++, 0x000000ff, xor_masks
[2] & 0xffffff00);
407 for(x
= (left
+ 3) & ~3; x
< (right
& ~3); x
+= 4)
409 *ptr
++ = xor_masks
[0];
410 *ptr
++ = xor_masks
[1];
411 *ptr
++ = xor_masks
[2];
417 do_rop_32(ptr
, 0xff000000, xor_masks
[0] & 0x00ffffff);
420 *ptr
++ = xor_masks
[0];
421 do_rop_32(ptr
, 0xffff0000, xor_masks
[1] & 0x0000ffff);
424 *ptr
++ = xor_masks
[0];
425 *ptr
++ = xor_masks
[1];
426 do_rop_32(ptr
, 0xffffff00, xor_masks
[2] & 0x000000ff);
434 static void solid_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
439 for(i
= 0; i
< num
; i
++, rc
++)
441 assert( !is_rect_empty( rc
));
443 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
445 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
446 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
447 do_rop_16(ptr
++, and, xor);
449 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
450 memset_16( start
, xor, rc
->right
- rc
->left
);
454 static void solid_rects_8(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
459 for(i
= 0; i
< num
; i
++, rc
++)
461 assert( !is_rect_empty( rc
));
463 start
= get_pixel_ptr_8(dib
, rc
->left
, rc
->top
);
465 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
466 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
467 do_rop_8(ptr
++, and, xor);
469 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
470 memset( start
, xor, rc
->right
- rc
->left
);
474 static void solid_rects_4(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
478 BYTE byte_and
= (and & 0xf) | ((and << 4) & 0xf0);
479 BYTE byte_xor
= (xor & 0xf) | ((xor << 4) & 0xf0);
481 for(i
= 0; i
< num
; i
++, rc
++)
483 int left
= dib
->rect
.left
+ rc
->left
;
484 int right
= dib
->rect
.left
+ rc
->right
;
486 assert( !is_rect_empty( rc
));
488 start
= get_pixel_ptr_4(dib
, rc
->left
, rc
->top
);
491 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
494 if(left
& 1) /* upper nibble untouched */
495 do_rop_8(ptr
++, byte_and
| 0xf0, byte_xor
& 0x0f);
497 for(x
= (left
+ 1) & ~1; x
< (right
& ~1); x
+= 2)
498 do_rop_8(ptr
++, byte_and
, byte_xor
);
500 if(right
& 1) /* lower nibble untouched */
501 do_rop_8(ptr
, byte_and
| 0x0f, byte_xor
& 0xf0);
506 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
508 unsigned int byte_len
= (right
- ((left
+ 1) & ~1)) / 2;
511 if(left
& 1) /* upper nibble untouched */
512 do_rop_8(ptr
++, 0xf0, byte_xor
& 0x0f);
514 memset( ptr
, byte_xor
, byte_len
);
516 if(right
& 1) /* lower nibble untouched */
517 do_rop_8(ptr
+ byte_len
, 0x0f, byte_xor
& 0xf0);
523 static void solid_rects_1(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
527 BYTE byte_and
= (and & 1) ? 0xff : 0;
528 BYTE byte_xor
= (xor & 1) ? 0xff : 0;
529 static const BYTE masks
[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
531 for(i
= 0; i
< num
; i
++, rc
++)
533 int left
= dib
->rect
.left
+ rc
->left
;
534 int right
= dib
->rect
.left
+ rc
->right
;
536 assert( !is_rect_empty( rc
));
538 start
= get_pixel_ptr_1(dib
, rc
->left
, rc
->top
);
540 if ((left
& ~7) == (right
& ~7)) /* Special case for lines that start and end in the same byte */
542 BYTE mask
= masks
[left
& 7] & ~masks
[right
& 7];
544 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
546 do_rop_8(start
, byte_and
| ~mask
, byte_xor
& mask
);
551 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
556 do_rop_8(ptr
++, byte_and
| ~masks
[left
& 7], byte_xor
& masks
[left
& 7]);
558 for(x
= (left
+ 7) & ~7; x
< (right
& ~7); x
+= 8)
559 do_rop_8(ptr
++, byte_and
, byte_xor
);
562 /* this is inverted wrt start mask */
563 do_rop_8(ptr
, byte_and
| masks
[right
& 7], byte_xor
& ~masks
[right
& 7]);
568 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
570 unsigned int byte_len
= (right
- ((left
+ 7) & ~7)) / 8;
575 do_rop_8(ptr
++, ~masks
[left
& 7], byte_xor
& masks
[left
& 7]);
577 memset( ptr
, byte_xor
, byte_len
);
580 do_rop_8(ptr
+ byte_len
, masks
[right
& 7], byte_xor
& ~masks
[right
& 7]);
586 static void solid_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
591 static void solid_line_32(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
592 DWORD
and, DWORD
xor)
594 DWORD
*ptr
= get_pixel_ptr_32( dib
, start
->x
, start
->y
);
595 int len
= params
->length
, err
= params
->err_start
;
596 int major_inc
, minor_inc
;
600 major_inc
= params
->x_inc
;
601 minor_inc
= (dib
->stride
* params
->y_inc
) / 4;
605 major_inc
= (dib
->stride
* params
->y_inc
) / 4;
606 minor_inc
= params
->x_inc
;
611 do_rop_32( ptr
, and, xor );
612 if (err
+ params
->bias
> 0)
615 err
+= params
->err_add_1
;
617 else err
+= params
->err_add_2
;
622 static void solid_line_24(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
623 DWORD
and, DWORD
xor)
625 BYTE
*ptr
= get_pixel_ptr_24( dib
, start
->x
, start
->y
);
626 int len
= params
->length
, err
= params
->err_start
;
627 int major_inc
, minor_inc
;
631 major_inc
= params
->x_inc
* 3;
632 minor_inc
= dib
->stride
* params
->y_inc
;
636 major_inc
= dib
->stride
* params
->y_inc
;
637 minor_inc
= params
->x_inc
* 3;
642 do_rop_8( ptr
, and, xor );
643 do_rop_8( ptr
+ 1, and >> 8, xor >> 8 );
644 do_rop_8( ptr
+ 2, and >> 16, xor >> 16 );
645 if (err
+ params
->bias
> 0)
648 err
+= params
->err_add_1
;
650 else err
+= params
->err_add_2
;
655 static void solid_line_16(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
656 DWORD
and, DWORD
xor)
658 WORD
*ptr
= get_pixel_ptr_16( dib
, start
->x
, start
->y
);
659 int len
= params
->length
, err
= params
->err_start
;
660 int major_inc
, minor_inc
;
664 major_inc
= params
->x_inc
;
665 minor_inc
= (dib
->stride
* params
->y_inc
) / 2;
669 major_inc
= (dib
->stride
* params
->y_inc
) / 2;
670 minor_inc
= params
->x_inc
;
675 do_rop_16( ptr
, and, xor );
676 if (err
+ params
->bias
> 0)
679 err
+= params
->err_add_1
;
681 else err
+= params
->err_add_2
;
686 static void solid_line_8(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
687 DWORD
and, DWORD
xor)
689 BYTE
*ptr
= get_pixel_ptr_8( dib
, start
->x
, start
->y
);
690 int len
= params
->length
, err
= params
->err_start
;
691 int major_inc
, minor_inc
;
695 major_inc
= params
->x_inc
;
696 minor_inc
= dib
->stride
* params
->y_inc
;
700 major_inc
= dib
->stride
* params
->y_inc
;
701 minor_inc
= params
->x_inc
;
706 do_rop_8( ptr
, and, xor );
707 if (err
+ params
->bias
> 0)
710 err
+= params
->err_add_1
;
712 else err
+= params
->err_add_2
;
717 static void solid_line_4(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
718 DWORD
and, DWORD
xor)
720 BYTE
*ptr
= get_pixel_ptr_4( dib
, start
->x
, start
->y
);
721 int len
= params
->length
, err
= params
->err_start
;
722 int x
= dib
->rect
.left
+ start
->x
;
724 and = (and & 0x0f) | ((and << 4) & 0xf0);
725 xor = (xor & 0x0f) | ((xor << 4) & 0xf0);
731 do_rop_mask_8( ptr
, and, xor, pixel_masks_4
[ x
% 2 ] );
732 if (err
+ params
->bias
> 0)
734 ptr
+= dib
->stride
* params
->y_inc
;
735 err
+= params
->err_add_1
;
737 else err
+= params
->err_add_2
;
738 if ((x
/ 2) != ((x
+ params
->x_inc
) / 2))
739 ptr
+= params
->x_inc
;
747 do_rop_mask_8( ptr
, and, xor, pixel_masks_4
[ x
% 2 ] );
748 if (err
+ params
->bias
> 0)
750 if ((x
/ 2) != ((x
+ params
->x_inc
) / 2))
751 ptr
+= params
->x_inc
;
753 err
+= params
->err_add_1
;
755 else err
+= params
->err_add_2
;
756 ptr
+= dib
->stride
* params
->y_inc
;
761 static void solid_line_1(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
762 DWORD
and, DWORD
xor)
764 BYTE
*ptr
= get_pixel_ptr_1( dib
, start
->x
, start
->y
);
765 int len
= params
->length
, err
= params
->err_start
;
766 int x
= dib
->rect
.left
+ start
->x
;
768 and = (and & 0x1) ? 0xff : 0;
769 xor = (xor & 0x1) ? 0xff : 0;
775 do_rop_mask_8( ptr
, and, xor, pixel_masks_1
[ x
% 8 ] );
776 if (err
+ params
->bias
> 0)
778 ptr
+= dib
->stride
* params
->y_inc
;
779 err
+= params
->err_add_1
;
781 else err
+= params
->err_add_2
;
782 if ((x
/ 8) != ((x
+ params
->x_inc
) / 8))
783 ptr
+= params
->x_inc
;
791 do_rop_mask_8( ptr
, and, xor, pixel_masks_1
[ x
% 8 ] );
792 if (err
+ params
->bias
> 0)
794 if ((x
/ 8) != ((x
+ params
->x_inc
) / 8))
795 ptr
+= params
->x_inc
;
797 err
+= params
->err_add_1
;
799 else err
+= params
->err_add_2
;
800 ptr
+= dib
->stride
* params
->y_inc
;
805 static void solid_line_null(const dib_info
*dib
, const POINT
*start
, const struct line_params
*params
,
806 DWORD
and, DWORD
xor)
811 static inline INT
calc_offset(INT edge
, INT size
, INT origin
)
815 if(edge
- origin
>= 0)
816 offset
= (edge
- origin
) % size
;
819 offset
= (origin
- edge
) % size
;
820 if(offset
) offset
= size
- offset
;
825 static inline POINT
calc_brush_offset(const RECT
*rc
, const dib_info
*brush
, const POINT
*origin
)
829 offset
.x
= calc_offset(rc
->left
, brush
->width
, origin
->x
);
830 offset
.y
= calc_offset(rc
->top
, brush
->height
, origin
->y
);
835 static void pattern_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
836 const dib_info
*brush
, const rop_mask_bits
*bits
)
838 DWORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
839 int x
, y
, i
, len
, brush_x
;
842 for(i
= 0; i
< num
; i
++, rc
++)
844 offset
= calc_brush_offset(rc
, brush
, origin
);
845 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
846 start_xor
= (DWORD
*)bits
->xor + offset
.y
* brush
->stride
/ 4;
850 start_and
= (DWORD
*)bits
->and + offset
.y
* brush
->stride
/ 4;
852 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
854 and_ptr
= start_and
+ offset
.x
;
855 xor_ptr
= start_xor
+ offset
.x
;
857 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
859 do_rop_32(ptr
++, *and_ptr
++, *xor_ptr
++);
860 if(and_ptr
== start_and
+ brush
->width
)
868 if(offset
.y
== brush
->height
)
870 start_and
= bits
->and;
871 start_xor
= bits
->xor;
876 start_and
+= brush
->stride
/ 4;
877 start_xor
+= brush
->stride
/ 4;
883 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
885 for (x
= rc
->left
, brush_x
= offset
.x
; x
< rc
->right
; x
+= len
)
887 len
= min( rc
->right
- x
, brush
->width
- brush_x
);
888 memcpy( start
+ x
- rc
->left
, start_xor
+ brush_x
, len
* 4 );
892 start_xor
+= brush
->stride
/ 4;
894 if(offset
.y
== brush
->height
)
896 start_xor
= bits
->xor;
904 static void pattern_rects_24(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
905 const dib_info
*brush
, const rop_mask_bits
*bits
)
907 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
908 int x
, y
, i
, len
, brush_x
;
911 for(i
= 0; i
< num
; i
++, rc
++)
913 offset
= calc_brush_offset(rc
, brush
, origin
);
915 start
= get_pixel_ptr_24(dib
, rc
->left
, rc
->top
);
916 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
920 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
921 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
923 and_ptr
= start_and
+ offset
.x
* 3;
924 xor_ptr
= start_xor
+ offset
.x
* 3;
926 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
928 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
929 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
930 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
931 if(and_ptr
== start_and
+ brush
->width
* 3)
939 if(offset
.y
== brush
->height
)
941 start_and
= bits
->and;
942 start_xor
= bits
->xor;
947 start_and
+= brush
->stride
;
948 start_xor
+= brush
->stride
;
954 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
956 for (x
= rc
->left
, brush_x
= offset
.x
; x
< rc
->right
; x
+= len
)
958 len
= min( rc
->right
- x
, brush
->width
- brush_x
);
959 memcpy( start
+ (x
- rc
->left
) * 3, start_xor
+ brush_x
* 3, len
* 3 );
963 start_xor
+= brush
->stride
;
965 if(offset
.y
== brush
->height
)
967 start_xor
= bits
->xor;
975 static void pattern_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
976 const dib_info
*brush
, const rop_mask_bits
*bits
)
978 WORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
979 int x
, y
, i
, len
, brush_x
;
982 for(i
= 0; i
< num
; i
++, rc
++)
984 offset
= calc_brush_offset(rc
, brush
, origin
);
986 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
987 start_xor
= (WORD
*)bits
->xor + offset
.y
* brush
->stride
/ 2;
991 start_and
= (WORD
*)bits
->and + offset
.y
* brush
->stride
/ 2;
992 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
994 and_ptr
= start_and
+ offset
.x
;
995 xor_ptr
= start_xor
+ offset
.x
;
997 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
999 do_rop_16(ptr
++, *and_ptr
++, *xor_ptr
++);
1000 if(and_ptr
== start_and
+ brush
->width
)
1002 and_ptr
= start_and
;
1003 xor_ptr
= start_xor
;
1008 if(offset
.y
== brush
->height
)
1010 start_and
= bits
->and;
1011 start_xor
= bits
->xor;
1016 start_and
+= brush
->stride
/ 2;
1017 start_xor
+= brush
->stride
/ 2;
1023 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
1025 for (x
= rc
->left
, brush_x
= offset
.x
; x
< rc
->right
; x
+= len
)
1027 len
= min( rc
->right
- x
, brush
->width
- brush_x
);
1028 memcpy( start
+ x
- rc
->left
, start_xor
+ brush_x
, len
* 2 );
1032 start_xor
+= brush
->stride
/ 2;
1034 if(offset
.y
== brush
->height
)
1036 start_xor
= bits
->xor;
1044 static void pattern_rects_8(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1045 const dib_info
*brush
, const rop_mask_bits
*bits
)
1047 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
1048 int x
, y
, i
, len
, brush_x
;
1051 for(i
= 0; i
< num
; i
++, rc
++)
1053 offset
= calc_brush_offset(rc
, brush
, origin
);
1055 start
= get_pixel_ptr_8(dib
, rc
->left
, rc
->top
);
1056 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
1060 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
1061 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1063 and_ptr
= start_and
+ offset
.x
;
1064 xor_ptr
= start_xor
+ offset
.x
;
1066 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
1068 do_rop_8(ptr
++, *and_ptr
++, *xor_ptr
++);
1069 if(and_ptr
== start_and
+ brush
->width
)
1071 and_ptr
= start_and
;
1072 xor_ptr
= start_xor
;
1077 if(offset
.y
== brush
->height
)
1079 start_and
= bits
->and;
1080 start_xor
= bits
->xor;
1085 start_and
+= brush
->stride
;
1086 start_xor
+= brush
->stride
;
1092 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1094 for (x
= rc
->left
, brush_x
= offset
.x
; x
< rc
->right
; x
+= len
)
1096 len
= min( rc
->right
- x
, brush
->width
- brush_x
);
1097 memcpy( start
+ x
- rc
->left
, start_xor
+ brush_x
, len
);
1101 start_xor
+= brush
->stride
;
1103 if(offset
.y
== brush
->height
)
1105 start_xor
= bits
->xor;
1113 static void pattern_rects_4(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1114 const dib_info
*brush
, const rop_mask_bits
*bits
)
1116 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
1117 int x
, y
, i
, left
, right
;
1120 for(i
= 0; i
< num
; i
++, rc
++)
1122 offset
= calc_brush_offset(rc
, brush
, origin
);
1123 left
= dib
->rect
.left
+ rc
->left
;
1124 right
= dib
->rect
.left
+ rc
->right
;
1126 start
= get_pixel_ptr_4(dib
, rc
->left
, rc
->top
);
1127 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
1131 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
1132 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1134 INT brush_x
= offset
.x
;
1135 BYTE byte_and
, byte_xor
;
1137 and_ptr
= start_and
+ brush_x
/ 2;
1138 xor_ptr
= start_xor
+ brush_x
/ 2;
1140 for(x
= left
, ptr
= start
; x
< right
; x
++)
1142 /* FIXME: Two pixels at a time */
1143 if(x
& 1) /* lower dst nibble */
1145 if(brush_x
& 1) /* lower pat nibble */
1147 byte_and
= *and_ptr
++ | 0xf0;
1148 byte_xor
= *xor_ptr
++ & 0x0f;
1150 else /* upper pat nibble */
1152 byte_and
= (*and_ptr
>> 4) | 0xf0;
1153 byte_xor
= (*xor_ptr
>> 4) & 0x0f;
1156 else /* upper dst nibble */
1158 if(brush_x
& 1) /* lower pat nibble */
1160 byte_and
= (*and_ptr
++ << 4) | 0x0f;
1161 byte_xor
= (*xor_ptr
++ << 4) & 0xf0;
1163 else /* upper pat nibble */
1165 byte_and
= *and_ptr
| 0x0f;
1166 byte_xor
= *xor_ptr
& 0xf0;
1169 do_rop_8(ptr
, byte_and
, byte_xor
);
1173 if(++brush_x
== brush
->width
)
1176 and_ptr
= start_and
;
1177 xor_ptr
= start_xor
;
1182 if(offset
.y
== brush
->height
)
1184 start_and
= bits
->and;
1185 start_xor
= bits
->xor;
1190 start_and
+= brush
->stride
;
1191 start_xor
+= brush
->stride
;
1197 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1199 INT brush_x
= offset
.x
;
1202 xor_ptr
= start_xor
+ brush_x
/ 2;
1204 for(x
= left
, ptr
= start
; x
< right
; x
++)
1206 /* FIXME: Two pixels at a time */
1207 if(x
& 1) /* lower dst nibble */
1209 if(brush_x
& 1) /* lower pat nibble */
1210 byte_xor
= *xor_ptr
++ & 0x0f;
1211 else /* upper pat nibble */
1212 byte_xor
= (*xor_ptr
>> 4) & 0x0f;
1213 do_rop_8(ptr
, 0xf0, byte_xor
);
1215 else /* upper dst nibble */
1217 if(brush_x
& 1) /* lower pat nibble */
1218 byte_xor
= (*xor_ptr
++ << 4) & 0xf0;
1219 else /* upper pat nibble */
1220 byte_xor
= *xor_ptr
& 0xf0;
1221 do_rop_8(ptr
, 0x0f, byte_xor
);
1226 if(++brush_x
== brush
->width
)
1229 xor_ptr
= start_xor
;
1233 start_xor
+= brush
->stride
;
1235 if(offset
.y
== brush
->height
)
1237 start_xor
= bits
->xor;
1245 static void pattern_rects_1(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1246 const dib_info
*brush
, const rop_mask_bits
*bits
)
1248 BYTE
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
1249 int x
, y
, i
, left
, right
;
1252 for(i
= 0; i
< num
; i
++, rc
++)
1254 offset
= calc_brush_offset(rc
, brush
, origin
);
1255 left
= dib
->rect
.left
+ rc
->left
;
1256 right
= dib
->rect
.left
+ rc
->right
;
1258 start
= get_pixel_ptr_1(dib
, rc
->left
, rc
->top
);
1259 start_xor
= (BYTE
*)bits
->xor + offset
.y
* brush
->stride
;
1263 start_and
= (BYTE
*)bits
->and + offset
.y
* brush
->stride
;
1264 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1266 INT brush_x
= offset
.x
;
1267 BYTE byte_and
, byte_xor
;
1269 and_ptr
= start_and
+ brush_x
/ 8;
1270 xor_ptr
= start_xor
+ brush_x
/ 8;
1272 for(x
= left
, ptr
= start
; x
< right
; x
++)
1274 byte_and
= (*and_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
1275 byte_and
|= ~pixel_masks_1
[x
% 8];
1276 byte_xor
= (*xor_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
1277 byte_xor
&= pixel_masks_1
[x
% 8];
1279 do_rop_8(ptr
, byte_and
, byte_xor
);
1281 if((x
& 7) == 7) ptr
++;
1283 if((brush_x
& 7) == 7)
1289 if(++brush_x
== brush
->width
)
1292 and_ptr
= start_and
;
1293 xor_ptr
= start_xor
;
1298 if(offset
.y
== brush
->height
)
1300 start_and
= bits
->and;
1301 start_xor
= bits
->xor;
1306 start_and
+= brush
->stride
;
1307 start_xor
+= brush
->stride
;
1313 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
)
1315 INT brush_x
= offset
.x
;
1317 xor_ptr
= start_xor
+ brush_x
/ 8;
1319 for(x
= left
, ptr
= start
; x
< right
; x
++)
1321 BYTE byte_xor
= (*xor_ptr
& pixel_masks_1
[brush_x
% 8]) ? 0xff : 0;
1322 byte_xor
&= pixel_masks_1
[x
% 8];
1324 do_rop_8(ptr
, ~pixel_masks_1
[x
% 8], byte_xor
);
1326 if((x
& 7) == 7) ptr
++;
1327 if((brush_x
& 7) == 7) xor_ptr
++;
1329 if(++brush_x
== brush
->width
)
1332 xor_ptr
= start_xor
;
1336 start_xor
+= brush
->stride
;
1338 if(offset
.y
== brush
->height
)
1340 start_xor
= bits
->xor;
1348 static void pattern_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
1349 const dib_info
*brush
, const rop_mask_bits
*bits
)
1354 static void copy_rect_32(const dib_info
*dst
, const RECT
*rc
,
1355 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1357 DWORD
*dst_start
, *src_start
;
1358 struct rop_codes codes
;
1359 int y
, dst_stride
, src_stride
;
1361 if (overlap
& OVERLAP_BELOW
)
1363 dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->bottom
- 1);
1364 src_start
= get_pixel_ptr_32(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1365 dst_stride
= -dst
->stride
/ 4;
1366 src_stride
= -src
->stride
/ 4;
1370 dst_start
= get_pixel_ptr_32(dst
, rc
->left
, rc
->top
);
1371 src_start
= get_pixel_ptr_32(src
, origin
->x
, origin
->y
);
1372 dst_stride
= dst
->stride
/ 4;
1373 src_stride
= src
->stride
/ 4;
1376 if (rop2
== R2_COPYPEN
)
1378 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1379 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 4 );
1383 get_rop_codes( rop2
, &codes
);
1384 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1386 if (overlap
& OVERLAP_RIGHT
)
1387 do_rop_codes_line_rev_32( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1389 do_rop_codes_line_32( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1393 static void copy_rect_24(const dib_info
*dst
, const RECT
*rc
,
1394 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1396 BYTE
*dst_start
, *src_start
;
1397 int y
, dst_stride
, src_stride
;
1398 struct rop_codes codes
;
1400 if (overlap
& OVERLAP_BELOW
)
1402 dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->bottom
- 1);
1403 src_start
= get_pixel_ptr_24(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1404 dst_stride
= -dst
->stride
;
1405 src_stride
= -src
->stride
;
1409 dst_start
= get_pixel_ptr_24(dst
, rc
->left
, rc
->top
);
1410 src_start
= get_pixel_ptr_24(src
, origin
->x
, origin
->y
);
1411 dst_stride
= dst
->stride
;
1412 src_stride
= src
->stride
;
1415 if (rop2
== R2_COPYPEN
)
1417 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1418 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 3 );
1422 get_rop_codes( rop2
, &codes
);
1423 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1425 if (overlap
& OVERLAP_RIGHT
)
1426 do_rop_codes_line_rev_8( dst_start
, src_start
, &codes
, (rc
->right
- rc
->left
) * 3 );
1428 do_rop_codes_line_8( dst_start
, src_start
, &codes
, (rc
->right
- rc
->left
) * 3 );
1432 static void copy_rect_16(const dib_info
*dst
, const RECT
*rc
,
1433 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1435 WORD
*dst_start
, *src_start
;
1436 int y
, dst_stride
, src_stride
;
1437 struct rop_codes codes
;
1439 if (overlap
& OVERLAP_BELOW
)
1441 dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->bottom
- 1);
1442 src_start
= get_pixel_ptr_16(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1443 dst_stride
= -dst
->stride
/ 2;
1444 src_stride
= -src
->stride
/ 2;
1448 dst_start
= get_pixel_ptr_16(dst
, rc
->left
, rc
->top
);
1449 src_start
= get_pixel_ptr_16(src
, origin
->x
, origin
->y
);
1450 dst_stride
= dst
->stride
/ 2;
1451 src_stride
= src
->stride
/ 2;
1454 if (rop2
== R2_COPYPEN
)
1456 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1457 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) * 2 );
1461 get_rop_codes( rop2
, &codes
);
1462 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1464 if (overlap
& OVERLAP_RIGHT
)
1465 do_rop_codes_line_rev_16( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1467 do_rop_codes_line_16( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1471 static void copy_rect_8(const dib_info
*dst
, const RECT
*rc
,
1472 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1474 BYTE
*dst_start
, *src_start
;
1475 int y
, dst_stride
, src_stride
;
1476 struct rop_codes codes
;
1478 if (overlap
& OVERLAP_BELOW
)
1480 dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->bottom
- 1);
1481 src_start
= get_pixel_ptr_8(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1482 dst_stride
= -dst
->stride
;
1483 src_stride
= -src
->stride
;
1487 dst_start
= get_pixel_ptr_8(dst
, rc
->left
, rc
->top
);
1488 src_start
= get_pixel_ptr_8(src
, origin
->x
, origin
->y
);
1489 dst_stride
= dst
->stride
;
1490 src_stride
= src
->stride
;
1493 if (rop2
== R2_COPYPEN
)
1495 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1496 memmove( dst_start
, src_start
, (rc
->right
- rc
->left
) );
1500 get_rop_codes( rop2
, &codes
);
1501 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1503 if (overlap
& OVERLAP_RIGHT
)
1504 do_rop_codes_line_rev_8( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1506 do_rop_codes_line_8( dst_start
, src_start
, &codes
, rc
->right
- rc
->left
);
1510 static void copy_rect_4(const dib_info
*dst
, const RECT
*rc
,
1511 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1513 BYTE
*dst_start
, *src_start
;
1514 int y
, dst_stride
, src_stride
;
1515 struct rop_codes codes
;
1516 int left
= dst
->rect
.left
+ rc
->left
;
1517 int right
= dst
->rect
.left
+ rc
->right
;
1518 int org_x
= src
->rect
.left
+ origin
->x
;
1520 if (overlap
& OVERLAP_BELOW
)
1522 dst_start
= get_pixel_ptr_4(dst
, rc
->left
, rc
->bottom
- 1);
1523 src_start
= get_pixel_ptr_4(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1524 dst_stride
= -dst
->stride
;
1525 src_stride
= -src
->stride
;
1529 dst_start
= get_pixel_ptr_4(dst
, rc
->left
, rc
->top
);
1530 src_start
= get_pixel_ptr_4(src
, origin
->x
, origin
->y
);
1531 dst_stride
= dst
->stride
;
1532 src_stride
= src
->stride
;
1535 if (rop2
== R2_COPYPEN
&& (left
& 1) == 0 && (org_x
& 1) == 0 && (right
& 1) == 0)
1537 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1538 memmove( dst_start
, src_start
, (right
- left
) / 2 );
1542 get_rop_codes( rop2
, &codes
);
1543 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1545 if (overlap
& OVERLAP_RIGHT
)
1546 do_rop_codes_line_rev_4( dst_start
, left
& 1, src_start
, org_x
& 1, &codes
, right
- left
);
1548 do_rop_codes_line_4( dst_start
, left
& 1, src_start
, org_x
& 1, &codes
, right
- left
);
1552 static void copy_rect_1(const dib_info
*dst
, const RECT
*rc
,
1553 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1555 BYTE
*dst_start
, *src_start
;
1556 int y
, dst_stride
, src_stride
;
1557 struct rop_codes codes
;
1558 int left
= dst
->rect
.left
+ rc
->left
;
1559 int right
= dst
->rect
.left
+ rc
->right
;
1560 int org_x
= src
->rect
.left
+ origin
->x
;
1562 if (overlap
& OVERLAP_BELOW
)
1564 dst_start
= get_pixel_ptr_1(dst
, rc
->left
, rc
->bottom
- 1);
1565 src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
+ rc
->bottom
- rc
->top
- 1);
1566 dst_stride
= -dst
->stride
;
1567 src_stride
= -src
->stride
;
1571 dst_start
= get_pixel_ptr_1(dst
, rc
->left
, rc
->top
);
1572 src_start
= get_pixel_ptr_1(src
, origin
->x
, origin
->y
);
1573 dst_stride
= dst
->stride
;
1574 src_stride
= src
->stride
;
1577 if (rop2
== R2_COPYPEN
&& (left
& 7) == 0 && (org_x
& 7) == 0 && (right
& 7) == 0)
1579 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1580 memmove( dst_start
, src_start
, (right
- left
) / 8 );
1584 get_rop_codes( rop2
, &codes
);
1585 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_start
+= dst_stride
, src_start
+= src_stride
)
1587 if (overlap
& OVERLAP_RIGHT
)
1588 do_rop_codes_line_rev_1( dst_start
, left
& 7, src_start
, org_x
& 7, &codes
, right
- left
);
1590 do_rop_codes_line_1( dst_start
, left
& 7, src_start
, org_x
& 7, &codes
, right
- left
);
1594 static void copy_rect_null(const dib_info
*dst
, const RECT
*rc
,
1595 const dib_info
*src
, const POINT
*origin
, int rop2
, int overlap
)
1600 static DWORD
get_pixel_32(const dib_info
*dib
, int x
, int y
)
1602 DWORD
*ptr
= get_pixel_ptr_32( dib
, x
, y
);
1606 static DWORD
get_pixel_24(const dib_info
*dib
, int x
, int y
)
1608 BYTE
*ptr
= get_pixel_ptr_24( dib
, x
, y
);
1609 return ptr
[0] | ((DWORD
)ptr
[1] << 8) | ((DWORD
)ptr
[2] << 16);
1612 static DWORD
get_pixel_16(const dib_info
*dib
, int x
, int y
)
1614 WORD
*ptr
= get_pixel_ptr_16( dib
, x
, y
);
1618 static DWORD
get_pixel_8(const dib_info
*dib
, int x
, int y
)
1620 BYTE
*ptr
= get_pixel_ptr_8( dib
, x
, y
);
1624 static DWORD
get_pixel_4(const dib_info
*dib
, int x
, int y
)
1626 BYTE
*ptr
= get_pixel_ptr_4( dib
, x
, y
);
1628 if ((dib
->rect
.left
+ x
) & 1)
1631 return (*ptr
>> 4) & 0x0f;
1634 static DWORD
get_pixel_1(const dib_info
*dib
, int x
, int y
)
1636 BYTE
*ptr
= get_pixel_ptr_1( dib
, x
, y
);
1637 return (*ptr
& pixel_masks_1
[(dib
->rect
.left
+ x
) & 7]) ? 1 : 0;
1640 static DWORD
get_pixel_null(const dib_info
*dib
, int x
, int y
)
1645 static DWORD
colorref_to_pixel_888(const dib_info
*dib
, COLORREF color
)
1647 return ( ((color
>> 16) & 0xff) | (color
& 0xff00) | ((color
<< 16) & 0xff0000) );
1650 static const DWORD field_masks
[33] =
1652 0x00, /* should never happen */
1653 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff,
1654 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1655 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1656 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1659 static inline DWORD
get_field(DWORD field
, int shift
, int len
)
1661 shift
= shift
- (8 - len
);
1666 field
&= field_masks
[len
];
1667 field
|= field
>> len
;
1671 static inline DWORD
put_field(DWORD field
, int shift
, int len
)
1673 shift
= shift
- (8 - len
);
1674 field
&= field_masks
[len
];
1682 static DWORD
colorref_to_pixel_masks(const dib_info
*dib
, COLORREF colour
)
1686 r
= GetRValue(colour
);
1687 g
= GetGValue(colour
);
1688 b
= GetBValue(colour
);
1690 return put_field(r
, dib
->red_shift
, dib
->red_len
) |
1691 put_field(g
, dib
->green_shift
, dib
->green_len
) |
1692 put_field(b
, dib
->blue_shift
, dib
->blue_len
);
1695 static DWORD
colorref_to_pixel_555(const dib_info
*dib
, COLORREF color
)
1697 return ( ((color
>> 19) & 0x1f) | ((color
>> 6) & 0x03e0) | ((color
<< 7) & 0x7c00) );
1700 static DWORD
rgb_to_pixel_colortable(const dib_info
*dib
, BYTE r
, BYTE g
, BYTE b
)
1702 const RGBQUAD
*color_table
= get_dib_color_table( dib
);
1703 int size
= dib
->color_table
? dib
->color_table_size
: 1 << dib
->bit_count
;
1704 int i
, best_index
= 0;
1705 DWORD diff
, best_diff
= 0xffffffff;
1707 /* special case for conversion to 1-bpp without a color table:
1708 * we get a 1-entry table containing the background color
1710 if (dib
->bit_count
== 1 && size
== 1)
1711 return (r
== color_table
[0].rgbRed
&&
1712 g
== color_table
[0].rgbGreen
&&
1713 b
== color_table
[0].rgbBlue
);
1715 for(i
= 0; i
< size
; i
++)
1717 const RGBQUAD
*cur
= color_table
+ i
;
1718 diff
= (r
- cur
->rgbRed
) * (r
- cur
->rgbRed
)
1719 + (g
- cur
->rgbGreen
) * (g
- cur
->rgbGreen
)
1720 + (b
- cur
->rgbBlue
) * (b
- cur
->rgbBlue
);
1728 if(diff
< best_diff
)
1737 static DWORD
rgb_to_pixel_mono(const dib_info
*dib
, BOOL dither
, int x
, int y
, BYTE r
, BYTE g
, BYTE b
)
1742 ret
= rgb_to_pixel_colortable( dib
, r
, g
, b
);
1744 ret
= ((30 * r
+ 59 * g
+ 11 * b
) / 100 + bayer_16x16
[y
% 16][x
% 16]) > 255;
1746 return ret
? 0xff : 0;
1749 static DWORD
colorref_to_pixel_colortable(const dib_info
*dib
, COLORREF color
)
1751 return rgb_to_pixel_colortable( dib
, GetRValue(color
), GetGValue(color
), GetBValue(color
) );
1754 static DWORD
colorref_to_pixel_null(const dib_info
*dib
, COLORREF color
)
1759 static COLORREF
pixel_to_colorref_888(const dib_info
*dib
, DWORD pixel
)
1761 return ( ((pixel
>> 16) & 0xff) | (pixel
& 0xff00) | ((pixel
<< 16) & 0xff0000) );
1764 static COLORREF
pixel_to_colorref_masks(const dib_info
*dib
, DWORD pixel
)
1766 return RGB( get_field( pixel
, dib
->red_shift
, dib
->red_len
),
1767 get_field( pixel
, dib
->green_shift
, dib
->green_len
),
1768 get_field( pixel
, dib
->blue_shift
, dib
->blue_len
) );
1771 static COLORREF
pixel_to_colorref_555(const dib_info
*dib
, DWORD pixel
)
1773 return RGB( ((pixel
>> 7) & 0xf8) | ((pixel
>> 12) & 0x07),
1774 ((pixel
>> 2) & 0xf8) | ((pixel
>> 7) & 0x07),
1775 ((pixel
<< 3) & 0xf8) | ((pixel
>> 2) & 0x07) );
1778 static COLORREF
pixel_to_colorref_colortable(const dib_info
*dib
, DWORD pixel
)
1780 const RGBQUAD
*color_table
= get_dib_color_table( dib
);
1782 if (!dib
->color_table
|| pixel
< dib
->color_table_size
)
1784 RGBQUAD quad
= color_table
[pixel
];
1785 return RGB( quad
.rgbRed
, quad
.rgbGreen
, quad
.rgbBlue
);
1790 static COLORREF
pixel_to_colorref_null(const dib_info
*dib
, DWORD pixel
)
1795 static inline BOOL
bit_fields_match(const dib_info
*d1
, const dib_info
*d2
)
1797 assert( d1
->bit_count
> 8 && d1
->bit_count
== d2
->bit_count
);
1799 return d1
->red_mask
== d2
->red_mask
&&
1800 d1
->green_mask
== d2
->green_mask
&&
1801 d1
->blue_mask
== d2
->blue_mask
;
1804 static void convert_to_8888(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
1806 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
1807 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
1809 switch(src
->bit_count
)
1813 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1814 if(src
->funcs
== &funcs_8888
)
1816 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
1817 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
1820 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1822 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
1823 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
1824 dst_start
+= dst
->stride
/ 4;
1825 src_start
+= src
->stride
/ 4;
1829 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
1831 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1833 dst_pixel
= dst_start
;
1834 src_pixel
= src_start
;
1835 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1837 src_val
= *src_pixel
++;
1838 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << 16) |
1839 (((src_val
>> src
->green_shift
) & 0xff) << 8) |
1840 ((src_val
>> src
->blue_shift
) & 0xff);
1842 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1843 dst_start
+= dst
->stride
/ 4;
1844 src_start
+= src
->stride
/ 4;
1849 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1851 dst_pixel
= dst_start
;
1852 src_pixel
= src_start
;
1853 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1855 src_val
= *src_pixel
++;
1856 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
1857 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
1858 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
1860 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1861 dst_start
+= dst
->stride
/ 4;
1862 src_start
+= src
->stride
/ 4;
1870 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1872 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1874 dst_pixel
= dst_start
;
1875 src_pixel
= src_start
;
1876 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1879 rgb
.rgbBlue
= *src_pixel
++;
1880 rgb
.rgbGreen
= *src_pixel
++;
1881 rgb
.rgbRed
= *src_pixel
++;
1883 *dst_pixel
++ = ((rgb
.rgbRed
<< 16) & 0xff0000) | ((rgb
.rgbGreen
<< 8) & 0x00ff00) | (rgb
.rgbBlue
& 0x0000ff);
1885 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1886 dst_start
+= dst
->stride
/ 4;
1887 src_start
+= src
->stride
;
1894 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1895 if(src
->funcs
== &funcs_555
)
1897 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1899 dst_pixel
= dst_start
;
1900 src_pixel
= src_start
;
1901 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1903 src_val
= *src_pixel
++;
1904 *dst_pixel
++ = ((src_val
<< 9) & 0xf80000) | ((src_val
<< 4) & 0x070000) |
1905 ((src_val
<< 6) & 0x00f800) | ((src_val
<< 1) & 0x000700) |
1906 ((src_val
<< 3) & 0x0000f8) | ((src_val
>> 2) & 0x000007);
1908 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1909 dst_start
+= dst
->stride
/ 4;
1910 src_start
+= src
->stride
/ 2;
1913 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
1915 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1917 dst_pixel
= dst_start
;
1918 src_pixel
= src_start
;
1919 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1921 src_val
= *src_pixel
++;
1922 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
1923 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
1924 (((src_val
>> src
->green_shift
) << 11) & 0x00f800) |
1925 (((src_val
>> src
->green_shift
) << 6) & 0x000700) |
1926 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
1927 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
1929 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1930 dst_start
+= dst
->stride
/ 4;
1931 src_start
+= src
->stride
/ 2;
1934 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
1936 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1938 dst_pixel
= dst_start
;
1939 src_pixel
= src_start
;
1940 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1942 src_val
= *src_pixel
++;
1943 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 19) & 0xf80000) |
1944 (((src_val
>> src
->red_shift
) << 14) & 0x070000) |
1945 (((src_val
>> src
->green_shift
) << 10) & 0x00fc00) |
1946 (((src_val
>> src
->green_shift
) << 4) & 0x000300) |
1947 (((src_val
>> src
->blue_shift
) << 3) & 0x0000f8) |
1948 (((src_val
>> src
->blue_shift
) >> 2) & 0x000007);
1950 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1951 dst_start
+= dst
->stride
/ 4;
1952 src_start
+= src
->stride
/ 2;
1957 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1959 dst_pixel
= dst_start
;
1960 src_pixel
= src_start
;
1961 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1963 src_val
= *src_pixel
++;
1964 *dst_pixel
++ = (get_field( src_val
, src
->red_shift
, src
->red_len
) << 16 |
1965 get_field( src_val
, src
->green_shift
, src
->green_len
) << 8 |
1966 get_field( src_val
, src
->blue_shift
, src
->blue_len
));
1968 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1969 dst_start
+= dst
->stride
/ 4;
1970 src_start
+= src
->stride
/ 2;
1978 const RGBQUAD
*color_table
= get_dib_color_table( src
);
1979 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
1980 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
1982 dst_pixel
= dst_start
;
1983 src_pixel
= src_start
;
1984 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
1986 RGBQUAD rgb
= color_table
[*src_pixel
++];
1987 *dst_pixel
++ = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
1989 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
1990 dst_start
+= dst
->stride
/ 4;
1991 src_start
+= src
->stride
;
1998 const RGBQUAD
*color_table
= get_dib_color_table( src
);
1999 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2000 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2002 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2003 src_pixel
= src_start
;
2004 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2008 rgb
= color_table
[*src_pixel
++ & 0xf];
2010 rgb
= color_table
[*src_pixel
>> 4];
2011 dst_start
[x
] = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
2013 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2014 dst_start
+= dst
->stride
/ 4;
2015 src_start
+= src
->stride
;
2022 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2023 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2024 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2026 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2027 for(x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2030 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2031 rgb
= color_table
[src_val
];
2032 dst_start
[x
] = rgb
.rgbRed
<< 16 | rgb
.rgbGreen
<< 8 | rgb
.rgbBlue
;
2034 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2035 dst_start
+= dst
->stride
/ 4;
2036 src_start
+= src
->stride
;
2043 static void convert_to_32(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2045 DWORD
*dst_start
= get_pixel_ptr_32(dst
, 0, 0), *dst_pixel
, src_val
;
2046 int x
, y
, pad_size
= (dst
->width
- (src_rect
->right
- src_rect
->left
)) * 4;
2048 switch(src
->bit_count
)
2052 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2054 if(src
->funcs
== &funcs_8888
)
2056 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2058 dst_pixel
= dst_start
;
2059 src_pixel
= src_start
;
2060 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2062 src_val
= *src_pixel
++;
2063 *dst_pixel
++ = put_field(src_val
>> 16, dst
->red_shift
, dst
->red_len
) |
2064 put_field(src_val
>> 8, dst
->green_shift
, dst
->green_len
) |
2065 put_field(src_val
, dst
->blue_shift
, dst
->blue_len
);
2067 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2068 dst_start
+= dst
->stride
/ 4;
2069 src_start
+= src
->stride
/ 4;
2072 else if(bit_fields_match(src
, dst
))
2074 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2075 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2078 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2080 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 4);
2081 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2082 dst_start
+= dst
->stride
/ 4;
2083 src_start
+= src
->stride
/ 4;
2087 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8 &&
2088 dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
2090 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2092 dst_pixel
= dst_start
;
2093 src_pixel
= src_start
;
2094 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2096 src_val
= *src_pixel
++;
2097 *dst_pixel
++ = (((src_val
>> src
->red_shift
) & 0xff) << dst
->red_shift
) |
2098 (((src_val
>> src
->green_shift
) & 0xff) << dst
->green_shift
) |
2099 (((src_val
>> src
->blue_shift
) & 0xff) << dst
->blue_shift
);
2101 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2102 dst_start
+= dst
->stride
/ 4;
2103 src_start
+= src
->stride
/ 4;
2108 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2110 dst_pixel
= dst_start
;
2111 src_pixel
= src_start
;
2112 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2114 src_val
= *src_pixel
++;
2115 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
2116 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
2117 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
2119 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2120 dst_start
+= dst
->stride
/ 4;
2121 src_start
+= src
->stride
/ 4;
2129 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2131 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2133 dst_pixel
= dst_start
;
2134 src_pixel
= src_start
;
2135 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2138 rgb
.rgbBlue
= *src_pixel
++;
2139 rgb
.rgbGreen
= *src_pixel
++;
2140 rgb
.rgbRed
= *src_pixel
++;
2142 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2143 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2144 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2146 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2147 dst_start
+= dst
->stride
/ 4;
2148 src_start
+= src
->stride
;
2155 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2156 if(src
->funcs
== &funcs_555
)
2158 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2160 dst_pixel
= dst_start
;
2161 src_pixel
= src_start
;
2162 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2164 src_val
= *src_pixel
++;
2165 *dst_pixel
++ = put_field(((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07), dst
->red_shift
, dst
->red_len
) |
2166 put_field(((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07), dst
->green_shift
, dst
->green_len
) |
2167 put_field(((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2169 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2170 dst_start
+= dst
->stride
/ 4;
2171 src_start
+= src
->stride
/ 2;
2174 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2176 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2178 dst_pixel
= dst_start
;
2179 src_pixel
= src_start
;
2180 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2182 src_val
= *src_pixel
++;
2183 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2184 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
2185 put_field( (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2186 (((src_val
>> src
->green_shift
) >> 2) & 0x07), dst
->green_shift
, dst
->green_len
) |
2187 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2188 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2190 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2191 dst_start
+= dst
->stride
/ 4;
2192 src_start
+= src
->stride
/ 2;
2195 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2197 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2199 dst_pixel
= dst_start
;
2200 src_pixel
= src_start
;
2201 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2203 src_val
= *src_pixel
++;
2204 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2205 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
2206 put_field( (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2207 (((src_val
>> src
->green_shift
) >> 4) & 0x03), dst
->green_shift
, dst
->green_len
) |
2208 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2209 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2211 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2212 dst_start
+= dst
->stride
/ 4;
2213 src_start
+= src
->stride
/ 2;
2218 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2220 dst_pixel
= dst_start
;
2221 src_pixel
= src_start
;
2222 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2224 src_val
= *src_pixel
++;
2225 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
2226 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
2227 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
2229 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2230 dst_start
+= dst
->stride
/ 4;
2231 src_start
+= src
->stride
/ 2;
2239 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2240 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2241 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2243 dst_pixel
= dst_start
;
2244 src_pixel
= src_start
;
2245 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2247 RGBQUAD rgb
= color_table
[*src_pixel
++];
2248 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2249 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2250 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2252 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2253 dst_start
+= dst
->stride
/ 4;
2254 src_start
+= src
->stride
;
2261 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2262 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2263 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2265 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2266 src_pixel
= src_start
;
2267 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2271 rgb
= color_table
[*src_pixel
++ & 0xf];
2273 rgb
= color_table
[*src_pixel
>> 4];
2274 dst_start
[x
] = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2275 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2276 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2278 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2279 dst_start
+= dst
->stride
/ 4;
2280 src_start
+= src
->stride
;
2287 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2288 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2289 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2291 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2292 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2295 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2296 rgb
= color_table
[src_val
];
2297 dst_start
[x
] = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2298 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2299 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2301 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2302 dst_start
+= dst
->stride
/ 4;
2303 src_start
+= src
->stride
;
2310 static void convert_to_24(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2312 BYTE
*dst_start
= get_pixel_ptr_24(dst
, 0, 0), *dst_pixel
;
2314 int x
, y
, pad_size
= ((dst
->width
* 3 + 3) & ~3) - (src_rect
->right
- src_rect
->left
) * 3;
2316 switch(src
->bit_count
)
2320 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2321 if(src
->funcs
== &funcs_8888
)
2323 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2325 dst_pixel
= dst_start
;
2326 src_pixel
= src_start
;
2327 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2329 src_val
= *src_pixel
++;
2330 *dst_pixel
++ = src_val
& 0xff;
2331 *dst_pixel
++ = (src_val
>> 8) & 0xff;
2332 *dst_pixel
++ = (src_val
>> 16) & 0xff;
2334 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2335 dst_start
+= dst
->stride
;
2336 src_start
+= src
->stride
/ 4;
2339 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2341 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2343 dst_pixel
= dst_start
;
2344 src_pixel
= src_start
;
2345 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2347 src_val
= *src_pixel
++;
2348 *dst_pixel
++ = (src_val
>> src
->blue_shift
) & 0xff;
2349 *dst_pixel
++ = (src_val
>> src
->green_shift
) & 0xff;
2350 *dst_pixel
++ = (src_val
>> src
->red_shift
) & 0xff;
2352 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2353 dst_start
+= dst
->stride
;
2354 src_start
+= src
->stride
/ 4;
2359 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2361 dst_pixel
= dst_start
;
2362 src_pixel
= src_start
;
2363 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2365 src_val
= *src_pixel
++;
2366 *dst_pixel
++ = get_field( src_val
, src
->blue_shift
, src
->blue_len
);
2367 *dst_pixel
++ = get_field( src_val
, src
->green_shift
, src
->green_len
);
2368 *dst_pixel
++ = get_field( src_val
, src
->red_shift
, src
->red_len
);
2370 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2371 dst_start
+= dst
->stride
;
2372 src_start
+= src
->stride
/ 4;
2380 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
);
2382 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2383 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2386 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2388 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 3);
2389 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
) * 3, 0, pad_size
);
2390 dst_start
+= dst
->stride
;
2391 src_start
+= src
->stride
;
2399 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2400 if(src
->funcs
== &funcs_555
)
2402 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2404 dst_pixel
= dst_start
;
2405 src_pixel
= src_start
;
2406 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2408 src_val
= *src_pixel
++;
2409 *dst_pixel
++ = ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07);
2410 *dst_pixel
++ = ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07);
2411 *dst_pixel
++ = ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07);
2413 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2414 dst_start
+= dst
->stride
;
2415 src_start
+= src
->stride
/ 2;
2418 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2420 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2422 dst_pixel
= dst_start
;
2423 src_pixel
= src_start
;
2424 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2426 src_val
= *src_pixel
++;
2427 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2428 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
2429 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2430 (((src_val
>> src
->green_shift
) >> 2) & 0x07);
2431 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2432 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
2434 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2435 dst_start
+= dst
->stride
;
2436 src_start
+= src
->stride
/ 2;
2439 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2441 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2443 dst_pixel
= dst_start
;
2444 src_pixel
= src_start
;
2445 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2447 src_val
= *src_pixel
++;
2448 *dst_pixel
++ = (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2449 (((src_val
>> src
->blue_shift
) >> 2) & 0x07);
2450 *dst_pixel
++ = (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2451 (((src_val
>> src
->green_shift
) >> 4) & 0x03);
2452 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2453 (((src_val
>> src
->red_shift
) >> 2) & 0x07);
2455 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2456 dst_start
+= dst
->stride
;
2457 src_start
+= src
->stride
/ 2;
2462 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2464 dst_pixel
= dst_start
;
2465 src_pixel
= src_start
;
2466 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2468 src_val
= *src_pixel
++;
2469 *dst_pixel
++ = get_field(src_val
, src
->blue_shift
, src
->blue_len
);
2470 *dst_pixel
++ = get_field(src_val
, src
->green_shift
, src
->green_len
);
2471 *dst_pixel
++ = get_field(src_val
, src
->red_shift
, src
->red_len
);
2473 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2474 dst_start
+= dst
->stride
;
2475 src_start
+= src
->stride
/ 2;
2483 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2484 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2485 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2487 dst_pixel
= dst_start
;
2488 src_pixel
= src_start
;
2489 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2491 RGBQUAD rgb
= color_table
[*src_pixel
++];
2492 *dst_pixel
++ = rgb
.rgbBlue
;
2493 *dst_pixel
++ = rgb
.rgbGreen
;
2494 *dst_pixel
++ = rgb
.rgbRed
;
2496 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2497 dst_start
+= dst
->stride
;
2498 src_start
+= src
->stride
;
2505 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2506 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2507 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2509 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2510 src_pixel
= src_start
;
2511 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2515 rgb
= color_table
[*src_pixel
++ & 0xf];
2517 rgb
= color_table
[*src_pixel
>> 4];
2518 dst_start
[x
* 3] = rgb
.rgbBlue
;
2519 dst_start
[x
* 3 + 1] = rgb
.rgbGreen
;
2520 dst_start
[x
* 3 + 2] = rgb
.rgbRed
;
2522 if(pad_size
) memset(dst_start
+ x
* 3, 0, pad_size
);
2523 dst_start
+= dst
->stride
;
2524 src_start
+= src
->stride
;
2531 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2532 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2533 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2535 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2536 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2539 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2540 rgb
= color_table
[src_val
];
2541 dst_start
[x
* 3] = rgb
.rgbBlue
;
2542 dst_start
[x
* 3 + 1] = rgb
.rgbGreen
;
2543 dst_start
[x
* 3 + 2] = rgb
.rgbRed
;
2545 if(pad_size
) memset(dst_start
+ x
* 3, 0, pad_size
);
2546 dst_start
+= dst
->stride
;
2547 src_start
+= src
->stride
;
2554 static void convert_to_555(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2556 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
2557 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
2560 switch(src
->bit_count
)
2564 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2566 if(src
->funcs
== &funcs_8888
)
2568 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2570 dst_pixel
= dst_start
;
2571 src_pixel
= src_start
;
2572 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2574 src_val
= *src_pixel
++;
2575 *dst_pixel
++ = ((src_val
>> 9) & 0x7c00) |
2576 ((src_val
>> 6) & 0x03e0) |
2577 ((src_val
>> 3) & 0x001f);
2579 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2580 dst_start
+= dst
->stride
/ 2;
2581 src_start
+= src
->stride
/ 4;
2584 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
2586 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2588 dst_pixel
= dst_start
;
2589 src_pixel
= src_start
;
2590 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2592 src_val
= *src_pixel
++;
2593 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 7) & 0x7c00) |
2594 (((src_val
>> src
->green_shift
) << 2) & 0x03e0) |
2595 (((src_val
>> src
->blue_shift
) >> 3) & 0x001f);
2597 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2598 dst_start
+= dst
->stride
/ 2;
2599 src_start
+= src
->stride
/ 4;
2604 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2606 dst_pixel
= dst_start
;
2607 src_pixel
= src_start
;
2608 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2610 src_val
= *src_pixel
++;
2611 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
2612 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
2613 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
2615 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2616 dst_start
+= dst
->stride
/ 2;
2617 src_start
+= src
->stride
/ 4;
2625 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2627 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2629 dst_pixel
= dst_start
;
2630 src_pixel
= src_start
;
2631 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2634 rgb
.rgbBlue
= *src_pixel
++;
2635 rgb
.rgbGreen
= *src_pixel
++;
2636 rgb
.rgbRed
= *src_pixel
++;
2638 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2639 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2640 ((rgb
.rgbBlue
>> 3) & 0x001f);
2642 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2643 dst_start
+= dst
->stride
/ 2;
2644 src_start
+= src
->stride
;
2651 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2652 if(src
->funcs
== &funcs_555
)
2654 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2655 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2658 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2660 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
2661 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2662 dst_start
+= dst
->stride
/ 2;
2663 src_start
+= src
->stride
/ 2;
2667 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2669 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2671 dst_pixel
= dst_start
;
2672 src_pixel
= src_start
;
2673 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2675 src_val
= *src_pixel
++;
2676 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
2677 (((src_val
>> src
->green_shift
) << 5) & 0x03e0) |
2678 ( (src_val
>> src
->blue_shift
) & 0x001f);
2680 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2681 dst_start
+= dst
->stride
/ 2;
2682 src_start
+= src
->stride
/ 2;
2685 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2687 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2689 dst_pixel
= dst_start
;
2690 src_pixel
= src_start
;
2691 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2693 src_val
= *src_pixel
++;
2694 *dst_pixel
++ = (((src_val
>> src
->red_shift
) << 10) & 0x7c00) |
2695 (((src_val
>> src
->green_shift
) << 4) & 0x03e0) |
2696 ( (src_val
>> src
->blue_shift
) & 0x001f);
2698 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2699 dst_start
+= dst
->stride
/ 2;
2700 src_start
+= src
->stride
/ 2;
2705 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2707 dst_pixel
= dst_start
;
2708 src_pixel
= src_start
;
2709 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2711 src_val
= *src_pixel
++;
2712 *dst_pixel
++ = (((get_field(src_val
, src
->red_shift
, src
->red_len
) << 7) & 0x7c00) |
2713 ((get_field(src_val
, src
->green_shift
, src
->green_len
) << 2) & 0x03e0) |
2714 ( get_field(src_val
, src
->blue_shift
, src
->blue_len
) >> 3));
2716 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2717 dst_start
+= dst
->stride
/ 2;
2718 src_start
+= src
->stride
/ 2;
2726 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2727 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2728 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2730 dst_pixel
= dst_start
;
2731 src_pixel
= src_start
;
2732 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2734 RGBQUAD rgb
= color_table
[*src_pixel
++];
2735 *dst_pixel
++ = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2736 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2737 ((rgb
.rgbBlue
>> 3) & 0x001f);
2739 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2740 dst_start
+= dst
->stride
/ 2;
2741 src_start
+= src
->stride
;
2748 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2749 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2750 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2752 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
2753 src_pixel
= src_start
;
2754 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2758 rgb
= color_table
[*src_pixel
++ & 0xf];
2760 rgb
= color_table
[*src_pixel
>> 4];
2761 dst_start
[x
] = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2762 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2763 ((rgb
.rgbBlue
>> 3) & 0x001f);
2765 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2766 dst_start
+= dst
->stride
/ 2;
2767 src_start
+= src
->stride
;
2774 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2775 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
2776 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2778 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
2779 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
2782 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
2783 rgb
= color_table
[src_val
];
2784 dst_start
[x
] = ((rgb
.rgbRed
<< 7) & 0x7c00) |
2785 ((rgb
.rgbGreen
<< 2) & 0x03e0) |
2786 ((rgb
.rgbBlue
>> 3) & 0x001f);
2788 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
2789 dst_start
+= dst
->stride
/ 2;
2790 src_start
+= src
->stride
;
2797 static void convert_to_16(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
2799 WORD
*dst_start
= get_pixel_ptr_16(dst
, 0, 0), *dst_pixel
;
2800 INT x
, y
, pad_size
= ((dst
->width
+ 1) & ~1) * 2 - (src_rect
->right
- src_rect
->left
) * 2;
2803 switch(src
->bit_count
)
2807 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2809 if(src
->funcs
== &funcs_8888
)
2811 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2813 dst_pixel
= dst_start
;
2814 src_pixel
= src_start
;
2815 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2817 src_val
= *src_pixel
++;
2818 *dst_pixel
++ = put_field(src_val
>> 16, dst
->red_shift
, dst
->red_len
) |
2819 put_field(src_val
>> 8, dst
->green_shift
, dst
->green_len
) |
2820 put_field(src_val
, dst
->blue_shift
, dst
->blue_len
);
2822 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2823 dst_start
+= dst
->stride
/ 2;
2824 src_start
+= src
->stride
/ 4;
2827 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
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
++ = put_field(src_val
>> src
->red_shift
, dst
->red_shift
, dst
->red_len
) |
2837 put_field(src_val
>> src
->green_shift
, dst
->green_shift
, dst
->green_len
) |
2838 put_field(src_val
>> src
->blue_shift
, dst
->blue_shift
, dst
->blue_len
);
2840 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2841 dst_start
+= dst
->stride
/ 2;
2842 src_start
+= src
->stride
/ 4;
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
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
2855 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
2856 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
2858 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2859 dst_start
+= dst
->stride
/ 2;
2860 src_start
+= src
->stride
/ 4;
2868 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2870 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2872 dst_pixel
= dst_start
;
2873 src_pixel
= src_start
;
2874 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2877 rgb
.rgbBlue
= *src_pixel
++;
2878 rgb
.rgbGreen
= *src_pixel
++;
2879 rgb
.rgbRed
= *src_pixel
++;
2881 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
2882 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
2883 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
2885 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2886 dst_start
+= dst
->stride
/ 2;
2887 src_start
+= src
->stride
;
2894 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
2895 if(src
->funcs
== &funcs_555
)
2897 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2899 dst_pixel
= dst_start
;
2900 src_pixel
= src_start
;
2901 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2903 src_val
= *src_pixel
++;
2904 *dst_pixel
++ = put_field(((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07), dst
->red_shift
, dst
->red_len
) |
2905 put_field(((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07), dst
->green_shift
, dst
->green_len
) |
2906 put_field(((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2908 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2909 dst_start
+= dst
->stride
/ 2;
2910 src_start
+= src
->stride
/ 2;
2913 else if(bit_fields_match(src
, dst
))
2915 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
2916 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
2919 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2921 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
) * 2);
2922 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
2923 dst_start
+= dst
->stride
/ 2;
2924 src_start
+= src
->stride
/ 2;
2928 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
2930 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2932 dst_pixel
= dst_start
;
2933 src_pixel
= src_start
;
2934 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2936 src_val
= *src_pixel
++;
2937 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2938 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
2939 put_field( (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
2940 (((src_val
>> src
->green_shift
) >> 2) & 0x07), dst
->green_shift
, dst
->green_len
) |
2941 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2942 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2944 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2945 dst_start
+= dst
->stride
/ 2;
2946 src_start
+= src
->stride
/ 2;
2949 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
2951 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2953 dst_pixel
= dst_start
;
2954 src_pixel
= src_start
;
2955 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2957 src_val
= *src_pixel
++;
2958 *dst_pixel
++ = put_field( (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
2959 (((src_val
>> src
->red_shift
) >> 2) & 0x07), dst
->red_shift
, dst
->red_len
) |
2960 put_field( (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
2961 (((src_val
>> src
->green_shift
) >> 4) & 0x03), dst
->green_shift
, dst
->green_len
) |
2962 put_field( (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
2963 (((src_val
>> src
->blue_shift
) >> 2) & 0x07), dst
->blue_shift
, dst
->blue_len
);
2965 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2966 dst_start
+= dst
->stride
/ 2;
2967 src_start
+= src
->stride
/ 2;
2972 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
2974 dst_pixel
= dst_start
;
2975 src_pixel
= src_start
;
2976 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
2978 src_val
= *src_pixel
++;
2979 *dst_pixel
++ = put_field(get_field(src_val
, src
->red_shift
, src
->red_len
), dst
->red_shift
, dst
->red_len
) |
2980 put_field(get_field(src_val
, src
->green_shift
, src
->green_len
), dst
->green_shift
, dst
->green_len
) |
2981 put_field(get_field(src_val
, src
->blue_shift
, src
->blue_len
), dst
->blue_shift
, dst
->blue_len
);
2983 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
2984 dst_start
+= dst
->stride
/ 2;
2985 src_start
+= src
->stride
/ 2;
2993 const RGBQUAD
*color_table
= get_dib_color_table( src
);
2994 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
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 RGBQUAD rgb
= color_table
[*src_pixel
++];
3002 *dst_pixel
++ = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
3003 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
3004 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
3006 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3007 dst_start
+= dst
->stride
/ 2;
3008 src_start
+= src
->stride
;
3015 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3016 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3017 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3019 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3020 src_pixel
= src_start
;
3021 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3025 rgb
= color_table
[*src_pixel
++ & 0xf];
3027 rgb
= color_table
[*src_pixel
>> 4];
3028 dst_start
[x
] = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
3029 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
3030 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
3032 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3033 dst_start
+= dst
->stride
/ 2;
3034 src_start
+= src
->stride
;
3041 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3042 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3043 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3045 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3046 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3049 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3050 rgb
= color_table
[src_val
];
3051 dst_start
[x
] = put_field(rgb
.rgbRed
, dst
->red_shift
, dst
->red_len
) |
3052 put_field(rgb
.rgbGreen
, dst
->green_shift
, dst
->green_len
) |
3053 put_field(rgb
.rgbBlue
, dst
->blue_shift
, dst
->blue_len
);
3055 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3056 dst_start
+= dst
->stride
/ 2;
3057 src_start
+= src
->stride
;
3064 static inline BOOL
color_tables_match(const dib_info
*d1
, const dib_info
*d2
)
3066 if (!d1
->color_table
|| !d2
->color_table
) return (!d1
->color_table
&& !d2
->color_table
);
3067 return !memcmp(d1
->color_table
, d2
->color_table
, (1 << d1
->bit_count
) * sizeof(d1
->color_table
[0]));
3070 static inline DWORD
rgb_lookup_colortable(const dib_info
*dst
, BYTE r
, BYTE g
, BYTE b
)
3072 /* Windows reduces precision to 5 bits, probably in order to build some sort of lookup cache */
3073 return rgb_to_pixel_colortable( dst
, (r
& ~7) + 4, (g
& ~7) + 4, (b
& ~7) + 4 );
3076 static void convert_to_8(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3078 BYTE
*dst_start
= get_pixel_ptr_8(dst
, 0, 0), *dst_pixel
;
3079 INT x
, y
, pad_size
= ((dst
->width
+ 3) & ~3) - (src_rect
->right
- src_rect
->left
);
3082 switch(src
->bit_count
)
3086 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3088 if(src
->funcs
== &funcs_8888
)
3090 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3092 dst_pixel
= dst_start
;
3093 src_pixel
= src_start
;
3094 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3096 src_val
= *src_pixel
++;
3097 *dst_pixel
++ = rgb_lookup_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
3099 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3100 dst_start
+= dst
->stride
;
3101 src_start
+= src
->stride
/ 4;
3104 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3106 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3108 dst_pixel
= dst_start
;
3109 src_pixel
= src_start
;
3110 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3112 src_val
= *src_pixel
++;
3113 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3114 src_val
>> src
->red_shift
,
3115 src_val
>> src
->green_shift
,
3116 src_val
>> src
->blue_shift
);
3118 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3119 dst_start
+= dst
->stride
;
3120 src_start
+= src
->stride
/ 4;
3125 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3127 dst_pixel
= dst_start
;
3128 src_pixel
= src_start
;
3129 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3131 src_val
= *src_pixel
++;
3132 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3133 get_field(src_val
, src
->red_shift
, src
->red_len
),
3134 get_field(src_val
, src
->green_shift
, src
->green_len
),
3135 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3137 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3138 dst_start
+= dst
->stride
;
3139 src_start
+= src
->stride
/ 4;
3147 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3149 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3151 dst_pixel
= dst_start
;
3152 src_pixel
= src_start
;
3153 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3155 *dst_pixel
++ = rgb_lookup_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0] );
3157 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3158 dst_start
+= dst
->stride
;
3159 src_start
+= src
->stride
;
3166 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3167 if(src
->funcs
== &funcs_555
)
3169 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3171 dst_pixel
= dst_start
;
3172 src_pixel
= src_start
;
3173 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3175 src_val
= *src_pixel
++;
3176 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3177 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3178 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3179 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
3181 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3182 dst_start
+= dst
->stride
;
3183 src_start
+= src
->stride
/ 2;
3186 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3188 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3190 dst_pixel
= dst_start
;
3191 src_pixel
= src_start
;
3192 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3194 src_val
= *src_pixel
++;
3195 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3196 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3197 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3198 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3199 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3200 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3201 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3203 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3204 dst_start
+= dst
->stride
;
3205 src_start
+= src
->stride
/ 2;
3208 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3210 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3212 dst_pixel
= dst_start
;
3213 src_pixel
= src_start
;
3214 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3216 src_val
= *src_pixel
++;
3217 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3218 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3219 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3220 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3221 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3222 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3223 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3225 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3226 dst_start
+= dst
->stride
;
3227 src_start
+= src
->stride
/ 2;
3232 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3234 dst_pixel
= dst_start
;
3235 src_pixel
= src_start
;
3236 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3238 src_val
= *src_pixel
++;
3239 *dst_pixel
++ = rgb_lookup_colortable(dst
,
3240 get_field(src_val
, src
->red_shift
, src
->red_len
),
3241 get_field(src_val
, src
->green_shift
, src
->green_len
),
3242 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3244 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3245 dst_start
+= dst
->stride
;
3246 src_start
+= src
->stride
/ 2;
3254 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3256 if(color_tables_match(dst
, src
))
3258 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
3259 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3262 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3264 memcpy(dst_start
, src_start
, src_rect
->right
- src_rect
->left
);
3265 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
), 0, pad_size
);
3266 dst_start
+= dst
->stride
;
3267 src_start
+= src
->stride
;
3273 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3274 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3276 dst_pixel
= dst_start
;
3277 src_pixel
= src_start
;
3278 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3280 RGBQUAD rgb
= color_table
[*src_pixel
++];
3281 *dst_pixel
++ = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3283 if(pad_size
) memset(dst_pixel
, 0, pad_size
);
3284 dst_start
+= dst
->stride
;
3285 src_start
+= src
->stride
;
3293 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3294 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3295 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3297 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3298 src_pixel
= src_start
;
3299 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3303 rgb
= color_table
[*src_pixel
++ & 0xf];
3305 rgb
= color_table
[*src_pixel
>> 4];
3306 dst_start
[x
] = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3308 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3309 dst_start
+= dst
->stride
;
3310 src_start
+= src
->stride
;
3317 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3318 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3319 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3321 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3322 for (x
= 0; x
< src_rect
->right
- src_rect
->left
; x
++, pos
++)
3325 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3326 rgb
= color_table
[src_val
];
3327 dst_start
[x
] = rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3329 if(pad_size
) memset(dst_start
+ x
, 0, pad_size
);
3330 dst_start
+= dst
->stride
;
3331 src_start
+= src
->stride
;
3338 static void convert_to_4(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3340 BYTE
*dst_start
= get_pixel_ptr_4(dst
, 0, 0), *dst_pixel
, dst_val
;
3341 INT x
, y
, pad_size
= ((dst
->width
+ 7) & ~7) / 2 - (src_rect
->right
- src_rect
->left
+ 1) / 2;
3344 switch(src
->bit_count
)
3348 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3350 if(src
->funcs
== &funcs_8888
)
3352 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3354 dst_pixel
= dst_start
;
3355 src_pixel
= src_start
;
3356 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3358 src_val
= *src_pixel
++;
3359 dst_val
= rgb_to_pixel_colortable(dst
, src_val
>> 16, src_val
>> 8, src_val
);
3360 if((x
- src_rect
->left
) & 1)
3362 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3366 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3370 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3371 memset(dst_pixel
, 0, pad_size
);
3373 dst_start
+= dst
->stride
;
3374 src_start
+= src
->stride
/ 4;
3377 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3379 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3381 dst_pixel
= dst_start
;
3382 src_pixel
= src_start
;
3383 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3385 src_val
= *src_pixel
++;
3386 dst_val
= rgb_to_pixel_colortable(dst
,
3387 src_val
>> src
->red_shift
,
3388 src_val
>> src
->green_shift
,
3389 src_val
>> src
->blue_shift
);
3390 if((x
- src_rect
->left
) & 1)
3392 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3396 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3400 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3401 memset(dst_pixel
, 0, pad_size
);
3403 dst_start
+= dst
->stride
;
3404 src_start
+= src
->stride
/ 4;
3409 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3411 dst_pixel
= dst_start
;
3412 src_pixel
= src_start
;
3413 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3415 src_val
= *src_pixel
++;
3416 dst_val
= rgb_to_pixel_colortable(dst
,
3417 get_field(src_val
, src
->red_shift
, src
->red_len
),
3418 get_field(src_val
, src
->green_shift
, src
->green_len
),
3419 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3420 if((x
- src_rect
->left
) & 1)
3422 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3426 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3430 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3431 memset(dst_pixel
, 0, pad_size
);
3433 dst_start
+= dst
->stride
;
3434 src_start
+= src
->stride
/ 4;
3442 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3444 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3446 dst_pixel
= dst_start
;
3447 src_pixel
= src_start
;
3448 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3450 dst_val
= rgb_to_pixel_colortable(dst
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
3452 if((x
- src_rect
->left
) & 1)
3454 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3458 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3462 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3463 memset(dst_pixel
, 0, pad_size
);
3465 dst_start
+= dst
->stride
;
3466 src_start
+= src
->stride
;
3473 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3474 if(src
->funcs
== &funcs_555
)
3476 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3478 dst_pixel
= dst_start
;
3479 src_pixel
= src_start
;
3480 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3482 src_val
= *src_pixel
++;
3483 dst_val
= rgb_to_pixel_colortable(dst
,
3484 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3485 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3486 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07) );
3487 if((x
- src_rect
->left
) & 1)
3489 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3493 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3497 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3498 memset(dst_pixel
, 0, pad_size
);
3500 dst_start
+= dst
->stride
;
3501 src_start
+= src
->stride
/ 2;
3504 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3506 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3508 dst_pixel
= dst_start
;
3509 src_pixel
= src_start
;
3510 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3512 src_val
= *src_pixel
++;
3513 dst_val
= rgb_to_pixel_colortable(dst
,
3514 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3515 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3516 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3517 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3518 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3519 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3520 if((x
- src_rect
->left
) & 1)
3522 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3526 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3530 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3531 memset(dst_pixel
, 0, pad_size
);
3533 dst_start
+= dst
->stride
;
3534 src_start
+= src
->stride
/ 2;
3537 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3539 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3541 dst_pixel
= dst_start
;
3542 src_pixel
= src_start
;
3543 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3545 src_val
= *src_pixel
++;
3546 dst_val
= rgb_to_pixel_colortable(dst
,
3547 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3548 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3549 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3550 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3551 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3552 (((src_val
>> src
->blue_shift
) >> 2) & 0x07) );
3553 if((x
- src_rect
->left
) & 1)
3555 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3559 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3563 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3564 memset(dst_pixel
, 0, pad_size
);
3566 dst_start
+= dst
->stride
;
3567 src_start
+= src
->stride
/ 2;
3572 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3574 dst_pixel
= dst_start
;
3575 src_pixel
= src_start
;
3576 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3578 src_val
= *src_pixel
++;
3579 dst_val
= rgb_to_pixel_colortable(dst
,
3580 get_field(src_val
, src
->red_shift
, src
->red_len
),
3581 get_field(src_val
, src
->green_shift
, src
->green_len
),
3582 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3583 if((x
- src_rect
->left
) & 1)
3585 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3589 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3593 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3594 memset(dst_pixel
, 0, pad_size
);
3596 dst_start
+= dst
->stride
;
3597 src_start
+= src
->stride
/ 2;
3605 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3606 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3608 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3610 dst_pixel
= dst_start
;
3611 src_pixel
= src_start
;
3612 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++)
3614 RGBQUAD rgb
= color_table
[*src_pixel
++];
3615 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3616 if((x
- src_rect
->left
) & 1)
3618 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3622 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3626 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3627 memset(dst_pixel
, 0, pad_size
);
3629 dst_start
+= dst
->stride
;
3630 src_start
+= src
->stride
;
3637 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3639 if(color_tables_match(dst
, src
) && ((src
->rect
.left
+ src_rect
->left
) & 1) == 0)
3641 if (src
->stride
> 0 && src
->stride
== dst
->stride
&& !pad_size
)
3642 memcpy(dst_start
, src_start
, (src_rect
->bottom
- src_rect
->top
) * src
->stride
);
3645 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3647 memcpy(dst_start
, src_start
, (src_rect
->right
- src_rect
->left
+ 1) / 2);
3648 if(pad_size
) memset(dst_start
+ (src_rect
->right
- src_rect
->left
+ 1) / 2, 0, pad_size
);
3649 dst_start
+= dst
->stride
;
3650 src_start
+= src
->stride
;
3656 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3657 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3659 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
3660 dst_pixel
= dst_start
;
3661 src_pixel
= src_start
;
3662 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, pos
++)
3666 rgb
= color_table
[*src_pixel
++ & 0xf];
3668 rgb
= color_table
[*src_pixel
>> 4];
3669 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3670 if((x
- src_rect
->left
) & 1)
3672 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3676 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3680 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3681 memset(dst_pixel
, 0, pad_size
);
3683 dst_start
+= dst
->stride
;
3684 src_start
+= src
->stride
;
3692 const RGBQUAD
*color_table
= get_dib_color_table( src
);
3693 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
3694 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3696 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
3697 dst_pixel
= dst_start
;
3698 for(x
= src_rect
->left
; x
< src_rect
->right
; x
++, pos
++)
3701 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
3702 rgb
= color_table
[src_val
];
3703 dst_val
= rgb_to_pixel_colortable(dst
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
3704 if((x
- src_rect
->left
) & 1)
3706 *dst_pixel
= (dst_val
& 0x0f) | (*dst_pixel
& 0xf0);
3710 *dst_pixel
= (dst_val
<< 4) & 0xf0;
3714 if((x
- src_rect
->left
) & 1) dst_pixel
++;
3715 memset(dst_pixel
, 0, pad_size
);
3717 dst_start
+= dst
->stride
;
3718 src_start
+= src
->stride
;
3725 static void convert_to_1(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
3727 BYTE
*dst_start
= get_pixel_ptr_1(dst
, 0, 0), *dst_pixel
, dst_val
;
3728 INT x
, y
, pad_size
= ((dst
->width
+ 31) & ~31) / 8 - (src_rect
->right
- src_rect
->left
+ 7) / 8;
3732 switch(src
->bit_count
)
3736 DWORD
*src_start
= get_pixel_ptr_32(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3738 if(src
->funcs
== &funcs_8888
)
3740 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3742 dst_pixel
= dst_start
;
3743 src_pixel
= src_start
;
3744 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3746 src_val
= *src_pixel
++;
3747 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_val
>> 16, src_val
>> 8, src_val
);
3749 if(bit_pos
== 0) *dst_pixel
= 0;
3750 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3760 if(bit_pos
!= 0) dst_pixel
++;
3761 memset(dst_pixel
, 0, pad_size
);
3763 dst_start
+= dst
->stride
;
3764 src_start
+= src
->stride
/ 4;
3767 else if(src
->red_len
== 8 && src
->green_len
== 8 && src
->blue_len
== 8)
3769 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3771 dst_pixel
= dst_start
;
3772 src_pixel
= src_start
;
3773 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3775 src_val
= *src_pixel
++;
3776 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
,
3777 src_val
>> src
->red_shift
,
3778 src_val
>> src
->green_shift
,
3779 src_val
>> src
->blue_shift
);
3781 if(bit_pos
== 0) *dst_pixel
= 0;
3782 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3792 if(bit_pos
!= 0) dst_pixel
++;
3793 memset(dst_pixel
, 0, pad_size
);
3795 dst_start
+= dst
->stride
;
3796 src_start
+= src
->stride
/ 4;
3801 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3803 dst_pixel
= dst_start
;
3804 src_pixel
= src_start
;
3805 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3807 src_val
= *src_pixel
++;
3808 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
,
3809 get_field(src_val
, src
->red_shift
, src
->red_len
),
3810 get_field(src_val
, src
->green_shift
, src
->green_len
),
3811 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3813 if(bit_pos
== 0) *dst_pixel
= 0;
3814 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3824 if(bit_pos
!= 0) dst_pixel
++;
3825 memset(dst_pixel
, 0, pad_size
);
3827 dst_start
+= dst
->stride
;
3828 src_start
+= src
->stride
/ 4;
3836 BYTE
*src_start
= get_pixel_ptr_24(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3838 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3840 dst_pixel
= dst_start
;
3841 src_pixel
= src_start
;
3842 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, src_pixel
+= 3)
3844 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, src_pixel
[2], src_pixel
[1], src_pixel
[0]);
3846 if(bit_pos
== 0) *dst_pixel
= 0;
3847 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3857 if(bit_pos
!= 0) dst_pixel
++;
3858 memset(dst_pixel
, 0, pad_size
);
3860 dst_start
+= dst
->stride
;
3861 src_start
+= src
->stride
;
3868 WORD
*src_start
= get_pixel_ptr_16(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
3869 if(src
->funcs
== &funcs_555
)
3871 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3873 dst_pixel
= dst_start
;
3874 src_pixel
= src_start
;
3875 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3877 src_val
= *src_pixel
++;
3878 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
,
3879 ((src_val
>> 7) & 0xf8) | ((src_val
>> 12) & 0x07),
3880 ((src_val
>> 2) & 0xf8) | ((src_val
>> 7) & 0x07),
3881 ((src_val
<< 3) & 0xf8) | ((src_val
>> 2) & 0x07));
3883 if(bit_pos
== 0) *dst_pixel
= 0;
3884 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3894 if(bit_pos
!= 0) dst_pixel
++;
3895 memset(dst_pixel
, 0, pad_size
);
3897 dst_start
+= dst
->stride
;
3898 src_start
+= src
->stride
/ 2;
3901 else if(src
->red_len
== 5 && src
->green_len
== 5 && src
->blue_len
== 5)
3903 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3905 dst_pixel
= dst_start
;
3906 src_pixel
= src_start
;
3907 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3909 src_val
= *src_pixel
++;
3910 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
,
3911 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3912 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3913 (((src_val
>> src
->green_shift
) << 3) & 0xf8) |
3914 (((src_val
>> src
->green_shift
) >> 2) & 0x07),
3915 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3916 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
3917 if(bit_pos
== 0) *dst_pixel
= 0;
3918 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3928 if(bit_pos
!= 0) dst_pixel
++;
3929 memset(dst_pixel
, 0, pad_size
);
3931 dst_start
+= dst
->stride
;
3932 src_start
+= src
->stride
/ 2;
3935 else if(src
->red_len
== 5 && src
->green_len
== 6 && src
->blue_len
== 5)
3937 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3939 dst_pixel
= dst_start
;
3940 src_pixel
= src_start
;
3941 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3943 src_val
= *src_pixel
++;
3944 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
,
3945 (((src_val
>> src
->red_shift
) << 3) & 0xf8) |
3946 (((src_val
>> src
->red_shift
) >> 2) & 0x07),
3947 (((src_val
>> src
->green_shift
) << 2) & 0xfc) |
3948 (((src_val
>> src
->green_shift
) >> 4) & 0x03),
3949 (((src_val
>> src
->blue_shift
) << 3) & 0xf8) |
3950 (((src_val
>> src
->blue_shift
) >> 2) & 0x07));
3951 if(bit_pos
== 0) *dst_pixel
= 0;
3952 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3962 if(bit_pos
!= 0) dst_pixel
++;
3963 memset(dst_pixel
, 0, pad_size
);
3965 dst_start
+= dst
->stride
;
3966 src_start
+= src
->stride
/ 2;
3971 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
3973 dst_pixel
= dst_start
;
3974 src_pixel
= src_start
;
3975 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
3977 src_val
= *src_pixel
++;
3978 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
,
3979 get_field(src_val
, src
->red_shift
, src
->red_len
),
3980 get_field(src_val
, src
->green_shift
, src
->green_len
),
3981 get_field(src_val
, src
->blue_shift
, src
->blue_len
));
3982 if(bit_pos
== 0) *dst_pixel
= 0;
3983 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
3993 if(bit_pos
!= 0) dst_pixel
++;
3994 memset(dst_pixel
, 0, pad_size
);
3996 dst_start
+= dst
->stride
;
3997 src_start
+= src
->stride
/ 2;
4005 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4006 BYTE
*src_start
= get_pixel_ptr_8(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4008 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4010 dst_pixel
= dst_start
;
4011 src_pixel
= src_start
;
4012 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++)
4014 RGBQUAD rgb
= color_table
[*src_pixel
++];
4015 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
4017 if(bit_pos
== 0) *dst_pixel
= 0;
4018 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4028 if(bit_pos
!= 0) dst_pixel
++;
4029 memset(dst_pixel
, 0, pad_size
);
4031 dst_start
+= dst
->stride
;
4032 src_start
+= src
->stride
;
4039 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4040 BYTE
*src_start
= get_pixel_ptr_4(src
, src_rect
->left
, src_rect
->top
), *src_pixel
;
4042 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4044 int pos
= (src
->rect
.left
+ src_rect
->left
) & 1;
4045 dst_pixel
= dst_start
;
4046 src_pixel
= src_start
;
4047 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, pos
++)
4051 rgb
= color_table
[*src_pixel
++ & 0xf];
4053 rgb
= color_table
[*src_pixel
>> 4];
4054 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
4056 if(bit_pos
== 0) *dst_pixel
= 0;
4057 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4067 if(bit_pos
!= 0) dst_pixel
++;
4068 memset(dst_pixel
, 0, pad_size
);
4070 dst_start
+= dst
->stride
;
4071 src_start
+= src
->stride
;
4076 /* Note that while MSDN states that a 1 bpp dib brush -> mono dc
4077 uses text/bkgnd colours instead of the dib's colour table, this
4078 doesn't appear to be the case for a dc backed by a
4083 const RGBQUAD
*color_table
= get_dib_color_table( src
);
4084 BYTE
*src_start
= get_pixel_ptr_1(src
, src_rect
->left
, src_rect
->top
);
4085 for(y
= src_rect
->top
; y
< src_rect
->bottom
; y
++)
4087 int pos
= (src
->rect
.left
+ src_rect
->left
) & 7;
4088 dst_pixel
= dst_start
;
4089 for(x
= src_rect
->left
, bit_pos
= 0; x
< src_rect
->right
; x
++, pos
++)
4092 src_val
= (src_start
[pos
/ 8] & pixel_masks_1
[pos
% 8]) ? 1 : 0;
4093 rgb
= color_table
[src_val
];
4094 dst_val
= rgb_to_pixel_mono(dst
, dither
, x
, y
, rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
);
4096 if(bit_pos
== 0) *dst_pixel
= 0;
4097 *dst_pixel
= (*dst_pixel
& ~pixel_masks_1
[bit_pos
]) | (dst_val
& pixel_masks_1
[bit_pos
]);
4107 if(bit_pos
!= 0) dst_pixel
++;
4108 memset(dst_pixel
, 0, pad_size
);
4110 dst_start
+= dst
->stride
;
4111 src_start
+= src
->stride
;
4118 static void convert_to_null(dib_info
*dst
, const dib_info
*src
, const RECT
*src_rect
, BOOL dither
)
4122 static inline BYTE
blend_color(BYTE dst
, BYTE src
, DWORD alpha
)
4124 return (src
* alpha
+ dst
* (255 - alpha
) + 127) / 255;
4127 static inline DWORD
blend_argb_constant_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
4129 return (blend_color( dst
, src
, alpha
) |
4130 blend_color( dst
>> 8, src
>> 8, alpha
) << 8 |
4131 blend_color( dst
>> 16, src
>> 16, alpha
) << 16 |
4132 blend_color( dst
>> 24, src
>> 24, alpha
) << 24);
4135 static inline DWORD
blend_argb_no_src_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
4137 return (blend_color( dst
, src
, alpha
) |
4138 blend_color( dst
>> 8, src
>> 8, alpha
) << 8 |
4139 blend_color( dst
>> 16, src
>> 16, alpha
) << 16 |
4140 blend_color( dst
>> 24, 255, alpha
) << 24);
4143 static inline DWORD
blend_argb( DWORD dst
, DWORD src
)
4146 BYTE g
= (BYTE
)(src
>> 8);
4147 BYTE r
= (BYTE
)(src
>> 16);
4148 DWORD alpha
= (BYTE
)(src
>> 24);
4149 return ((b
+ ((BYTE
)dst
* (255 - alpha
) + 127) / 255) |
4150 (g
+ ((BYTE
)(dst
>> 8) * (255 - alpha
) + 127) / 255) << 8 |
4151 (r
+ ((BYTE
)(dst
>> 16) * (255 - alpha
) + 127) / 255) << 16 |
4152 (alpha
+ ((BYTE
)(dst
>> 24) * (255 - alpha
) + 127) / 255) << 24);
4155 static inline DWORD
blend_argb_alpha( DWORD dst
, DWORD src
, DWORD alpha
)
4157 BYTE b
= ((BYTE
)src
* alpha
+ 127) / 255;
4158 BYTE g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
4159 BYTE r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
4160 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
4161 return ((b
+ ((BYTE
)dst
* (255 - alpha
) + 127) / 255) |
4162 (g
+ ((BYTE
)(dst
>> 8) * (255 - alpha
) + 127) / 255) << 8 |
4163 (r
+ ((BYTE
)(dst
>> 16) * (255 - alpha
) + 127) / 255) << 16 |
4164 (alpha
+ ((BYTE
)(dst
>> 24) * (255 - alpha
) + 127) / 255) << 24);
4167 static inline DWORD
blend_rgb( BYTE dst_r
, BYTE dst_g
, BYTE dst_b
, DWORD src
, BLENDFUNCTION blend
)
4169 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
4171 DWORD alpha
= blend
.SourceConstantAlpha
;
4172 BYTE src_b
= ((BYTE
)src
* alpha
+ 127) / 255;
4173 BYTE src_g
= ((BYTE
)(src
>> 8) * alpha
+ 127) / 255;
4174 BYTE src_r
= ((BYTE
)(src
>> 16) * alpha
+ 127) / 255;
4175 alpha
= ((BYTE
)(src
>> 24) * alpha
+ 127) / 255;
4176 return ((src_b
+ (dst_b
* (255 - alpha
) + 127) / 255) |
4177 (src_g
+ (dst_g
* (255 - alpha
) + 127) / 255) << 8 |
4178 (src_r
+ (dst_r
* (255 - alpha
) + 127) / 255) << 16);
4180 return (blend_color( dst_b
, src
, blend
.SourceConstantAlpha
) |
4181 blend_color( dst_g
, src
>> 8, blend
.SourceConstantAlpha
) << 8 |
4182 blend_color( dst_r
, src
>> 16, blend
.SourceConstantAlpha
) << 16);
4185 static void blend_rect_8888(const dib_info
*dst
, const RECT
*rc
,
4186 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4188 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4189 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
4192 if (blend
.AlphaFormat
& AC_SRC_ALPHA
)
4194 if (blend
.SourceConstantAlpha
== 255)
4195 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4196 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4197 dst_ptr
[x
] = blend_argb( dst_ptr
[x
], src_ptr
[x
] );
4199 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4200 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4201 dst_ptr
[x
] = blend_argb_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
4203 else if (src
->compression
== BI_RGB
)
4204 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4205 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4206 dst_ptr
[x
] = blend_argb_constant_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
4208 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4209 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4210 dst_ptr
[x
] = blend_argb_no_src_alpha( dst_ptr
[x
], src_ptr
[x
], blend
.SourceConstantAlpha
);
4213 static void blend_rect_32(const dib_info
*dst
, const RECT
*rc
,
4214 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4216 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4217 DWORD
*dst_ptr
= get_pixel_ptr_32( dst
, rc
->left
, rc
->top
);
4220 if (dst
->red_len
== 8 && dst
->green_len
== 8 && dst
->blue_len
== 8)
4222 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4224 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4226 DWORD val
= blend_rgb( dst_ptr
[x
] >> dst
->red_shift
,
4227 dst_ptr
[x
] >> dst
->green_shift
,
4228 dst_ptr
[x
] >> dst
->blue_shift
,
4229 src_ptr
[x
], blend
);
4230 dst_ptr
[x
] = ((( val
& 0xff) << dst
->blue_shift
) |
4231 (((val
>> 8) & 0xff) << dst
->green_shift
) |
4232 (((val
>> 16) & 0xff) << dst
->red_shift
));
4238 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 4, src_ptr
+= src
->stride
/ 4)
4240 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4242 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
4243 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
4244 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
4245 src_ptr
[x
], blend
);
4246 dst_ptr
[x
] = (put_field( val
>> 16, dst
->red_shift
, dst
->red_len
) |
4247 put_field( val
>> 8, dst
->green_shift
, dst
->green_len
) |
4248 put_field( val
, dst
->blue_shift
, dst
->blue_len
));
4254 static void blend_rect_24(const dib_info
*dst
, const RECT
*rc
,
4255 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4257 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4258 BYTE
*dst_ptr
= get_pixel_ptr_24( dst
, rc
->left
, rc
->top
);
4261 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4263 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4265 DWORD val
= blend_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
4266 src_ptr
[x
], blend
);
4267 dst_ptr
[x
* 3] = val
;
4268 dst_ptr
[x
* 3 + 1] = val
>> 8;
4269 dst_ptr
[x
* 3 + 2] = val
>> 16;
4274 static void blend_rect_555(const dib_info
*dst
, const RECT
*rc
,
4275 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4277 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4278 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
4281 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
4283 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4285 DWORD val
= blend_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
4286 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
4287 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
4288 src_ptr
[x
], blend
);
4289 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
4294 static void blend_rect_16(const dib_info
*dst
, const RECT
*rc
,
4295 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4297 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4298 WORD
*dst_ptr
= get_pixel_ptr_16( dst
, rc
->left
, rc
->top
);
4301 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
/ 2, src_ptr
+= src
->stride
/ 4)
4303 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4305 DWORD val
= blend_rgb( get_field( dst_ptr
[x
], dst
->red_shift
, dst
->red_len
),
4306 get_field( dst_ptr
[x
], dst
->green_shift
, dst
->green_len
),
4307 get_field( dst_ptr
[x
], dst
->blue_shift
, dst
->blue_len
),
4308 src_ptr
[x
], blend
);
4309 dst_ptr
[x
] = (put_field((val
>> 16), dst
->red_shift
, dst
->red_len
) |
4310 put_field((val
>> 8), dst
->green_shift
, dst
->green_len
) |
4311 put_field( val
, dst
->blue_shift
, dst
->blue_len
));
4316 static void blend_rect_8(const dib_info
*dst
, const RECT
*rc
,
4317 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4319 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4320 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4321 BYTE
*dst_ptr
= get_pixel_ptr_8( dst
, rc
->left
, rc
->top
);
4324 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4326 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4328 RGBQUAD rgb
= color_table
[dst_ptr
[x
]];
4329 DWORD val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[x
], blend
);
4330 dst_ptr
[x
] = rgb_lookup_colortable( dst
, val
>> 16, val
>> 8, val
);
4335 static void blend_rect_4(const dib_info
*dst
, const RECT
*rc
,
4336 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4338 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4339 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4340 BYTE
*dst_ptr
= get_pixel_ptr_4( dst
, rc
->left
, rc
->top
);
4343 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4345 for (i
= 0, x
= (dst
->rect
.left
+ rc
->left
) & 1; i
< rc
->right
- rc
->left
; i
++, x
++)
4347 DWORD val
= ((x
& 1) ? dst_ptr
[x
/ 2] : (dst_ptr
[x
/ 2] >> 4)) & 0x0f;
4348 RGBQUAD rgb
= color_table
[val
];
4349 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[i
], blend
);
4350 val
= rgb_lookup_colortable( dst
, val
>> 16, val
>> 8, val
);
4352 dst_ptr
[x
/ 2] = val
| (dst_ptr
[x
/ 2] & 0xf0);
4354 dst_ptr
[x
/ 2] = (val
<< 4) | (dst_ptr
[x
/ 2] & 0x0f);
4359 static void blend_rect_1(const dib_info
*dst
, const RECT
*rc
,
4360 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4362 const RGBQUAD
*color_table
= get_dib_color_table( dst
);
4363 DWORD
*src_ptr
= get_pixel_ptr_32( src
, origin
->x
, origin
->y
);
4364 BYTE
*dst_ptr
= get_pixel_ptr_1( dst
, rc
->left
, rc
->top
);
4367 for (y
= rc
->top
; y
< rc
->bottom
; y
++, dst_ptr
+= dst
->stride
, src_ptr
+= src
->stride
/ 4)
4369 for (i
= 0, x
= (dst
->rect
.left
+ rc
->left
) & 7; i
< rc
->right
- rc
->left
; i
++, x
++)
4371 DWORD val
= (dst_ptr
[x
/ 8] & pixel_masks_1
[x
% 8]) ? 1 : 0;
4372 RGBQUAD rgb
= color_table
[val
];
4373 val
= blend_rgb( rgb
.rgbRed
, rgb
.rgbGreen
, rgb
.rgbBlue
, src_ptr
[i
], blend
);
4374 val
= rgb_to_pixel_colortable(dst
, val
>> 16, val
>> 8, val
) ? 0xff : 0;
4375 dst_ptr
[x
/ 8] = (dst_ptr
[x
/ 8] & ~pixel_masks_1
[x
% 8]) | (val
& pixel_masks_1
[x
% 8]);
4380 static void blend_rect_null(const dib_info
*dst
, const RECT
*rc
,
4381 const dib_info
*src
, const POINT
*origin
, BLENDFUNCTION blend
)
4385 static inline DWORD
gradient_rgb_8888( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
)
4388 r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 256;
4389 g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 256;
4390 b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 256;
4391 a
= (v
[0].Alpha
* (len
- pos
) + v
[1].Alpha
* pos
) / len
/ 256;
4392 return a
<< 24 | r
<< 16 | g
<< 8 | b
;
4395 static inline DWORD
gradient_rgb_24( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
)
4398 r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 256;
4399 g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 256;
4400 b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 256;
4401 return r
<< 16 | g
<< 8 | b
;
4404 static inline WORD
gradient_rgb_555( const TRIVERTEX
*v
, unsigned int pos
, unsigned int len
,
4405 unsigned int x
, unsigned int y
)
4407 int r
= (v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4408 int g
= (v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4409 int b
= (v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4410 r
= min( 31, max( 0, r
/ 16 ));
4411 g
= min( 31, max( 0, g
/ 16 ));
4412 b
= min( 31, max( 0, b
/ 16 ));
4413 return (r
<< 10) | (g
<< 5) | b
;
4416 static inline BYTE
gradient_rgb_8( const dib_info
*dib
, const TRIVERTEX
*v
,
4417 unsigned int pos
, unsigned int len
, unsigned int x
, unsigned int y
)
4419 BYTE r
= ((v
[0].Red
* (len
- pos
) + v
[1].Red
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4420 BYTE g
= ((v
[0].Green
* (len
- pos
) + v
[1].Green
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4421 BYTE b
= ((v
[0].Blue
* (len
- pos
) + v
[1].Blue
* pos
) / len
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4422 return rgb_to_pixel_colortable( dib
, r
* 127, g
* 127, b
* 127 );
4425 /* compute the left/right triangle limit for row y */
4426 static inline void triangle_coords( const TRIVERTEX
*v
, const RECT
*rc
, int y
, int *left
, int *right
)
4430 if (y
< v
[1].y
) x1
= edge_coord( y
, v
[0].x
, v
[0].y
, v
[1].x
, v
[1].y
);
4431 else x1
= edge_coord( y
, v
[1].x
, v
[1].y
, v
[2].x
, v
[2].y
);
4433 x2
= edge_coord( y
, v
[0].x
, v
[0].y
, v
[2].x
, v
[2].y
);
4435 *left
= max( rc
->left
, min( x1
, x2
) );
4436 *right
= min( rc
->right
, max( x1
, x2
) );
4439 /* compute the matrix determinant for triangular barycentric coordinates (constant across the triangle) */
4440 static inline int triangle_det( const TRIVERTEX
*v
)
4442 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
);
4445 /* compute the barycentric weights for a given point inside the triangle */
4446 static inline void triangle_weights( const TRIVERTEX
*v
, int x
, int y
, INT64
*l1
, INT64
*l2
)
4448 *l1
= (v
[1].y
- v
[2].y
) * (x
- v
[2].x
) - (v
[1].x
- v
[2].x
) * (y
- v
[2].y
);
4449 *l2
= (v
[2].y
- v
[0].y
) * (x
- v
[2].x
) - (v
[2].x
- v
[0].x
) * (y
- v
[2].y
);
4452 static inline DWORD
gradient_triangle_8888( const TRIVERTEX
*v
, int x
, int y
, int det
)
4457 triangle_weights( v
, x
, y
, &l1
, &l2
);
4458 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 256;
4459 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 256;
4460 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 256;
4461 a
= (v
[0].Alpha
* l1
+ v
[1].Alpha
* l2
+ v
[2].Alpha
* (det
- l1
- l2
)) / det
/ 256;
4462 return a
<< 24 | r
<< 16 | g
<< 8 | b
;
4465 static inline DWORD
gradient_triangle_24( const TRIVERTEX
*v
, int x
, int y
, int det
)
4470 triangle_weights( v
, x
, y
, &l1
, &l2
);
4471 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 256;
4472 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 256;
4473 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 256;
4474 return r
<< 16 | g
<< 8 | b
;
4477 static inline DWORD
gradient_triangle_555( const TRIVERTEX
*v
, int x
, int y
, int det
)
4482 triangle_weights( v
, x
, y
, &l1
, &l2
);
4483 r
= (v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4484 g
= (v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4485 b
= (v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 128 + bayer_4x4
[y
% 4][x
% 4];
4486 r
= min( 31, max( 0, r
/ 16 ));
4487 g
= min( 31, max( 0, g
/ 16 ));
4488 b
= min( 31, max( 0, b
/ 16 ));
4489 return (r
<< 10) | (g
<< 5) | b
;
4492 static inline DWORD
gradient_triangle_8( const dib_info
*dib
, const TRIVERTEX
*v
, int x
, int y
, int det
)
4497 triangle_weights( v
, x
, y
, &l1
, &l2
);
4498 r
= ((v
[0].Red
* l1
+ v
[1].Red
* l2
+ v
[2].Red
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4499 g
= ((v
[0].Green
* l1
+ v
[1].Green
* l2
+ v
[2].Green
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4500 b
= ((v
[0].Blue
* l1
+ v
[1].Blue
* l2
+ v
[2].Blue
* (det
- l1
- l2
)) / det
/ 128 + bayer_16x16
[y
% 16][x
% 16]) / 256;
4501 return rgb_to_pixel_colortable( dib
, r
* 127, g
* 127, b
* 127 );
4504 static BOOL
gradient_rect_8888( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4506 DWORD
*ptr
= get_pixel_ptr_32( dib
, rc
->left
, rc
->top
);
4507 int x
, y
, left
, right
, det
;
4511 case GRADIENT_FILL_RECT_H
:
4512 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4513 ptr
[x
] = gradient_rgb_8888( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
4515 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4516 memcpy( ptr
+ dib
->stride
/ 4, ptr
, (rc
->right
- rc
->left
) * 4 );
4519 case GRADIENT_FILL_RECT_V
:
4520 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4522 DWORD val
= gradient_rgb_8888( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4523 memset_32( ptr
, val
, rc
->right
- rc
->left
);
4527 case GRADIENT_FILL_TRIANGLE
:
4528 if (!(det
= triangle_det( v
))) return FALSE
;
4529 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4531 triangle_coords( v
, rc
, y
, &left
, &right
);
4532 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_8888( v
, x
, y
, det
);
4539 static BOOL
gradient_rect_32( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4541 DWORD
*ptr
= get_pixel_ptr_32( dib
, rc
->left
, rc
->top
);
4542 int x
, y
, left
, right
, det
;
4546 case GRADIENT_FILL_RECT_H
:
4547 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
4549 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4551 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
4552 ptr
[x
] = ((( val
& 0xff) << dib
->blue_shift
) |
4553 (((val
>> 8) & 0xff) << dib
->green_shift
) |
4554 (((val
>> 16) & 0xff) << dib
->red_shift
));
4559 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4561 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
4562 ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4563 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4564 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4568 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4569 memcpy( ptr
+ dib
->stride
/ 4, ptr
, (rc
->right
- rc
->left
) * 4 );
4572 case GRADIENT_FILL_RECT_V
:
4573 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4575 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4576 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
4577 val
= ((( val
& 0xff) << dib
->blue_shift
) |
4578 (((val
>> 8) & 0xff) << dib
->green_shift
) |
4579 (((val
>> 16) & 0xff) << dib
->red_shift
));
4581 val
= (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4582 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4583 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4585 memset_32( ptr
, val
, rc
->right
- rc
->left
);
4589 case GRADIENT_FILL_TRIANGLE
:
4590 if (!(det
= triangle_det( v
))) return FALSE
;
4591 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 4)
4593 triangle_coords( v
, rc
, y
, &left
, &right
);
4595 if (dib
->red_len
== 8 && dib
->green_len
== 8 && dib
->blue_len
== 8)
4596 for (x
= left
; x
< right
; x
++)
4598 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
4599 ptr
[x
- rc
->left
] = ((( val
& 0xff) << dib
->blue_shift
) |
4600 (((val
>> 8) & 0xff) << dib
->green_shift
) |
4601 (((val
>> 16) & 0xff) << dib
->red_shift
));
4604 for (x
= left
; x
< right
; x
++)
4606 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
4607 ptr
[x
- rc
->left
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4608 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4609 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4617 static BOOL
gradient_rect_24( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4619 BYTE
*ptr
= get_pixel_ptr_24( dib
, rc
->left
, rc
->top
);
4620 int x
, y
, left
, right
, det
;
4624 case GRADIENT_FILL_RECT_H
:
4625 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4627 DWORD val
= gradient_rgb_24( v
, rc
->left
+ x
- v
[0].x
, v
[1].x
- v
[0].x
);
4629 ptr
[x
* 3 + 1] = val
>> 8;
4630 ptr
[x
* 3 + 2] = val
>> 16;
4633 for (y
= rc
->top
+ 1; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4634 memcpy( ptr
+ dib
->stride
, ptr
, (rc
->right
- rc
->left
) * 3 );
4637 case GRADIENT_FILL_RECT_V
:
4638 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4640 DWORD val
= gradient_rgb_24( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
);
4641 for (x
= 0; x
< rc
->right
- rc
->left
; x
++)
4644 ptr
[x
* 3 + 1] = val
>> 8;
4645 ptr
[x
* 3 + 2] = val
>> 16;
4650 case GRADIENT_FILL_TRIANGLE
:
4651 if (!(det
= triangle_det( v
))) return FALSE
;
4652 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4654 triangle_coords( v
, rc
, y
, &left
, &right
);
4655 for (x
= left
; x
< right
; x
++)
4657 DWORD val
= gradient_triangle_24( v
, x
, y
, det
);
4658 ptr
[(x
- rc
->left
) * 3] = val
;
4659 ptr
[(x
- rc
->left
) * 3 + 1] = val
>> 8;
4660 ptr
[(x
- rc
->left
) * 3 + 2] = val
>> 16;
4668 static BOOL
gradient_rect_555( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4670 WORD
*ptr
= get_pixel_ptr_16( dib
, rc
->left
, rc
->top
);
4671 int x
, y
, left
, right
, det
;
4675 case GRADIENT_FILL_RECT_H
:
4676 for (y
= rc
->top
; y
< min( rc
->top
+ 4, rc
->bottom
); y
++, ptr
+= dib
->stride
/ 2)
4677 for (x
= rc
->left
; x
< rc
->right
; x
++)
4678 ptr
[x
- rc
->left
] = gradient_rgb_555( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
4679 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4680 memcpy( ptr
, ptr
- dib
->stride
* 2, (rc
->right
- rc
->left
) * 2 );
4683 case GRADIENT_FILL_RECT_V
:
4684 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4687 for (x
= 0; x
< 4; x
++) values
[x
] = gradient_rgb_555( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
4688 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 4];
4692 case GRADIENT_FILL_TRIANGLE
:
4693 if (!(det
= triangle_det( v
))) return FALSE
;
4694 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4696 triangle_coords( v
, rc
, y
, &left
, &right
);
4697 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_555( v
, x
, y
, det
);
4704 static BOOL
gradient_rect_16( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4706 WORD
*ptr
= get_pixel_ptr_16( dib
, rc
->left
, rc
->top
);
4707 int x
, y
, left
, right
, det
;
4711 case GRADIENT_FILL_RECT_H
:
4712 for (y
= rc
->top
; y
< min( rc
->top
+ 4, rc
->bottom
); y
++, ptr
+= dib
->stride
/ 2)
4713 for (x
= rc
->left
; x
< rc
->right
; x
++)
4715 WORD val
= gradient_rgb_555( v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
4716 ptr
[x
- rc
->left
] = (put_field(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07), dib
->red_shift
, dib
->red_len
) |
4717 put_field(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07), dib
->green_shift
, dib
->green_len
) |
4718 put_field(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07), dib
->blue_shift
, dib
->blue_len
));
4720 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4721 memcpy( ptr
, ptr
- dib
->stride
* 2, (rc
->right
- rc
->left
) * 2 );
4724 case GRADIENT_FILL_RECT_V
:
4725 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4728 for (x
= 0; x
< 4; x
++)
4730 WORD val
= gradient_rgb_555( v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
4731 values
[x
] = (put_field(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07), dib
->red_shift
, dib
->red_len
) |
4732 put_field(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07), dib
->green_shift
, dib
->green_len
) |
4733 put_field(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07), dib
->blue_shift
, dib
->blue_len
));
4735 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 4];
4739 case GRADIENT_FILL_TRIANGLE
:
4740 if (!(det
= triangle_det( v
))) return FALSE
;
4741 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
/ 2)
4743 triangle_coords( v
, rc
, y
, &left
, &right
);
4744 for (x
= left
; x
< right
; x
++)
4746 WORD val
= gradient_triangle_555( v
, x
, y
, det
);
4747 ptr
[x
- rc
->left
] = (put_field(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07), dib
->red_shift
, dib
->red_len
) |
4748 put_field(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07), dib
->green_shift
, dib
->green_len
) |
4749 put_field(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07), dib
->blue_shift
, dib
->blue_len
));
4757 static BOOL
gradient_rect_8( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4759 BYTE
*ptr
= get_pixel_ptr_8( dib
, rc
->left
, rc
->top
);
4760 int x
, y
, left
, right
, det
;
4764 case GRADIENT_FILL_RECT_H
:
4765 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
4766 for (x
= rc
->left
; x
< rc
->right
; x
++)
4767 ptr
[x
- rc
->left
] = gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
4768 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4769 memcpy( ptr
, ptr
- dib
->stride
* 16, rc
->right
- rc
->left
);
4772 case GRADIENT_FILL_RECT_V
:
4773 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4776 for (x
= 0; x
< 16; x
++)
4777 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
4778 for (x
= rc
->left
; x
< rc
->right
; x
++) ptr
[x
- rc
->left
] = values
[x
% 16];
4782 case GRADIENT_FILL_TRIANGLE
:
4783 if (!(det
= triangle_det( v
))) return FALSE
;
4784 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4786 triangle_coords( v
, rc
, y
, &left
, &right
);
4787 for (x
= left
; x
< right
; x
++) ptr
[x
- rc
->left
] = gradient_triangle_8( dib
, v
, x
, y
, det
);
4794 static BOOL
gradient_rect_4( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4796 BYTE
*ptr
= get_pixel_ptr_4( dib
, rc
->left
, rc
->top
);
4797 int x
, y
, left
, right
, det
, pos
;
4801 case GRADIENT_FILL_RECT_H
:
4802 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
4804 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 1; x
< rc
->right
; x
++, pos
++)
4806 BYTE val
= gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
);
4808 ptr
[pos
/ 2] = val
| (ptr
[pos
/ 2] & 0xf0);
4810 ptr
[pos
/ 2] = (val
<< 4) | (ptr
[pos
/ 2] & 0x0f);
4813 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4816 pos
= (dib
->rect
.left
+ rc
->left
) & 1;
4819 ptr
[0] = (ptr
[-16 * dib
->stride
] & 0x0f) | (ptr
[0] & 0xf0);
4823 for (; x
< rc
->right
- 1; x
+= 2, pos
+= 2) ptr
[pos
/ 2] = ptr
[pos
/ 2 - 16 * dib
->stride
];
4825 ptr
[pos
/ 2] = (ptr
[pos
/ 2] & 0x0f) | (ptr
[pos
/ 2 - 16 * dib
->stride
] & 0xf0);
4829 case GRADIENT_FILL_RECT_V
:
4830 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4833 for (x
= 0; x
< 16; x
++)
4834 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
);
4835 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 1; x
< rc
->right
; x
++, pos
++)
4837 ptr
[pos
/ 2] = values
[x
% 16] | (ptr
[pos
/ 2] & 0xf0);
4839 ptr
[pos
/ 2] = (values
[x
% 16] << 4) | (ptr
[pos
/ 2] & 0x0f);
4843 case GRADIENT_FILL_TRIANGLE
:
4844 if (!(det
= triangle_det( v
))) return FALSE
;
4845 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4847 triangle_coords( v
, rc
, y
, &left
, &right
);
4848 for (x
= left
, pos
= left
- rc
->left
+ ((dib
->rect
.left
+ rc
->left
) & 1); x
< right
; x
++, pos
++)
4850 BYTE val
= gradient_triangle_8( dib
, v
, x
, y
, det
);
4852 ptr
[pos
/ 2] = val
| (ptr
[pos
/ 2] & 0xf0);
4854 ptr
[pos
/ 2] = (val
<< 4) | (ptr
[pos
/ 2] & 0x0f);
4862 static BOOL
gradient_rect_1( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4864 BYTE
*ptr
= get_pixel_ptr_1( dib
, rc
->left
, rc
->top
);
4865 int x
, y
, left
, right
, det
, pos
;
4869 case GRADIENT_FILL_RECT_H
:
4870 for (y
= rc
->top
; y
< min( rc
->top
+ 16, rc
->bottom
); y
++, ptr
+= dib
->stride
)
4872 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
4874 BYTE val
= gradient_rgb_8( dib
, v
, x
- v
[0].x
, v
[1].x
- v
[0].x
, x
, y
) ? 0xff : 0;
4875 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) | (val
& pixel_masks_1
[pos
% 8]);
4878 for ( ; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4879 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
4880 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
4881 (ptr
[pos
/ 8 - 16 * dib
->stride
] & pixel_masks_1
[pos
% 8]);
4884 case GRADIENT_FILL_RECT_V
:
4885 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4888 for (x
= 0; x
< 16; x
++)
4889 values
[x
] = gradient_rgb_8( dib
, v
, y
- v
[0].y
, v
[1].y
- v
[0].y
, x
, y
) ? 0xff : 0;
4890 for (x
= rc
->left
, pos
= (dib
->rect
.left
+ rc
->left
) & 7; x
< rc
->right
; x
++, pos
++)
4891 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
4892 (values
[x
% 16] & pixel_masks_1
[pos
% 8]);
4896 case GRADIENT_FILL_TRIANGLE
:
4897 if (!(det
= triangle_det( v
))) return FALSE
;
4898 for (y
= rc
->top
; y
< rc
->bottom
; y
++, ptr
+= dib
->stride
)
4900 triangle_coords( v
, rc
, y
, &left
, &right
);
4901 for (x
= left
, pos
= left
- rc
->left
+ ((dib
->rect
.left
+ rc
->left
) & 7); x
< right
; x
++, pos
++)
4903 BYTE val
= gradient_triangle_8( dib
, v
, x
, y
, det
) ? 0xff : 0;
4904 ptr
[pos
/ 8] = (ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) | (val
& pixel_masks_1
[pos
% 8]);
4912 static BOOL
gradient_rect_null( const dib_info
*dib
, const RECT
*rc
, const TRIVERTEX
*v
, int mode
)
4917 static inline BYTE
aa_color( BYTE dst
, BYTE text
, BYTE min_comp
, BYTE max_comp
)
4919 if (dst
== text
) return dst
;
4923 DWORD diff
= dst
- text
;
4924 DWORD range
= max_comp
- text
;
4925 dst
= text
+ (diff
* range
) / (0xff - text
);
4930 DWORD diff
= text
- dst
;
4931 DWORD range
= text
- min_comp
;
4932 dst
= text
- (diff
* range
) / text
;
4937 static inline DWORD
aa_rgb( BYTE r_dst
, BYTE g_dst
, BYTE b_dst
, DWORD text
, const struct intensity_range
*range
)
4939 return (aa_color( b_dst
, text
, range
->b_min
, range
->b_max
) |
4940 aa_color( g_dst
, text
>> 8, range
->g_min
, range
->g_max
) << 8 |
4941 aa_color( r_dst
, text
>> 16, range
->r_min
, range
->r_max
) << 16);
4944 static void draw_glyph_8888( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4945 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4947 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
4948 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4951 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4953 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4955 if (glyph_ptr
[x
] <= 1) continue;
4956 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4957 dst_ptr
[x
] = aa_rgb( dst_ptr
[x
] >> 16, dst_ptr
[x
] >> 8, dst_ptr
[x
], text_pixel
, ranges
+ glyph_ptr
[x
] );
4959 dst_ptr
+= dib
->stride
/ 4;
4960 glyph_ptr
+= glyph
->stride
;
4964 static void draw_glyph_32( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4965 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4967 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
4968 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
4972 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
4973 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
4974 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
4976 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
4978 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
4980 if (glyph_ptr
[x
] <= 1) continue;
4981 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
4982 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
4983 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
4984 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
4985 text
, ranges
+ glyph_ptr
[x
] );
4986 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
4987 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
4988 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
4990 dst_ptr
+= dib
->stride
/ 4;
4991 glyph_ptr
+= glyph
->stride
;
4995 static void draw_glyph_24( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
4996 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
4998 BYTE
*dst_ptr
= get_pixel_ptr_24( dib
, rect
->left
, rect
->top
);
4999 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
5003 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
5005 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
5007 if (glyph_ptr
[x
] <= 1) continue;
5008 if (glyph_ptr
[x
] >= 16)
5011 val
= aa_rgb( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
5012 text_pixel
, ranges
+ glyph_ptr
[x
] );
5013 dst_ptr
[x
* 3] = val
;
5014 dst_ptr
[x
* 3 + 1] = val
>> 8;
5015 dst_ptr
[x
* 3 + 2] = val
>> 16;
5017 dst_ptr
+= dib
->stride
;
5018 glyph_ptr
+= glyph
->stride
;
5022 static void draw_glyph_555( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
5023 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
5025 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
5026 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
5030 text
= ((text_pixel
<< 9) & 0xf80000) | ((text_pixel
<< 4) & 0x070000) |
5031 ((text_pixel
<< 6) & 0x00f800) | ((text_pixel
<< 1) & 0x000700) |
5032 ((text_pixel
<< 3) & 0x0000f8) | ((text_pixel
>> 2) & 0x000007);
5034 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
5036 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
5038 if (glyph_ptr
[x
] <= 1) continue;
5039 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
5040 val
= aa_rgb( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
5041 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
5042 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
5043 text
, ranges
+ glyph_ptr
[x
] );
5044 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
5046 dst_ptr
+= dib
->stride
/ 2;
5047 glyph_ptr
+= glyph
->stride
;
5051 static void draw_glyph_16( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
5052 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
5054 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
5055 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
5059 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
5060 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
5061 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
5063 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
5065 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
5067 if (glyph_ptr
[x
] <= 1) continue;
5068 if (glyph_ptr
[x
] >= 16) { dst_ptr
[x
] = text_pixel
; continue; }
5069 val
= aa_rgb( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
5070 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
5071 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
5072 text
, ranges
+ glyph_ptr
[x
] );
5073 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
5074 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
5075 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
5077 dst_ptr
+= dib
->stride
/ 2;
5078 glyph_ptr
+= glyph
->stride
;
5082 static void draw_glyph_8( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
5083 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
5085 BYTE
*dst_ptr
= get_pixel_ptr_8( dib
, rect
->left
, rect
->top
);
5086 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
5089 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
5091 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
5093 /* no antialiasing, glyph should only contain 0 or 16. */
5094 if (glyph_ptr
[x
] >= 16)
5095 dst_ptr
[x
] = text_pixel
;
5097 dst_ptr
+= dib
->stride
;
5098 glyph_ptr
+= glyph
->stride
;
5102 static void draw_glyph_4( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
5103 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
5105 BYTE
*dst_ptr
= get_pixel_ptr_4( dib
, rect
->left
, rect
->top
);
5106 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
5109 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
5111 for (x
= 0, pos
= (dib
->rect
.left
+ rect
->left
) & 1; x
< rect
->right
- rect
->left
; x
++, pos
++)
5113 /* no antialiasing, glyph should only contain 0 or 16. */
5114 if (glyph_ptr
[x
] >= 16)
5117 dst_ptr
[pos
/ 2] = text_pixel
| (dst_ptr
[pos
/ 2] & 0xf0);
5119 dst_ptr
[pos
/ 2] = (text_pixel
<< 4) | (dst_ptr
[pos
/ 2] & 0x0f);
5122 dst_ptr
+= dib
->stride
;
5123 glyph_ptr
+= glyph
->stride
;
5127 static void draw_glyph_1( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
5128 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
5130 BYTE
*dst_ptr
= get_pixel_ptr_1( dib
, rect
->left
, rect
->top
);
5131 const BYTE
*glyph_ptr
= get_pixel_ptr_8( glyph
, origin
->x
, origin
->y
);
5133 BYTE text
= (text_pixel
& 1) ? 0xff : 0;
5135 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
5137 for (x
= 0, pos
= (dib
->rect
.left
+ rect
->left
) & 7; x
< rect
->right
- rect
->left
; x
++, pos
++)
5139 /* no antialiasing, glyph should only contain 0 or 16. */
5140 if (glyph_ptr
[x
] >= 16)
5141 dst_ptr
[pos
/ 8] = (dst_ptr
[pos
/ 8] & ~pixel_masks_1
[pos
% 8]) |
5142 (text
& pixel_masks_1
[pos
% 8]);
5144 dst_ptr
+= dib
->stride
;
5145 glyph_ptr
+= glyph
->stride
;
5149 static void draw_glyph_null( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
5150 const POINT
*origin
, DWORD text_pixel
, const struct intensity_range
*ranges
)
5155 static inline DWORD
blend_subpixel( BYTE r
, BYTE g
, BYTE b
, DWORD text
, DWORD alpha
)
5157 return blend_color( r
, text
>> 16, (BYTE
)(alpha
>> 16) ) << 16 |
5158 blend_color( g
, text
>> 8, (BYTE
)(alpha
>> 8) ) << 8 |
5159 blend_color( b
, text
, (BYTE
) alpha
);
5162 static void draw_subpixel_glyph_8888( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
5163 const POINT
*origin
, DWORD text_pixel
)
5165 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
5166 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
5169 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
5171 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
5173 if (glyph_ptr
[x
] == 0) continue;
5174 dst_ptr
[x
] = blend_subpixel( dst_ptr
[x
] >> 16, dst_ptr
[x
] >> 8, dst_ptr
[x
], text_pixel
, glyph_ptr
[x
] );
5176 dst_ptr
+= dib
->stride
/ 4;
5177 glyph_ptr
+= glyph
->stride
/ 4;
5181 static void draw_subpixel_glyph_32( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
5182 const POINT
*origin
, DWORD text_pixel
)
5184 DWORD
*dst_ptr
= get_pixel_ptr_32( dib
, rect
->left
, rect
->top
);
5185 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
5189 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
5190 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
5191 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
5193 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
5195 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
5197 if (glyph_ptr
[x
] == 0) continue;
5198 val
= blend_subpixel( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
5199 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
5200 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
5201 text
, glyph_ptr
[x
] );
5202 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
5203 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
5204 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
5206 dst_ptr
+= dib
->stride
/ 4;
5207 glyph_ptr
+= glyph
->stride
/ 4;
5211 static void draw_subpixel_glyph_24( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
5212 const POINT
*origin
, DWORD text_pixel
)
5214 BYTE
*dst_ptr
= get_pixel_ptr_24( dib
, rect
->left
, rect
->top
);
5215 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
5219 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
5221 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
5223 if (glyph_ptr
[x
] == 0) continue;
5224 val
= blend_subpixel( dst_ptr
[x
* 3 + 2], dst_ptr
[x
* 3 + 1], dst_ptr
[x
* 3],
5225 text_pixel
, glyph_ptr
[x
] );
5226 dst_ptr
[x
* 3] = val
;
5227 dst_ptr
[x
* 3 + 1] = val
>> 8;
5228 dst_ptr
[x
* 3 + 2] = val
>> 16;
5230 dst_ptr
+= dib
->stride
;
5231 glyph_ptr
+= glyph
->stride
/ 4;
5235 static void draw_subpixel_glyph_555( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
5236 const POINT
*origin
, DWORD text_pixel
)
5238 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
5239 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
5243 text
= ((text_pixel
<< 9) & 0xf80000) | ((text_pixel
<< 4) & 0x070000) |
5244 ((text_pixel
<< 6) & 0x00f800) | ((text_pixel
<< 1) & 0x000700) |
5245 ((text_pixel
<< 3) & 0x0000f8) | ((text_pixel
>> 2) & 0x000007);
5247 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
5249 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
5251 if (glyph_ptr
[x
] == 0) continue;
5252 val
= blend_subpixel( ((dst_ptr
[x
] >> 7) & 0xf8) | ((dst_ptr
[x
] >> 12) & 0x07),
5253 ((dst_ptr
[x
] >> 2) & 0xf8) | ((dst_ptr
[x
] >> 7) & 0x07),
5254 ((dst_ptr
[x
] << 3) & 0xf8) | ((dst_ptr
[x
] >> 2) & 0x07),
5255 text
, glyph_ptr
[x
] );
5256 dst_ptr
[x
] = ((val
>> 9) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 3) & 0x001f);
5258 dst_ptr
+= dib
->stride
/ 2;
5259 glyph_ptr
+= glyph
->stride
/ 4;
5263 static void draw_subpixel_glyph_16( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
5264 const POINT
*origin
, DWORD text_pixel
)
5266 WORD
*dst_ptr
= get_pixel_ptr_16( dib
, rect
->left
, rect
->top
);
5267 const DWORD
*glyph_ptr
= get_pixel_ptr_32( glyph
, origin
->x
, origin
->y
);
5271 text
= get_field( text_pixel
, dib
->red_shift
, dib
->red_len
) << 16 |
5272 get_field( text_pixel
, dib
->green_shift
, dib
->green_len
) << 8 |
5273 get_field( text_pixel
, dib
->blue_shift
, dib
->blue_len
);
5275 for (y
= rect
->top
; y
< rect
->bottom
; y
++)
5277 for (x
= 0; x
< rect
->right
- rect
->left
; x
++)
5279 if (glyph_ptr
[x
] == 0) continue;
5280 val
= blend_subpixel( get_field(dst_ptr
[x
], dib
->red_shift
, dib
->red_len
),
5281 get_field(dst_ptr
[x
], dib
->green_shift
, dib
->green_len
),
5282 get_field(dst_ptr
[x
], dib
->blue_shift
, dib
->blue_len
),
5283 text
, glyph_ptr
[x
] );
5284 dst_ptr
[x
] = (put_field( val
>> 16, dib
->red_shift
, dib
->red_len
) |
5285 put_field( val
>> 8, dib
->green_shift
, dib
->green_len
) |
5286 put_field( val
, dib
->blue_shift
, dib
->blue_len
));
5288 dst_ptr
+= dib
->stride
/ 2;
5289 glyph_ptr
+= glyph
->stride
/ 4;
5293 static void draw_subpixel_glyph_null( const dib_info
*dib
, const RECT
*rect
, const dib_info
*glyph
,
5294 const POINT
*origin
, DWORD text_pixel
)
5299 static void create_rop_masks_32(const dib_info
*dib
, const BYTE
*hatch_ptr
,
5300 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
5302 DWORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
5305 /* masks are always 8x8 */
5306 assert( dib
->width
== 8 );
5307 assert( dib
->height
== 8 );
5309 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
5311 for(x
= 0; x
< 8; x
++)
5313 if(*hatch_ptr
& pixel_masks_1
[x
])
5315 and_bits
[x
] = fg
->and;
5316 xor_bits
[x
] = fg
->xor;
5320 and_bits
[x
] = bg
->and;
5321 xor_bits
[x
] = bg
->xor;
5324 and_bits
+= dib
->stride
/ 4;
5325 xor_bits
+= dib
->stride
/ 4;
5329 static void create_rop_masks_24(const dib_info
*dib
, const BYTE
*hatch_ptr
,
5330 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
5332 DWORD mask_start
= 0, mask_offset
;
5333 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
5336 /* masks are always 8x8 */
5337 assert( dib
->width
== 8 );
5338 assert( dib
->height
== 8 );
5340 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
5342 mask_offset
= mask_start
;
5343 for(x
= 0; x
< 8; x
++)
5345 if(*hatch_ptr
& pixel_masks_1
[x
])
5347 and_bits
[mask_offset
] = fg
->and & 0xff;
5348 xor_bits
[mask_offset
++] = fg
->xor & 0xff;
5349 and_bits
[mask_offset
] = (fg
->and >> 8) & 0xff;
5350 xor_bits
[mask_offset
++] = (fg
->xor >> 8) & 0xff;
5351 and_bits
[mask_offset
] = (fg
->and >> 16) & 0xff;
5352 xor_bits
[mask_offset
++] = (fg
->xor >> 16) & 0xff;
5356 and_bits
[mask_offset
] = bg
->and & 0xff;
5357 xor_bits
[mask_offset
++] = bg
->xor & 0xff;
5358 and_bits
[mask_offset
] = (bg
->and >> 8) & 0xff;
5359 xor_bits
[mask_offset
++] = (bg
->xor >> 8) & 0xff;
5360 and_bits
[mask_offset
] = (bg
->and >> 16) & 0xff;
5361 xor_bits
[mask_offset
++] = (bg
->xor >> 16) & 0xff;
5364 mask_start
+= dib
->stride
;
5368 static void create_rop_masks_16(const dib_info
*dib
, const BYTE
*hatch_ptr
,
5369 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
5371 WORD
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
5374 /* masks are always 8x8 */
5375 assert( dib
->width
== 8 );
5376 assert( dib
->height
== 8 );
5378 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
5380 for(x
= 0; x
< 8; x
++)
5382 if(*hatch_ptr
& pixel_masks_1
[x
])
5384 and_bits
[x
] = fg
->and;
5385 xor_bits
[x
] = fg
->xor;
5389 and_bits
[x
] = bg
->and;
5390 xor_bits
[x
] = bg
->xor;
5393 and_bits
+= dib
->stride
/ 2;
5394 xor_bits
+= dib
->stride
/ 2;
5398 static void create_rop_masks_8(const dib_info
*dib
, const BYTE
*hatch_ptr
,
5399 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
5401 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
5404 /* masks are always 8x8 */
5405 assert( dib
->width
== 8 );
5406 assert( dib
->height
== 8 );
5408 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
5410 for(x
= 0; x
< 8; x
++)
5412 if(*hatch_ptr
& pixel_masks_1
[x
])
5414 and_bits
[x
] = fg
->and;
5415 xor_bits
[x
] = fg
->xor;
5419 and_bits
[x
] = bg
->and;
5420 xor_bits
[x
] = bg
->xor;
5423 and_bits
+= dib
->stride
;
5424 xor_bits
+= dib
->stride
;
5428 static void create_rop_masks_4(const dib_info
*dib
, const BYTE
*hatch_ptr
,
5429 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
5432 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
5433 const rop_mask
*rop_mask
;
5436 /* masks are always 8x8 */
5437 assert( dib
->width
== 8 );
5438 assert( dib
->height
== 8 );
5440 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
5442 for(x
= mask_offset
= 0; x
< 8; x
++)
5444 if(*hatch_ptr
& pixel_masks_1
[x
])
5451 and_bits
[mask_offset
] |= (rop_mask
->and & 0x0f);
5452 xor_bits
[mask_offset
] |= (rop_mask
->xor & 0x0f);
5457 and_bits
[mask_offset
] = (rop_mask
->and << 4) & 0xf0;
5458 xor_bits
[mask_offset
] = (rop_mask
->xor << 4) & 0xf0;
5461 and_bits
+= dib
->stride
;
5462 xor_bits
+= dib
->stride
;
5466 static void create_rop_masks_1(const dib_info
*dib
, const BYTE
*hatch_ptr
,
5467 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
5469 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
5473 /* masks are always 8x8 */
5474 assert( dib
->width
== 8 );
5475 assert( dib
->height
== 8 );
5477 for(y
= 0; y
< 8; y
++, hatch_ptr
++)
5479 *and_bits
= *xor_bits
= 0;
5480 for(x
= 0; x
< 8; x
++)
5482 if(*hatch_ptr
& pixel_masks_1
[x
])
5484 rop_mask
.and = (fg
->and & 1) ? 0xff : 0;
5485 rop_mask
.xor = (fg
->xor & 1) ? 0xff : 0;
5489 rop_mask
.and = (bg
->and & 1) ? 0xff : 0;
5490 rop_mask
.xor = (bg
->xor & 1) ? 0xff : 0;
5492 *and_bits
|= (rop_mask
.and & pixel_masks_1
[x
]);
5493 *xor_bits
|= (rop_mask
.xor & pixel_masks_1
[x
]);
5495 and_bits
+= dib
->stride
;
5496 xor_bits
+= dib
->stride
;
5500 static void create_rop_masks_null(const dib_info
*dib
, const BYTE
*hatch_ptr
,
5501 const rop_mask
*fg
, const rop_mask
*bg
, rop_mask_bits
*bits
)
5505 static void create_dither_masks_8(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
5507 /* mapping between RGB triples and the default color table */
5508 static const BYTE mapping
[27] =
5510 0, /* 000000 -> 000000 */
5511 4, /* 00007f -> 000080 */
5512 252, /* 0000ff -> 0000ff */
5513 2, /* 007f00 -> 008000 */
5514 6, /* 007f7f -> 008080 */
5515 224, /* 007fff -> 0080c0 */
5516 250, /* 00ff00 -> 00ff00 */
5517 184, /* 00ff7f -> 00e080 */
5518 254, /* 00ffff -> 00ffff */
5519 1, /* 7f0000 -> 800000 */
5520 5, /* 7f007f -> 800080 */
5521 196, /* 7f00ff -> 8000c0 */
5522 3, /* 7f7f00 -> 808000 */
5523 248, /* 7f7f7f -> 808080 */
5524 228, /* 7f7fff -> 8080c0 */
5525 60, /* 7fff00 -> 80e000 */
5526 188, /* 7fff7f -> 80e080 */
5527 244, /* 7fffff -> 80c0c0 */
5528 249, /* ff0000 -> ff0000 */
5529 135, /* ff007f -> e00080 */
5530 253, /* ff00ff -> ff00ff */
5531 39, /* ff7f00 -> e08000 */
5532 167, /* ff7f7f -> e08080 */
5533 231, /* ff7fff -> e080c0 */
5534 251, /* ffff00 -> ffff00 */
5535 191, /* ffff7f -> e0e080 */
5536 255 /* ffffff -> ffffff */
5539 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
5540 struct rop_codes codes
;
5543 /* masks are always 8x8 */
5544 assert( dib
->width
== 8 );
5545 assert( dib
->height
== 8 );
5547 get_rop_codes( rop2
, &codes
);
5549 for (y
= 0; y
< 8; y
++)
5551 for (x
= 0; x
< 8; x
++)
5553 DWORD r
= ((GetRValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
5554 DWORD g
= ((GetGValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
5555 DWORD b
= ((GetBValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
5556 DWORD pixel
= mapping
[r
* 9 + g
* 3 + b
];
5557 and_bits
[x
] = (pixel
& codes
.a1
) ^ codes
.a2
;
5558 xor_bits
[x
] = (pixel
& codes
.x1
) ^ codes
.x2
;
5560 and_bits
+= dib
->stride
;
5561 xor_bits
+= dib
->stride
;
5565 static void create_dither_masks_4(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
5567 /* mapping between RGB triples and the default color table */
5568 static const BYTE mapping
[27] =
5570 0, /* 000000 -> 000000 */
5571 4, /* 00007f -> 000080 */
5572 12, /* 0000ff -> 0000ff */
5573 2, /* 007f00 -> 008000 */
5574 6, /* 007f7f -> 008080 */
5575 6, /* 007fff -> 008080 */
5576 10, /* 00ff00 -> 00ff00 */
5577 6, /* 00ff7f -> 008080 */
5578 14, /* 00ffff -> 00ffff */
5579 1, /* 7f0000 -> 800000 */
5580 5, /* 7f007f -> 800080 */
5581 5, /* 7f00ff -> 800080 */
5582 3, /* 7f7f00 -> 808000 */
5583 7, /* 7f7f7f -> 808080 */
5584 8, /* 7f7fff -> c0c0c0 */
5585 3, /* 7fff00 -> 808000 */
5586 8, /* 7fff7f -> c0c0c0 */
5587 8, /* 7fffff -> c0c0c0 */
5588 9, /* ff0000 -> ff0000 */
5589 5, /* ff007f -> 800080 */
5590 13, /* ff00ff -> ff00ff */
5591 3, /* ff7f00 -> 808000 */
5592 8, /* ff7f7f -> c0c0c0 */
5593 8, /* ff7fff -> c0c0c0 */
5594 11, /* ffff00 -> ffff00 */
5595 8, /* ffff7f -> c0c0c0 */
5596 15 /* ffffff -> ffffff */
5599 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
5600 struct rop_codes codes
;
5603 /* masks are always 8x8 */
5604 assert( dib
->width
== 8 );
5605 assert( dib
->height
== 8 );
5607 get_rop_codes( rop2
, &codes
);
5609 for (y
= 0; y
< 8; y
++)
5611 for (x
= 0; x
< 8; x
++)
5613 DWORD r
= ((GetRValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
5614 DWORD g
= ((GetGValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
5615 DWORD b
= ((GetBValue(color
) + 1) / 2 + bayer_8x8
[y
][x
]) / 64;
5616 DWORD pixel
= mapping
[r
* 9 + g
* 3 + b
];
5619 and_bits
[x
/ 2] |= (pixel
& codes
.a1
) ^ codes
.a2
;
5620 xor_bits
[x
/ 2] |= (pixel
& codes
.x1
) ^ codes
.x2
;
5624 and_bits
[x
/ 2] = ((pixel
& codes
.a1
) ^ codes
.a2
) << 4;
5625 xor_bits
[x
/ 2] = ((pixel
& codes
.x1
) ^ codes
.x2
) << 4;
5628 and_bits
+= dib
->stride
;
5629 xor_bits
+= dib
->stride
;
5633 static void create_dither_masks_1(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
5635 BYTE
*and_bits
= bits
->and, *xor_bits
= bits
->xor;
5636 struct rop_codes codes
;
5638 int x
, y
, grey
= (30 * GetRValue(color
) + 59 * GetGValue(color
) + 11 * GetBValue(color
) + 200) / 400;
5640 /* masks are always 8x8 */
5641 assert( dib
->width
== 8 );
5642 assert( dib
->height
== 8 );
5644 get_rop_codes( rop2
, &codes
);
5646 for (y
= 0; y
< 8; y
++)
5648 *and_bits
= *xor_bits
= 0;
5649 for (x
= 0; x
< 8; x
++)
5651 if (grey
+ bayer_8x8
[y
][x
] > 63)
5653 rop_mask
.and = (0xff & codes
.a1
) ^ codes
.a2
;
5654 rop_mask
.xor = (0xff & codes
.x1
) ^ codes
.x2
;
5658 rop_mask
.and = (0x00 & codes
.a1
) ^ codes
.a2
;
5659 rop_mask
.xor = (0x00 & codes
.x1
) ^ codes
.x2
;
5661 *and_bits
|= (rop_mask
.and & pixel_masks_1
[x
]);
5662 *xor_bits
|= (rop_mask
.xor & pixel_masks_1
[x
]);
5664 and_bits
+= dib
->stride
;
5665 xor_bits
+= dib
->stride
;
5669 static void create_dither_masks_null(const dib_info
*dib
, int rop2
, COLORREF color
, rop_mask_bits
*bits
)
5673 static inline void rop_codes_from_stretch_mode( int mode
, struct rop_codes
*codes
)
5678 case STRETCH_DELETESCANS
:
5679 get_rop_codes( R2_COPYPEN
, codes
);
5681 case STRETCH_ORSCANS
:
5682 get_rop_codes( R2_MERGEPEN
, codes
);
5684 case STRETCH_ANDSCANS
:
5685 get_rop_codes( R2_MASKPEN
, codes
);
5691 static void stretch_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
5692 const dib_info
*src_dib
, const POINT
*src_start
,
5693 const struct stretch_params
*params
, int mode
,
5696 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
5697 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
5698 int err
= params
->err_start
;
5701 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
5703 for (width
= params
->length
; width
; width
--)
5705 *dst_ptr
= *src_ptr
;
5706 dst_ptr
+= params
->dst_inc
;
5709 src_ptr
+= params
->src_inc
;
5710 err
+= params
->err_add_1
;
5712 else err
+= params
->err_add_2
;
5717 struct rop_codes codes
;
5719 rop_codes_from_stretch_mode( mode
, &codes
);
5720 for (width
= params
->length
; width
; width
--)
5722 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
5723 dst_ptr
+= params
->dst_inc
;
5726 src_ptr
+= params
->src_inc
;
5727 err
+= params
->err_add_1
;
5729 else err
+= params
->err_add_2
;
5734 static void stretch_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
5735 const dib_info
*src_dib
, const POINT
*src_start
,
5736 const struct stretch_params
*params
, int mode
,
5739 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
5740 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
5741 int err
= params
->err_start
;
5744 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
5746 for (width
= params
->length
; width
; width
--)
5748 dst_ptr
[0] = src_ptr
[0];
5749 dst_ptr
[1] = src_ptr
[1];
5750 dst_ptr
[2] = src_ptr
[2];
5751 dst_ptr
+= 3 * params
->dst_inc
;
5754 src_ptr
+= 3 * params
->src_inc
;
5755 err
+= params
->err_add_1
;
5757 else err
+= params
->err_add_2
;
5762 struct rop_codes codes
;
5764 rop_codes_from_stretch_mode( mode
, &codes
);
5765 for (width
= params
->length
; width
; width
--)
5767 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
5768 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
5769 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
5770 dst_ptr
+= 3 * params
->dst_inc
;
5773 src_ptr
+= 3 * params
->src_inc
;
5774 err
+= params
->err_add_1
;
5776 else err
+= params
->err_add_2
;
5781 static void stretch_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
5782 const dib_info
*src_dib
, const POINT
*src_start
,
5783 const struct stretch_params
*params
, int mode
,
5786 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
5787 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
5788 int err
= params
->err_start
;
5791 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
5793 for (width
= params
->length
; width
; width
--)
5795 *dst_ptr
= *src_ptr
;
5796 dst_ptr
+= params
->dst_inc
;
5799 src_ptr
+= params
->src_inc
;
5800 err
+= params
->err_add_1
;
5802 else err
+= params
->err_add_2
;
5807 struct rop_codes codes
;
5809 rop_codes_from_stretch_mode( mode
, &codes
);
5810 for (width
= params
->length
; width
; width
--)
5812 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
5813 dst_ptr
+= params
->dst_inc
;
5816 src_ptr
+= params
->src_inc
;
5817 err
+= params
->err_add_1
;
5819 else err
+= params
->err_add_2
;
5824 static void stretch_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
5825 const dib_info
*src_dib
, const POINT
*src_start
,
5826 const struct stretch_params
*params
, int mode
,
5829 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
5830 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
5831 int err
= params
->err_start
;
5834 if (mode
== STRETCH_DELETESCANS
|| !keep_dst
)
5836 for (width
= params
->length
; width
; width
--)
5838 *dst_ptr
= *src_ptr
;
5839 dst_ptr
+= params
->dst_inc
;
5842 src_ptr
+= params
->src_inc
;
5843 err
+= params
->err_add_1
;
5845 else err
+= params
->err_add_2
;
5850 struct rop_codes codes
;
5852 rop_codes_from_stretch_mode( mode
, &codes
);
5853 for (width
= params
->length
; width
; width
--)
5855 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
5856 dst_ptr
+= params
->dst_inc
;
5859 src_ptr
+= params
->src_inc
;
5860 err
+= params
->err_add_1
;
5862 else err
+= params
->err_add_2
;
5867 static void stretch_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
5868 const dib_info
*src_dib
, const POINT
*src_start
,
5869 const struct stretch_params
*params
, int mode
,
5872 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
5873 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
5874 int err
= params
->err_start
;
5875 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
5876 struct rop_codes codes
;
5879 if (!keep_dst
) mode
= STRETCH_DELETESCANS
;
5880 rop_codes_from_stretch_mode( mode
, &codes
);
5881 for (width
= params
->length
; width
; width
--)
5883 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
5884 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
5886 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
5888 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
5889 dst_ptr
+= params
->dst_inc
;
5890 dst_x
+= params
->dst_inc
;
5894 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
5895 src_ptr
+= params
->src_inc
;
5896 src_x
+= params
->src_inc
;
5897 err
+= params
->err_add_1
;
5899 else err
+= params
->err_add_2
;
5903 static void stretch_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
5904 const dib_info
*src_dib
, const POINT
*src_start
,
5905 const struct stretch_params
*params
, int mode
,
5908 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
5909 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
5910 int err
= params
->err_start
;
5911 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
5912 struct rop_codes codes
;
5915 if (!keep_dst
) mode
= STRETCH_DELETESCANS
;
5916 rop_codes_from_stretch_mode( mode
, &codes
);
5917 for (width
= params
->length
; width
; width
--)
5919 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
5920 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
5922 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
5923 dst_ptr
+= params
->dst_inc
;
5924 dst_x
+= params
->dst_inc
;
5928 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
5929 src_ptr
+= params
->src_inc
;
5930 src_x
+= params
->src_inc
;
5931 err
+= params
->err_add_1
;
5933 else err
+= params
->err_add_2
;
5937 static void stretch_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
5938 const dib_info
*src_dib
, const POINT
*src_start
,
5939 const struct stretch_params
*params
, int mode
,
5942 FIXME("bit count %d\n", dst_dib
->bit_count
);
5946 static void shrink_row_32(const dib_info
*dst_dib
, const POINT
*dst_start
,
5947 const dib_info
*src_dib
, const POINT
*src_start
,
5948 const struct stretch_params
*params
, int mode
,
5951 DWORD
*dst_ptr
= get_pixel_ptr_32( dst_dib
, dst_start
->x
, dst_start
->y
);
5952 DWORD
*src_ptr
= get_pixel_ptr_32( src_dib
, src_start
->x
, src_start
->y
);
5953 int err
= params
->err_start
;
5956 if (mode
== STRETCH_DELETESCANS
)
5958 for (width
= params
->length
; width
; width
--)
5960 *dst_ptr
= *src_ptr
;
5961 src_ptr
+= params
->src_inc
;
5964 dst_ptr
+= params
->dst_inc
;
5965 err
+= params
->err_add_1
;
5967 else err
+= params
->err_add_2
;
5972 struct rop_codes codes
;
5973 DWORD init_val
= (mode
== STRETCH_ANDSCANS
) ? ~0u : 0u;
5974 BOOL new_pix
= TRUE
;
5976 rop_codes_from_stretch_mode( mode
, &codes
);
5977 for (width
= params
->length
; width
; width
--)
5979 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
5980 do_rop_codes_32( dst_ptr
, *src_ptr
, &codes
);
5982 src_ptr
+= params
->src_inc
;
5985 dst_ptr
+= params
->dst_inc
;
5987 err
+= params
->err_add_1
;
5989 else err
+= params
->err_add_2
;
5994 static void shrink_row_24(const dib_info
*dst_dib
, const POINT
*dst_start
,
5995 const dib_info
*src_dib
, const POINT
*src_start
,
5996 const struct stretch_params
*params
, int mode
,
5999 BYTE
*dst_ptr
= get_pixel_ptr_24( dst_dib
, dst_start
->x
, dst_start
->y
);
6000 BYTE
*src_ptr
= get_pixel_ptr_24( src_dib
, src_start
->x
, src_start
->y
);
6001 int err
= params
->err_start
;
6004 if (mode
== STRETCH_DELETESCANS
)
6006 for (width
= params
->length
; width
; width
--)
6008 dst_ptr
[0] = src_ptr
[0];
6009 dst_ptr
[1] = src_ptr
[1];
6010 dst_ptr
[2] = src_ptr
[2];
6011 src_ptr
+= 3 * params
->src_inc
;
6014 dst_ptr
+= 3 * params
->dst_inc
;
6015 err
+= params
->err_add_1
;
6017 else err
+= params
->err_add_2
;
6022 struct rop_codes codes
;
6023 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
6024 BOOL new_pix
= TRUE
;
6026 rop_codes_from_stretch_mode( mode
, &codes
);
6027 for (width
= params
->length
; width
; width
--)
6029 if (new_pix
&& !keep_dst
) memset( dst_ptr
, init_val
, 3 );
6030 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
6031 do_rop_codes_8( dst_ptr
+ 1, *(src_ptr
+ 1), &codes
);
6032 do_rop_codes_8( dst_ptr
+ 2, *(src_ptr
+ 2), &codes
);
6034 src_ptr
+= 3 * params
->src_inc
;
6037 dst_ptr
+= 3 * params
->dst_inc
;
6039 err
+= params
->err_add_1
;
6041 else err
+= params
->err_add_2
;
6046 static void shrink_row_16(const dib_info
*dst_dib
, const POINT
*dst_start
,
6047 const dib_info
*src_dib
, const POINT
*src_start
,
6048 const struct stretch_params
*params
, int mode
,
6051 WORD
*dst_ptr
= get_pixel_ptr_16( dst_dib
, dst_start
->x
, dst_start
->y
);
6052 WORD
*src_ptr
= get_pixel_ptr_16( src_dib
, src_start
->x
, src_start
->y
);
6053 int err
= params
->err_start
;
6056 if (mode
== STRETCH_DELETESCANS
)
6058 for (width
= params
->length
; width
; width
--)
6060 *dst_ptr
= *src_ptr
;
6061 src_ptr
+= params
->src_inc
;
6064 dst_ptr
+= params
->dst_inc
;
6065 err
+= params
->err_add_1
;
6067 else err
+= params
->err_add_2
;
6072 struct rop_codes codes
;
6073 WORD init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xffff : 0;
6074 BOOL new_pix
= TRUE
;
6076 rop_codes_from_stretch_mode( mode
, &codes
);
6077 for (width
= params
->length
; width
; width
--)
6079 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
6080 do_rop_codes_16( dst_ptr
, *src_ptr
, &codes
);
6082 src_ptr
+= params
->src_inc
;
6085 dst_ptr
+= params
->dst_inc
;
6087 err
+= params
->err_add_1
;
6089 else err
+= params
->err_add_2
;
6094 static void shrink_row_8(const dib_info
*dst_dib
, const POINT
*dst_start
,
6095 const dib_info
*src_dib
, const POINT
*src_start
,
6096 const struct stretch_params
*params
, int mode
,
6099 BYTE
*dst_ptr
= get_pixel_ptr_8( dst_dib
, dst_start
->x
, dst_start
->y
);
6100 BYTE
*src_ptr
= get_pixel_ptr_8( src_dib
, src_start
->x
, src_start
->y
);
6101 int err
= params
->err_start
;
6104 if (mode
== STRETCH_DELETESCANS
)
6106 for (width
= params
->length
; width
; width
--)
6108 *dst_ptr
= *src_ptr
;
6109 src_ptr
+= params
->src_inc
;
6112 dst_ptr
+= params
->dst_inc
;
6113 err
+= params
->err_add_1
;
6115 else err
+= params
->err_add_2
;
6120 struct rop_codes codes
;
6121 BYTE init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
6122 BOOL new_pix
= TRUE
;
6124 rop_codes_from_stretch_mode( mode
, &codes
);
6125 for (width
= params
->length
; width
; width
--)
6127 if (new_pix
&& !keep_dst
) *dst_ptr
= init_val
;
6128 do_rop_codes_8( dst_ptr
, *src_ptr
, &codes
);
6130 src_ptr
+= params
->src_inc
;
6133 dst_ptr
+= params
->dst_inc
;
6135 err
+= params
->err_add_1
;
6137 else err
+= params
->err_add_2
;
6142 static void shrink_row_4(const dib_info
*dst_dib
, const POINT
*dst_start
,
6143 const dib_info
*src_dib
, const POINT
*src_start
,
6144 const struct stretch_params
*params
, int mode
,
6147 BYTE
*dst_ptr
= get_pixel_ptr_4( dst_dib
, dst_start
->x
, dst_start
->y
);
6148 BYTE
*src_ptr
= get_pixel_ptr_4( src_dib
, src_start
->x
, src_start
->y
);
6149 int err
= params
->err_start
;
6150 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
6151 struct rop_codes codes
;
6152 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
6153 BOOL new_pix
= TRUE
;
6155 rop_codes_from_stretch_mode( mode
, &codes
);
6156 for (width
= params
->length
; width
; width
--)
6158 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, (dst_x
& 1) ? 0x0f : 0xf0 );
6160 if (src_x
& 1) src_val
= (*src_ptr
& 0x0f) | (*src_ptr
<< 4);
6161 else src_val
= (*src_ptr
& 0xf0) | (*src_ptr
>> 4);
6163 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, (dst_x
& 1) ? 0x0f : 0xf0 );
6166 if ((src_x
& ~1) != ((src_x
+ params
->src_inc
) & ~1))
6167 src_ptr
+= params
->src_inc
;
6168 src_x
+= params
->src_inc
;
6172 if ((dst_x
& ~1) != ((dst_x
+ params
->dst_inc
) & ~1))
6173 dst_ptr
+= params
->dst_inc
;
6174 dst_x
+= params
->dst_inc
;
6176 err
+= params
->err_add_1
;
6178 else err
+= params
->err_add_2
;
6182 static void shrink_row_1(const dib_info
*dst_dib
, const POINT
*dst_start
,
6183 const dib_info
*src_dib
, const POINT
*src_start
,
6184 const struct stretch_params
*params
, int mode
,
6187 BYTE
*dst_ptr
= get_pixel_ptr_1( dst_dib
, dst_start
->x
, dst_start
->y
);
6188 BYTE
*src_ptr
= get_pixel_ptr_1( src_dib
, src_start
->x
, src_start
->y
);
6189 int err
= params
->err_start
;
6190 int width
, dst_x
= dst_dib
->rect
.left
+ dst_start
->x
, src_x
= src_dib
->rect
.left
+ src_start
->x
;
6191 struct rop_codes codes
;
6192 BYTE src_val
, init_val
= (mode
== STRETCH_ANDSCANS
) ? 0xff : 0;
6193 BOOL new_pix
= TRUE
;
6195 rop_codes_from_stretch_mode( mode
, &codes
);
6196 for (width
= params
->length
; width
; width
--)
6198 if (new_pix
&& !keep_dst
) do_rop_mask_8( dst_ptr
, 0, init_val
, pixel_masks_1
[dst_x
% 8] );
6199 src_val
= *src_ptr
& pixel_masks_1
[src_x
% 8] ? 0xff : 0;
6200 do_rop_codes_mask_8( dst_ptr
, src_val
, &codes
, pixel_masks_1
[dst_x
% 8] );
6203 if ((src_x
& ~7) != ((src_x
+ params
->src_inc
) & ~7))
6204 src_ptr
+= params
->src_inc
;
6205 src_x
+= params
->src_inc
;
6209 if ((dst_x
& ~7) != ((dst_x
+ params
->dst_inc
) & ~7))
6210 dst_ptr
+= params
->dst_inc
;
6211 dst_x
+= params
->dst_inc
;
6213 err
+= params
->err_add_1
;
6215 else err
+= params
->err_add_2
;
6219 static void shrink_row_null(const dib_info
*dst_dib
, const POINT
*dst_start
,
6220 const dib_info
*src_dib
, const POINT
*src_start
,
6221 const struct stretch_params
*params
, int mode
,
6224 FIXME("bit count %d\n", dst_dib
->bit_count
);
6228 const primitive_funcs funcs_8888
=
6237 draw_subpixel_glyph_8888
,
6239 colorref_to_pixel_888
,
6240 pixel_to_colorref_888
,
6242 create_rop_masks_32
,
6243 create_dither_masks_null
,
6248 const primitive_funcs funcs_32
=
6257 draw_subpixel_glyph_32
,
6259 colorref_to_pixel_masks
,
6260 pixel_to_colorref_masks
,
6262 create_rop_masks_32
,
6263 create_dither_masks_null
,
6268 const primitive_funcs funcs_24
=
6277 draw_subpixel_glyph_24
,
6279 colorref_to_pixel_888
,
6280 pixel_to_colorref_888
,
6282 create_rop_masks_24
,
6283 create_dither_masks_null
,
6288 const primitive_funcs funcs_555
=
6297 draw_subpixel_glyph_555
,
6299 colorref_to_pixel_555
,
6300 pixel_to_colorref_555
,
6302 create_rop_masks_16
,
6303 create_dither_masks_null
,
6308 const primitive_funcs funcs_16
=
6317 draw_subpixel_glyph_16
,
6319 colorref_to_pixel_masks
,
6320 pixel_to_colorref_masks
,
6322 create_rop_masks_16
,
6323 create_dither_masks_null
,
6328 const primitive_funcs funcs_8
=
6337 draw_subpixel_glyph_null
,
6339 colorref_to_pixel_colortable
,
6340 pixel_to_colorref_colortable
,
6343 create_dither_masks_8
,
6348 const primitive_funcs funcs_4
=
6357 draw_subpixel_glyph_null
,
6359 colorref_to_pixel_colortable
,
6360 pixel_to_colorref_colortable
,
6363 create_dither_masks_4
,
6368 const primitive_funcs funcs_1
=
6377 draw_subpixel_glyph_null
,
6379 colorref_to_pixel_colortable
,
6380 pixel_to_colorref_colortable
,
6383 create_dither_masks_1
,
6388 const primitive_funcs funcs_null
=
6397 draw_subpixel_glyph_null
,
6399 colorref_to_pixel_null
,
6400 pixel_to_colorref_null
,
6402 create_rop_masks_null
,
6403 create_dither_masks_null
,