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_16x16[16][16] =
42 { 0, 128, 32, 160, 8, 136, 40, 168, 2, 130, 34, 162, 10, 138, 42, 170 },
43 { 192, 64, 224, 96, 200, 72, 232, 104, 194, 66, 226, 98, 202, 74, 234, 106 },
44 { 48, 176, 16, 144, 56, 184, 24, 152, 50, 178, 18, 146, 58, 186, 26, 154 },
45 { 240, 112, 208, 80, 248, 120, 216, 88, 242, 114, 210, 82, 250, 122, 218, 90 },
46 { 12, 140, 44, 172, 4, 132, 36, 164, 14, 142, 46, 174, 6, 134, 38, 166 },
47 { 204, 76, 236, 108, 196, 68, 228, 100, 206, 78, 238, 110, 198, 70, 230, 102 },
48 { 60, 188, 28, 156, 52, 180, 20, 148, 62, 190, 30, 158, 54, 182, 22, 150 },
49 { 252, 124, 220, 92, 244, 116, 212, 84, 254, 126, 222, 94, 246, 118, 214, 86 },
50 { 3, 131, 35, 163, 11, 139, 43, 171, 1, 129, 33, 161, 9, 137, 41, 169 },
51 { 195, 67, 227, 99, 203, 75, 235, 107, 193, 65, 225, 97, 201, 73, 233, 105 },
52 { 51, 179, 19, 147, 59, 187, 27, 155, 49, 177, 17, 145, 57, 185, 25, 153 },
53 { 243, 115, 211, 83, 251, 123, 219, 91, 241, 113, 209, 81, 249, 121, 217, 89 },
54 { 15, 143, 47, 175, 7, 135, 39, 167, 13, 141, 45, 173, 5, 133, 37, 165 },
55 { 207, 79, 239, 111, 199, 71, 231, 103, 205, 77, 237, 109, 197, 69, 229, 101 },
56 { 63, 191, 31, 159, 55, 183, 23, 151, 61, 189, 29, 157, 53, 181, 21, 149 },
57 { 255, 127, 223, 95, 247, 119, 215, 87, 253, 125, 221, 93, 245, 117, 213, 85 },
60 static inline DWORD *get_pixel_ptr_32(const dib_info *dib, int x, int y)
62 return (DWORD *)((BYTE*)dib->bits.ptr + y * dib->stride + x * 4);
65 static inline DWORD *get_pixel_ptr_24_dword(const dib_info *dib, int x, int y)
67 return (DWORD *)((BYTE*)dib->bits.ptr + y * dib->stride) + x * 3 / 4;
70 static inline BYTE *get_pixel_ptr_24(const dib_info *dib, int x, int y)
72 return (BYTE*)dib->bits.ptr + y * dib->stride + x * 3;
75 static inline WORD *get_pixel_ptr_16(const dib_info *dib, int x, int y)
77 return (WORD *)((BYTE*)dib->bits.ptr + y * dib->stride + x * 2);
80 static inline BYTE *get_pixel_ptr_8(const dib_info *dib, int x, int y)
82 return (BYTE*)dib->bits.ptr + y * dib->stride + x;
85 static inline BYTE *get_pixel_ptr_4(const dib_info *dib, int x, int y)
87 return (BYTE*)dib->bits.ptr + y * dib->stride + x / 2;
90 static inline BYTE *get_pixel_ptr_1(const dib_info *dib, int x, int y)
92 return (BYTE*)dib->bits.ptr + y * dib->stride + x / 8;
95 static const BYTE pixel_masks_4[2] = {0xf0, 0x0f};
96 static const BYTE pixel_masks_1[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
98 static inline void do_rop_32(DWORD *ptr, DWORD and, DWORD xor)
100 *ptr = (*ptr & and) ^ xor;
103 static inline void do_rop_16(WORD *ptr, WORD and, WORD xor)
105 *ptr = (*ptr & and) ^ xor;
108 static inline void do_rop_8(BYTE *ptr, BYTE and, BYTE xor)
110 *ptr = (*ptr & and) ^ xor;
113 static inline void do_rop_mask_8(BYTE *ptr, BYTE and, BYTE xor, BYTE mask)
115 *ptr = (*ptr & (and | ~mask)) ^ (xor & mask);
118 static inline void do_rop_codes_32(DWORD *dst, DWORD src, struct rop_codes *codes)
120 do_rop_32( dst, (src & codes->a1) ^ codes->a2, (src & codes->x1) ^ codes->x2 );
123 static inline void do_rop_codes_16(WORD *dst, WORD src, struct rop_codes *codes)
125 do_rop_16( dst, (src & codes->a1) ^ codes->a2, (src & codes->x1) ^ codes->x2 );
128 static inline void do_rop_codes_8(BYTE *dst, BYTE src, struct rop_codes *codes)
130 do_rop_8( dst, (src & codes->a1) ^ codes->a2, (src & codes->x1) ^ codes->x2 );
133 static inline void do_rop_codes_mask_8(BYTE *dst, BYTE src, struct rop_codes *codes, BYTE mask)
135 do_rop_mask_8( dst, (src & codes->a1) ^ codes->a2, (src & codes->x1) ^ codes->x2, mask );
138 static inline void do_rop_codes_line_32(DWORD *dst, const DWORD *src, struct rop_codes *codes, int len)
140 for (; len > 0; len--, src++, dst++) do_rop_codes_32( dst, *src, codes );
143 static inline void do_rop_codes_line_rev_32(DWORD *dst, const DWORD *src, struct rop_codes *codes, int len)
145 for (src += len - 1, dst += len - 1; len > 0; len--, src--, dst--)
146 do_rop_codes_32( dst, *src, codes );
149 static inline void do_rop_codes_line_16(WORD *dst, const WORD *src, struct rop_codes *codes, int len)
151 for (; len > 0; len--, src++, dst++) do_rop_codes_16( dst, *src, codes );
154 static inline void do_rop_codes_line_rev_16(WORD *dst, const WORD *src, struct rop_codes *codes, int len)
156 for (src += len - 1, dst += len - 1; len > 0; len--, src--, dst--)
157 do_rop_codes_16( dst, *src, codes );
160 static inline void do_rop_codes_line_8(BYTE *dst, const BYTE *src, struct rop_codes *codes, int len)
162 for (; len > 0; len--, src++, dst++) do_rop_codes_8( dst, *src, codes );
165 static inline void do_rop_codes_line_rev_8(BYTE *dst, const BYTE *src, struct rop_codes *codes, int len)
167 for (src += len - 1, dst += len - 1; len > 0; len--, src--, dst--)
168 do_rop_codes_8( dst, *src, codes );
171 static inline void do_rop_codes_line_4(BYTE *dst, int dst_x, const BYTE *src, int src_x,
172 struct rop_codes *codes, int len)
176 for (src += src_x / 2, dst += dst_x / 2; len > 0; len--, dst_x++, src_x++)
180 if (src_x & 1) src_val = *src++;
181 else src_val = *src >> 4;
182 do_rop_codes_mask_8( dst++, src_val, codes, 0x0f );
186 if (src_x & 1) src_val = *src++ << 4;
188 do_rop_codes_mask_8( dst, src_val, codes, 0xf0 );
193 static inline void do_rop_codes_line_rev_4(BYTE *dst, int dst_x, const BYTE *src, int src_x,
194 struct rop_codes *codes, int len)
200 for (src += src_x / 2, dst += dst_x / 2; len > 0; len--, dst_x--, src_x--)
204 if (src_x & 1) src_val = *src;
205 else src_val = *src-- >> 4;
206 do_rop_codes_mask_8( dst, src_val, codes, 0x0f );
210 if (src_x & 1) src_val = *src << 4;
211 else src_val = *src--;
212 do_rop_codes_mask_8( dst--, src_val, codes, 0xf0 );
217 static inline void do_rop_codes_line_1(BYTE *dst, int dst_x, const BYTE *src, int src_x,
218 struct rop_codes *codes, int len)
222 for (src += src_x / 8, dst += dst_x / 8; len > 0; len--, dst_x++, src_x++)
224 src_val = *src & pixel_masks_1[src_x & 7] ? 0xff : 0;
225 do_rop_codes_mask_8( dst, src_val, codes, pixel_masks_1[dst_x & 7] );
226 if ((src_x & 7) == 7) src++;
227 if ((dst_x & 7) == 7) dst++;
231 static inline void do_rop_codes_line_rev_1(BYTE *dst, int dst_x, const BYTE *src, int src_x,
232 struct rop_codes *codes, int len)
238 for (src += src_x / 8, dst += dst_x / 8; len > 0; len--, dst_x--, src_x--)
240 src_val = *src & pixel_masks_1[src_x & 7] ? 0xff : 0;
241 do_rop_codes_mask_8( dst, src_val, codes, pixel_masks_1[dst_x & 7] );
242 if ((src_x & 7) == 0) src--;
243 if ((dst_x & 7) == 0) dst--;
247 static void solid_rects_32(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
252 for(i = 0; i < num; i++, rc++)
254 start = get_pixel_ptr_32(dib, rc->left, rc->top);
255 for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 4)
256 for(x = rc->left, ptr = start; x < rc->right; x++)
257 do_rop_32(ptr++, and, xor);
261 static void solid_rects_24(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
264 BYTE *byte_ptr, *byte_start;
266 DWORD and_masks[3], xor_masks[3];
268 and_masks[0] = ( and & 0x00ffffff) | ((and << 24) & 0xff000000);
269 and_masks[1] = ((and >> 8) & 0x0000ffff) | ((and << 16) & 0xffff0000);
270 and_masks[2] = ((and >> 16) & 0x000000ff) | ((and << 8) & 0xffffff00);
271 xor_masks[0] = ( xor & 0x00ffffff) | ((xor << 24) & 0xff000000);
272 xor_masks[1] = ((xor >> 8) & 0x0000ffff) | ((xor << 16) & 0xffff0000);
273 xor_masks[2] = ((xor >> 16) & 0x000000ff) | ((xor << 8) & 0xffffff00);
275 for(i = 0; i < num; i++, rc++)
277 if(rc->left >= rc->right) continue;
279 if((rc->left & ~3) == (rc->right & ~3)) /* Special case for lines that start and end in the same DWORD triplet */
281 byte_start = get_pixel_ptr_24(dib, rc->left, rc->top);
282 for(y = rc->top; y < rc->bottom; y++, byte_start += dib->stride)
284 for(x = rc->left, byte_ptr = byte_start; x < rc->right; x++)
286 do_rop_8(byte_ptr++, and_masks[0] & 0xff, xor_masks[0] & 0xff);
287 do_rop_8(byte_ptr++, and_masks[1] & 0xff, xor_masks[1] & 0xff);
288 do_rop_8(byte_ptr++, and_masks[2] & 0xff, xor_masks[2] & 0xff);
294 start = get_pixel_ptr_24_dword(dib, rc->left, rc->top);
295 for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 4)
302 do_rop_32(ptr++, and_masks[0] | 0x00ffffff, xor_masks[0] & 0xff000000);
303 do_rop_32(ptr++, and_masks[1], xor_masks[1]);
304 do_rop_32(ptr++, and_masks[2], xor_masks[2]);
307 do_rop_32(ptr++, and_masks[1] | 0x0000ffff, xor_masks[1] & 0xffff0000);
308 do_rop_32(ptr++, and_masks[2], xor_masks[2]);
311 do_rop_32(ptr++, and_masks[2] | 0x000000ff, xor_masks[2] & 0xffffff00);
315 for(x = (rc->left + 3) & ~3; x < (rc->right & ~3); x += 4)
317 do_rop_32(ptr++, and_masks[0], xor_masks[0]);
318 do_rop_32(ptr++, and_masks[1], xor_masks[1]);
319 do_rop_32(ptr++, and_masks[2], xor_masks[2]);
322 switch(rc->right & 3)
325 do_rop_32(ptr, and_masks[0] | 0xff000000, xor_masks[0] & 0x00ffffff);
328 do_rop_32(ptr++, and_masks[0], xor_masks[0]);
329 do_rop_32(ptr, and_masks[1] | 0xffff0000, xor_masks[1] & 0x0000ffff);
332 do_rop_32(ptr++, and_masks[0], xor_masks[0]);
333 do_rop_32(ptr++, and_masks[1], xor_masks[1]);
334 do_rop_32(ptr, and_masks[2] | 0xffffff00, xor_masks[2] & 0x000000ff);
342 static void solid_rects_16(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
347 for(i = 0; i < num; i++, rc++)
349 start = get_pixel_ptr_16(dib, rc->left, rc->top);
350 for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 2)
351 for(x = rc->left, ptr = start; x < rc->right; x++)
352 do_rop_16(ptr++, and, xor);
356 static void solid_rects_8(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
361 for(i = 0; i < num; i++, rc++)
363 start = get_pixel_ptr_8(dib, rc->left, rc->top);
364 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
365 for(x = rc->left, ptr = start; x < rc->right; x++)
366 do_rop_8(ptr++, and, xor);
370 static void solid_rects_4(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
374 BYTE byte_and = (and & 0xf) | ((and << 4) & 0xf0);
375 BYTE byte_xor = (xor & 0xf) | ((xor << 4) & 0xf0);
377 for(i = 0; i < num; i++, rc++)
379 if(rc->left >= rc->right) continue;
380 start = get_pixel_ptr_4(dib, rc->left, rc->top);
381 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
384 if(rc->left & 1) /* upper nibble untouched */
385 do_rop_8(ptr++, byte_and | 0xf0, byte_xor & 0x0f);
387 for(x = (rc->left + 1) & ~1; x < (rc->right & ~1); x += 2)
388 do_rop_8(ptr++, byte_and, byte_xor);
390 if(rc->right & 1) /* lower nibble untouched */
391 do_rop_8(ptr, byte_and | 0x0f, byte_xor & 0xf0);
396 static void solid_rects_1(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
400 BYTE byte_and = (and & 1) ? 0xff : 0;
401 BYTE byte_xor = (xor & 1) ? 0xff : 0;
402 BYTE start_and, start_xor, end_and, end_xor, mask;
403 static const BYTE masks[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
405 for(i = 0; i < num; i++, rc++)
407 if(rc->left >= rc->right) continue;
409 start = get_pixel_ptr_1(dib, rc->left, rc->top);
411 if((rc->left & ~7) == (rc->right & ~7)) /* Special case for lines that start and end in the same byte */
413 mask = masks[rc->left & 7] & ~masks[rc->right & 7];
415 start_and = byte_and | ~mask;
416 start_xor = byte_xor & mask;
417 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
419 do_rop_8(start, start_and, start_xor);
424 mask = masks[rc->left & 7];
425 start_and = byte_and | ~mask;
426 start_xor = byte_xor & mask;
428 mask = masks[rc->right & 7];
429 /* This is inverted wrt to start mask, so end_and/xor assignments reflect this */
430 end_and = byte_and | mask;
431 end_xor = byte_xor & ~mask;
433 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
438 do_rop_8(ptr++, start_and, start_xor);
440 for(x = (rc->left + 7) & ~7; x < (rc->right & ~7); x += 8)
441 do_rop_8(ptr++, byte_and, byte_xor);
444 do_rop_8(ptr, end_and, end_xor);
450 static void solid_rects_null(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
455 static void solid_line_32(const dib_info *dib, const POINT *start, const struct line_params *params,
456 DWORD and, DWORD xor)
458 DWORD *ptr = get_pixel_ptr_32( dib, start->x, start->y );
459 int len = params->length, err = params->err_start;
460 int major_inc, minor_inc;
464 major_inc = params->x_inc;
465 minor_inc = (dib->stride * params->y_inc) / 4;
469 major_inc = (dib->stride * params->y_inc) / 4;
470 minor_inc = params->x_inc;
475 do_rop_32( ptr, and, xor );
476 if (err + params->bias > 0)
479 err += params->err_add_1;
481 else err += params->err_add_2;
486 static void solid_line_24(const dib_info *dib, const POINT *start, const struct line_params *params,
487 DWORD and, DWORD xor)
489 BYTE *ptr = get_pixel_ptr_24( dib, start->x, start->y );
490 int len = params->length, err = params->err_start;
491 int major_inc, minor_inc;
495 major_inc = params->x_inc * 3;
496 minor_inc = dib->stride * params->y_inc;
500 major_inc = dib->stride * params->y_inc;
501 minor_inc = params->x_inc * 3;
506 do_rop_8( ptr, and, xor );
507 do_rop_8( ptr + 1, and >> 8, xor >> 8 );
508 do_rop_8( ptr + 2, and >> 16, xor >> 16 );
509 if (err + params->bias > 0)
512 err += params->err_add_1;
514 else err += params->err_add_2;
519 static void solid_line_16(const dib_info *dib, const POINT *start, const struct line_params *params,
520 DWORD and, DWORD xor)
522 WORD *ptr = get_pixel_ptr_16( dib, start->x, start->y );
523 int len = params->length, err = params->err_start;
524 int major_inc, minor_inc;
528 major_inc = params->x_inc;
529 minor_inc = (dib->stride * params->y_inc) / 2;
533 major_inc = (dib->stride * params->y_inc) / 2;
534 minor_inc = params->x_inc;
539 do_rop_16( ptr, and, xor );
540 if (err + params->bias > 0)
543 err += params->err_add_1;
545 else err += params->err_add_2;
550 static void solid_line_8(const dib_info *dib, const POINT *start, const struct line_params *params,
551 DWORD and, DWORD xor)
553 BYTE *ptr = get_pixel_ptr_8( dib, start->x, start->y );
554 int len = params->length, err = params->err_start;
555 int major_inc, minor_inc;
559 major_inc = params->x_inc;
560 minor_inc = dib->stride * params->y_inc;
564 major_inc = dib->stride * params->y_inc;
565 minor_inc = params->x_inc;
570 do_rop_8( ptr, and, xor );
571 if (err + params->bias > 0)
574 err += params->err_add_1;
576 else err += params->err_add_2;
581 static void solid_line_4(const dib_info *dib, const POINT *start, const struct line_params *params,
582 DWORD and, DWORD xor)
584 BYTE *ptr = get_pixel_ptr_4( dib, start->x, start->y );
585 int len = params->length, err = params->err_start;
588 and = (and & 0x0f) | ((and << 4) & 0xf0);
589 xor = (xor & 0x0f) | ((xor << 4) & 0xf0);
595 do_rop_mask_8( ptr, and, xor, pixel_masks_4[ x % 2 ] );
596 if (err + params->bias > 0)
598 ptr += dib->stride * params->y_inc;
599 err += params->err_add_1;
601 else err += params->err_add_2;
602 if ((x / 2) != ((x + params->x_inc) / 2))
603 ptr += params->x_inc;
611 do_rop_mask_8( ptr, and, xor, pixel_masks_4[ x % 2 ] );
612 if (err + params->bias > 0)
614 if ((x / 2) != ((x + params->x_inc) / 2))
615 ptr += params->x_inc;
617 err += params->err_add_1;
619 else err += params->err_add_2;
620 ptr += dib->stride * params->y_inc;
625 static void solid_line_1(const dib_info *dib, const POINT *start, const struct line_params *params,
626 DWORD and, DWORD xor)
628 BYTE *ptr = get_pixel_ptr_1( dib, start->x, start->y );
629 int len = params->length, err = params->err_start;
632 and = (and & 0x1) ? 0xff : 0;
633 xor = (xor & 0x1) ? 0xff : 0;
639 do_rop_mask_8( ptr, and, xor, pixel_masks_1[ x % 8 ] );
640 if (err + params->bias > 0)
642 ptr += dib->stride * params->y_inc;
643 err += params->err_add_1;
645 else err += params->err_add_2;
646 if ((x / 8) != ((x + params->x_inc) / 8))
647 ptr += params->x_inc;
655 do_rop_mask_8( ptr, and, xor, pixel_masks_1[ x % 8 ] );
656 if (err + params->bias > 0)
658 if ((x / 8) != ((x + params->x_inc) / 8))
659 ptr += params->x_inc;
661 err += params->err_add_1;
663 else err += params->err_add_2;
664 ptr += dib->stride * params->y_inc;
669 static void solid_line_null(const dib_info *dib, const POINT *start, const struct line_params *params,
670 DWORD and, DWORD xor)
675 static inline INT calc_offset(INT edge, INT size, INT origin)
679 if(edge - origin >= 0)
680 offset = (edge - origin) % size;
683 offset = (origin - edge) % size;
684 if(offset) offset = size - offset;
689 static inline POINT calc_brush_offset(const RECT *rc, const dib_info *brush, const POINT *origin)
693 offset.x = calc_offset(rc->left, brush->width, origin->x);
694 offset.y = calc_offset(rc->top, brush->height, origin->y);
699 static void pattern_rects_32(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
700 const dib_info *brush, void *and_bits, void *xor_bits)
702 DWORD *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
706 for(i = 0; i < num; i++, rc++)
708 offset = calc_brush_offset(rc, brush, origin);
710 start = get_pixel_ptr_32(dib, rc->left, rc->top);
711 start_and = (DWORD*)and_bits + offset.y * brush->stride / 4;
712 start_xor = (DWORD*)xor_bits + offset.y * brush->stride / 4;
714 for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 4)
716 and_ptr = start_and + offset.x;
717 xor_ptr = start_xor + offset.x;
719 for(x = rc->left, ptr = start; x < rc->right; x++)
721 do_rop_32(ptr++, *and_ptr++, *xor_ptr++);
722 if(and_ptr == start_and + brush->width)
730 if(offset.y == brush->height)
732 start_and = and_bits;
733 start_xor = xor_bits;
738 start_and += brush->stride / 4;
739 start_xor += brush->stride / 4;
745 static void pattern_rects_24(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
746 const dib_info *brush, void *and_bits, void *xor_bits)
748 BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
752 for(i = 0; i < num; i++, rc++)
754 offset = calc_brush_offset(rc, brush, origin);
756 start = get_pixel_ptr_24(dib, rc->left, rc->top);
757 start_and = (BYTE*)and_bits + offset.y * brush->stride;
758 start_xor = (BYTE*)xor_bits + offset.y * brush->stride;
760 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
762 and_ptr = start_and + offset.x * 3;
763 xor_ptr = start_xor + offset.x * 3;
765 for(x = rc->left, ptr = start; x < rc->right; x++)
767 do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
768 do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
769 do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
770 if(and_ptr == start_and + brush->width * 3)
778 if(offset.y == brush->height)
780 start_and = and_bits;
781 start_xor = xor_bits;
786 start_and += brush->stride;
787 start_xor += brush->stride;
793 static void pattern_rects_16(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
794 const dib_info *brush, void *and_bits, void *xor_bits)
796 WORD *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
800 for(i = 0; i < num; i++, rc++)
802 offset = calc_brush_offset(rc, brush, origin);
804 start = get_pixel_ptr_16(dib, rc->left, rc->top);
805 start_and = (WORD*)and_bits + offset.y * brush->stride / 2;
806 start_xor = (WORD*)xor_bits + offset.y * brush->stride / 2;
808 for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 2)
810 and_ptr = start_and + offset.x;
811 xor_ptr = start_xor + offset.x;
813 for(x = rc->left, ptr = start; x < rc->right; x++)
815 do_rop_16(ptr++, *and_ptr++, *xor_ptr++);
816 if(and_ptr == start_and + brush->width)
824 if(offset.y == brush->height)
826 start_and = and_bits;
827 start_xor = xor_bits;
832 start_and += brush->stride / 2;
833 start_xor += brush->stride / 2;
839 static void pattern_rects_8(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
840 const dib_info *brush, void *and_bits, void *xor_bits)
842 BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
846 for(i = 0; i < num; i++, rc++)
848 offset = calc_brush_offset(rc, brush, origin);
850 start = get_pixel_ptr_8(dib, rc->left, rc->top);
851 start_and = (BYTE*)and_bits + offset.y * brush->stride;
852 start_xor = (BYTE*)xor_bits + offset.y * brush->stride;
854 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
856 and_ptr = start_and + offset.x;
857 xor_ptr = start_xor + offset.x;
859 for(x = rc->left, ptr = start; x < rc->right; x++)
861 do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
862 if(and_ptr == start_and + brush->width)
870 if(offset.y == brush->height)
872 start_and = and_bits;
873 start_xor = xor_bits;
878 start_and += brush->stride;
879 start_xor += brush->stride;
885 static void pattern_rects_4(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
886 const dib_info *brush, void *and_bits, void *xor_bits)
888 BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
892 for(i = 0; i < num; i++, rc++)
894 offset = calc_brush_offset(rc, brush, origin);
896 start = get_pixel_ptr_4(dib, rc->left, rc->top);
897 start_and = (BYTE*)and_bits + offset.y * brush->stride;
898 start_xor = (BYTE*)xor_bits + offset.y * brush->stride;
900 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
902 INT brush_x = offset.x;
903 BYTE byte_and, byte_xor;
905 and_ptr = start_and + brush_x / 2;
906 xor_ptr = start_xor + brush_x / 2;
908 for(x = rc->left, ptr = start; x < rc->right; x++)
910 /* FIXME: Two pixels at a time */
911 if(x & 1) /* lower dst nibble */
913 if(brush_x & 1) /* lower pat nibble */
915 byte_and = *and_ptr++ | 0xf0;
916 byte_xor = *xor_ptr++ & 0x0f;
918 else /* upper pat nibble */
920 byte_and = (*and_ptr >> 4) | 0xf0;
921 byte_xor = (*xor_ptr >> 4) & 0x0f;
924 else /* upper dst nibble */
926 if(brush_x & 1) /* lower pat nibble */
928 byte_and = (*and_ptr++ << 4) | 0x0f;
929 byte_xor = (*xor_ptr++ << 4) & 0xf0;
931 else /* upper pat nibble */
933 byte_and = *and_ptr | 0x0f;
934 byte_xor = *xor_ptr & 0xf0;
937 do_rop_8(ptr, byte_and, byte_xor);
941 if(++brush_x == brush->width)
950 if(offset.y == brush->height)
952 start_and = and_bits;
953 start_xor = xor_bits;
958 start_and += brush->stride;
959 start_xor += brush->stride;
965 static void pattern_rects_1(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
966 const dib_info *brush, void *and_bits, void *xor_bits)
968 BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
972 for(i = 0; i < num; i++, rc++)
974 offset = calc_brush_offset(rc, brush, origin);
976 start = get_pixel_ptr_1(dib, rc->left, rc->top);
977 start_and = (BYTE*)and_bits + offset.y * brush->stride;
978 start_xor = (BYTE*)xor_bits + offset.y * brush->stride;
980 for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
982 INT brush_x = offset.x;
983 BYTE byte_and, byte_xor;
985 and_ptr = start_and + brush_x / 8;
986 xor_ptr = start_xor + brush_x / 8;
988 for(x = rc->left, ptr = start; x < rc->right; x++)
990 byte_and = (*and_ptr & pixel_masks_1[brush_x % 8]) ? 0xff : 0;
991 byte_and |= ~pixel_masks_1[x % 8];
992 byte_xor = (*xor_ptr & pixel_masks_1[brush_x % 8]) ? 0xff : 0;
993 byte_xor &= pixel_masks_1[x % 8];
995 do_rop_8(ptr, byte_and, byte_xor);
997 if((x & 7) == 7) ptr++;
999 if((brush_x & 7) == 7)
1005 if(++brush_x == brush->width)
1008 and_ptr = start_and;
1009 xor_ptr = start_xor;
1014 if(offset.y == brush->height)
1016 start_and = and_bits;
1017 start_xor = xor_bits;
1022 start_and += brush->stride;
1023 start_xor += brush->stride;
1029 static void pattern_rects_null(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
1030 const dib_info *brush, void *and_bits, void *xor_bits)
1035 static void copy_rect_32(const dib_info *dst, const RECT *rc,
1036 const dib_info *src, const POINT *origin, int rop2, int overlap)
1038 DWORD *dst_start, *src_start;
1039 struct rop_codes codes;
1040 int y, dst_stride, src_stride;
1042 if (overlap & OVERLAP_BELOW)
1044 dst_start = get_pixel_ptr_32(dst, rc->left, rc->bottom - 1);
1045 src_start = get_pixel_ptr_32(src, origin->x, origin->y + rc->bottom - rc->top - 1);
1046 dst_stride = -dst->stride / 4;
1047 src_stride = -src->stride / 4;
1051 dst_start = get_pixel_ptr_32(dst, rc->left, rc->top);
1052 src_start = get_pixel_ptr_32(src, origin->x, origin->y);
1053 dst_stride = dst->stride / 4;
1054 src_stride = src->stride / 4;
1057 if (rop2 == R2_COPYPEN)
1059 for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1060 memmove( dst_start, src_start, (rc->right - rc->left) * 4 );
1064 get_rop_codes( rop2, &codes );
1065 for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1067 if (overlap & OVERLAP_RIGHT)
1068 do_rop_codes_line_rev_32( dst_start, src_start, &codes, rc->right - rc->left );
1070 do_rop_codes_line_32( dst_start, src_start, &codes, rc->right - rc->left );
1074 static void copy_rect_24(const dib_info *dst, const RECT *rc,
1075 const dib_info *src, const POINT *origin, int rop2, int overlap)
1077 BYTE *dst_start, *src_start;
1078 int y, dst_stride, src_stride;
1079 struct rop_codes codes;
1081 if (overlap & OVERLAP_BELOW)
1083 dst_start = get_pixel_ptr_24(dst, rc->left, rc->bottom - 1);
1084 src_start = get_pixel_ptr_24(src, origin->x, origin->y + rc->bottom - rc->top - 1);
1085 dst_stride = -dst->stride;
1086 src_stride = -src->stride;
1090 dst_start = get_pixel_ptr_24(dst, rc->left, rc->top);
1091 src_start = get_pixel_ptr_24(src, origin->x, origin->y);
1092 dst_stride = dst->stride;
1093 src_stride = src->stride;
1096 if (rop2 == R2_COPYPEN)
1098 for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1099 memmove( dst_start, src_start, (rc->right - rc->left) * 3 );
1103 get_rop_codes( rop2, &codes );
1104 for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1106 if (overlap & OVERLAP_RIGHT)
1107 do_rop_codes_line_rev_8( dst_start, src_start, &codes, (rc->right - rc->left) * 3 );
1109 do_rop_codes_line_8( dst_start, src_start, &codes, (rc->right - rc->left) * 3 );
1113 static void copy_rect_16(const dib_info *dst, const RECT *rc,
1114 const dib_info *src, const POINT *origin, int rop2, int overlap)
1116 WORD *dst_start, *src_start;
1117 int y, dst_stride, src_stride;
1118 struct rop_codes codes;
1120 if (overlap & OVERLAP_BELOW)
1122 dst_start = get_pixel_ptr_16(dst, rc->left, rc->bottom - 1);
1123 src_start = get_pixel_ptr_16(src, origin->x, origin->y + rc->bottom - rc->top - 1);
1124 dst_stride = -dst->stride / 2;
1125 src_stride = -src->stride / 2;
1129 dst_start = get_pixel_ptr_16(dst, rc->left, rc->top);
1130 src_start = get_pixel_ptr_16(src, origin->x, origin->y);
1131 dst_stride = dst->stride / 2;
1132 src_stride = src->stride / 2;
1135 if (rop2 == R2_COPYPEN)
1137 for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1138 memmove( dst_start, src_start, (rc->right - rc->left) * 2 );
1142 get_rop_codes( rop2, &codes );
1143 for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1145 if (overlap & OVERLAP_RIGHT)
1146 do_rop_codes_line_rev_16( dst_start, src_start, &codes, rc->right - rc->left );
1148 do_rop_codes_line_16( dst_start, src_start, &codes, rc->right - rc->left );
1152 static void copy_rect_8(const dib_info *dst, const RECT *rc,
1153 const dib_info *src, const POINT *origin, int rop2, int overlap)
1155 BYTE *dst_start, *src_start;
1156 int y, dst_stride, src_stride;
1157 struct rop_codes codes;
1159 if (overlap & OVERLAP_BELOW)
1161 dst_start = get_pixel_ptr_8(dst, rc->left, rc->bottom - 1);
1162 src_start = get_pixel_ptr_8(src, origin->x, origin->y + rc->bottom - rc->top - 1);
1163 dst_stride = -dst->stride;
1164 src_stride = -src->stride;
1168 dst_start = get_pixel_ptr_8(dst, rc->left, rc->top);
1169 src_start = get_pixel_ptr_8(src, origin->x, origin->y);
1170 dst_stride = dst->stride;
1171 src_stride = src->stride;
1174 if (rop2 == R2_COPYPEN)
1176 for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1177 memmove( dst_start, src_start, (rc->right - rc->left) );
1181 get_rop_codes( rop2, &codes );
1182 for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1184 if (overlap & OVERLAP_RIGHT)
1185 do_rop_codes_line_rev_8( dst_start, src_start, &codes, rc->right - rc->left );
1187 do_rop_codes_line_8( dst_start, src_start, &codes, rc->right - rc->left );
1191 static void copy_rect_4(const dib_info *dst, const RECT *rc,
1192 const dib_info *src, const POINT *origin, int rop2, int overlap)
1194 BYTE *dst_start, *src_start;
1195 int y, dst_stride, src_stride;
1196 struct rop_codes codes;
1198 if (overlap & OVERLAP_BELOW)
1200 dst_start = get_pixel_ptr_4(dst, 0, rc->bottom - 1);
1201 src_start = get_pixel_ptr_4(src, 0, origin->y + rc->bottom - rc->top - 1);
1202 dst_stride = -dst->stride;
1203 src_stride = -src->stride;
1207 dst_start = get_pixel_ptr_4(dst, 0, rc->top);
1208 src_start = get_pixel_ptr_4(src, 0, origin->y);
1209 dst_stride = dst->stride;
1210 src_stride = src->stride;
1213 if (rop2 == R2_COPYPEN && (rc->left & 1) == 0 && (origin->x & 1) == 0 && (rc->right & 1) == 0)
1215 dst_start += rc->left / 2;
1216 src_start += origin->x / 2;
1217 for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1218 memmove( dst_start, src_start, (rc->right - rc->left) / 2 );
1222 get_rop_codes( rop2, &codes );
1223 for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1225 if (overlap & OVERLAP_RIGHT)
1226 do_rop_codes_line_rev_4( dst_start, rc->left, src_start, origin->x, &codes, rc->right - rc->left );
1228 do_rop_codes_line_4( dst_start, rc->left, src_start, origin->x, &codes, rc->right - rc->left );
1232 static void copy_rect_1(const dib_info *dst, const RECT *rc,
1233 const dib_info *src, const POINT *origin, int rop2, int overlap)
1235 BYTE *dst_start, *src_start;
1236 int y, dst_stride, src_stride;
1237 struct rop_codes codes;
1239 if (overlap & OVERLAP_BELOW)
1241 dst_start = get_pixel_ptr_1(dst, 0, rc->bottom - 1);
1242 src_start = get_pixel_ptr_1(src, 0, origin->y + rc->bottom - rc->top - 1);
1243 dst_stride = -dst->stride;
1244 src_stride = -src->stride;
1248 dst_start = get_pixel_ptr_1(dst, 0, rc->top);
1249 src_start = get_pixel_ptr_1(src, 0, origin->y);
1250 dst_stride = dst->stride;
1251 src_stride = src->stride;
1254 if (rop2 == R2_COPYPEN && (rc->left & 7) == 0 && (origin->x & 7) == 0 && (rc->right & 7) == 0)
1256 dst_start += rc->left / 8;
1257 src_start += origin->x / 8;
1258 for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1259 memmove( dst_start, src_start, (rc->right - rc->left) / 8 );
1263 get_rop_codes( rop2, &codes );
1264 for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1266 if (overlap & OVERLAP_RIGHT)
1267 do_rop_codes_line_rev_1( dst_start, rc->left, src_start, origin->x, &codes, rc->right - rc->left );
1269 do_rop_codes_line_1( dst_start, rc->left, src_start, origin->x, &codes, rc->right - rc->left );
1273 static void copy_rect_null(const dib_info *dst, const RECT *rc,
1274 const dib_info *src, const POINT *origin, int rop2, int overlap)
1279 static DWORD get_pixel_32(const dib_info *dib, int x, int y)
1281 DWORD *ptr = get_pixel_ptr_32( dib, x, y );
1285 static DWORD get_pixel_24(const dib_info *dib, int x, int y)
1287 BYTE *ptr = get_pixel_ptr_24( dib, x, y );
1288 return ptr[0] | ((DWORD)ptr[1] << 8) | ((DWORD)ptr[2] << 16);
1291 static DWORD get_pixel_16(const dib_info *dib, int x, int y)
1293 WORD *ptr = get_pixel_ptr_16( dib, x, y );
1297 static DWORD get_pixel_8(const dib_info *dib, int x, int y)
1299 BYTE *ptr = get_pixel_ptr_8( dib, x, y );
1303 static DWORD get_pixel_4(const dib_info *dib, int x, int y)
1305 BYTE *ptr = get_pixel_ptr_4( dib, x, y );
1310 return (*ptr >> 4) & 0x0f;
1313 static DWORD get_pixel_1(const dib_info *dib, int x, int y)
1315 BYTE *ptr = get_pixel_ptr_1( dib, x, y );
1316 return (*ptr & pixel_masks_1[x & 0x7]) ? 1 : 0;
1319 static DWORD get_pixel_null(const dib_info *dib, int x, int y)
1324 static DWORD colorref_to_pixel_888(const dib_info *dib, COLORREF color)
1326 return ( ((color >> 16) & 0xff) | (color & 0xff00) | ((color << 16) & 0xff0000) );
1329 static const DWORD field_masks[33] =
1331 0x00, /* should never happen */
1332 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff,
1333 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1334 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1335 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1338 static inline DWORD get_field(DWORD field, int shift, int len)
1340 shift = shift - (8 - len);
1345 field &= field_masks[len];
1346 field |= field >> len;
1350 static inline DWORD put_field(DWORD field, int shift, int len)
1352 shift = shift - (8 - len);
1353 field &= field_masks[len];
1361 static DWORD colorref_to_pixel_masks(const dib_info *dib, COLORREF colour)
1365 r = GetRValue(colour);
1366 g = GetGValue(colour);
1367 b = GetBValue(colour);
1369 return put_field(r, dib->red_shift, dib->red_len) |
1370 put_field(g, dib->green_shift, dib->green_len) |
1371 put_field(b, dib->blue_shift, dib->blue_len);
1374 static DWORD colorref_to_pixel_555(const dib_info *dib, COLORREF color)
1376 return ( ((color >> 19) & 0x1f) | ((color >> 6) & 0x03e0) | ((color << 7) & 0x7c00) );
1379 static DWORD rgb_to_pixel_colortable(const dib_info *dib, BYTE r, BYTE g, BYTE b)
1381 int i, best_index = 0;
1382 DWORD diff, best_diff = 0xffffffff;
1384 /* special case for conversion to 1-bpp without a color table:
1385 * we get a 1-entry table containing the background color
1387 if (dib->bit_count == 1 && dib->color_table_size == 1)
1388 return (r == dib->color_table[0].rgbRed &&
1389 g == dib->color_table[0].rgbGreen &&
1390 b == dib->color_table[0].rgbBlue);
1392 for(i = 0; i < dib->color_table_size; i++)
1394 const RGBQUAD *cur = dib->color_table + i;
1395 diff = (r - cur->rgbRed) * (r - cur->rgbRed)
1396 + (g - cur->rgbGreen) * (g - cur->rgbGreen)
1397 + (b - cur->rgbBlue) * (b - cur->rgbBlue);
1405 if(diff < best_diff)
1414 static DWORD colorref_to_pixel_colortable(const dib_info *dib, COLORREF color)
1416 return rgb_to_pixel_colortable( dib, GetRValue(color), GetGValue(color), GetBValue(color) );
1419 static DWORD colorref_to_pixel_null(const dib_info *dib, COLORREF color)
1424 static COLORREF pixel_to_colorref_888(const dib_info *dib, DWORD pixel)
1426 return ( ((pixel >> 16) & 0xff) | (pixel & 0xff00) | ((pixel << 16) & 0xff0000) );
1429 static COLORREF pixel_to_colorref_masks(const dib_info *dib, DWORD pixel)
1431 return RGB( get_field( pixel, dib->red_shift, dib->red_len ),
1432 get_field( pixel, dib->green_shift, dib->green_len ),
1433 get_field( pixel, dib->blue_shift, dib->blue_len ) );
1436 static COLORREF pixel_to_colorref_555(const dib_info *dib, DWORD pixel)
1438 return RGB( ((pixel >> 7) & 0xf8) | ((pixel >> 12) & 0x07),
1439 ((pixel >> 2) & 0xf8) | ((pixel >> 7) & 0x07),
1440 ((pixel << 3) & 0xf8) | ((pixel >> 2) & 0x07) );
1443 static COLORREF pixel_to_colorref_colortable(const dib_info *dib, DWORD pixel)
1445 if (pixel < dib->color_table_size)
1447 RGBQUAD quad = dib->color_table[pixel];
1448 return RGB( quad.rgbRed, quad.rgbGreen, quad.rgbBlue );
1453 static COLORREF pixel_to_colorref_null(const dib_info *dib, DWORD pixel)
1458 static inline BOOL bit_fields_match(const dib_info *d1, const dib_info *d2)
1460 assert( d1->bit_count > 8 && d1->bit_count == d2->bit_count );
1462 return d1->red_mask == d2->red_mask &&
1463 d1->green_mask == d2->green_mask &&
1464 d1->blue_mask == d2->blue_mask;
1467 static void convert_to_8888(dib_info *dst, const dib_info *src, const RECT *src_rect)
1469 DWORD *dst_start = get_pixel_ptr_32(dst, 0, 0), *dst_pixel, src_val;
1470 int x, y, pad_size = (dst->width - (src_rect->right - src_rect->left)) * 4;
1472 switch(src->bit_count)
1476 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1477 if(src->funcs == &funcs_8888)
1479 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
1480 memcpy(dst_start, src_start, (src_rect->bottom - src_rect->top) * src->stride);
1483 for(y = src_rect->top; y < src_rect->bottom; y++)
1485 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 4);
1486 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
1487 dst_start += dst->stride / 4;
1488 src_start += src->stride / 4;
1492 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
1494 for(y = src_rect->top; y < src_rect->bottom; y++)
1496 dst_pixel = dst_start;
1497 src_pixel = src_start;
1498 for(x = src_rect->left; x < src_rect->right; x++)
1500 src_val = *src_pixel++;
1501 *dst_pixel++ = (((src_val >> src->red_shift) & 0xff) << 16) |
1502 (((src_val >> src->green_shift) & 0xff) << 8) |
1503 ((src_val >> src->blue_shift) & 0xff);
1505 if(pad_size) memset(dst_pixel, 0, pad_size);
1506 dst_start += dst->stride / 4;
1507 src_start += src->stride / 4;
1512 for(y = src_rect->top; y < src_rect->bottom; y++)
1514 dst_pixel = dst_start;
1515 src_pixel = src_start;
1516 for(x = src_rect->left; x < src_rect->right; x++)
1518 src_val = *src_pixel++;
1519 *dst_pixel++ = (get_field( src_val, src->red_shift, src->red_len ) << 16 |
1520 get_field( src_val, src->green_shift, src->green_len ) << 8 |
1521 get_field( src_val, src->blue_shift, src->blue_len ));
1523 if(pad_size) memset(dst_pixel, 0, pad_size);
1524 dst_start += dst->stride / 4;
1525 src_start += src->stride / 4;
1533 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
1535 for(y = src_rect->top; y < src_rect->bottom; y++)
1537 dst_pixel = dst_start;
1538 src_pixel = src_start;
1539 for(x = src_rect->left; x < src_rect->right; x++)
1542 rgb.rgbBlue = *src_pixel++;
1543 rgb.rgbGreen = *src_pixel++;
1544 rgb.rgbRed = *src_pixel++;
1546 *dst_pixel++ = ((rgb.rgbRed << 16) & 0xff0000) | ((rgb.rgbGreen << 8) & 0x00ff00) | (rgb.rgbBlue & 0x0000ff);
1548 if(pad_size) memset(dst_pixel, 0, pad_size);
1549 dst_start += dst->stride / 4;
1550 src_start += src->stride;
1557 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
1558 if(src->funcs == &funcs_555)
1560 for(y = src_rect->top; y < src_rect->bottom; y++)
1562 dst_pixel = dst_start;
1563 src_pixel = src_start;
1564 for(x = src_rect->left; x < src_rect->right; x++)
1566 src_val = *src_pixel++;
1567 *dst_pixel++ = ((src_val << 9) & 0xf80000) | ((src_val << 4) & 0x070000) |
1568 ((src_val << 6) & 0x00f800) | ((src_val << 1) & 0x000700) |
1569 ((src_val << 3) & 0x0000f8) | ((src_val >> 2) & 0x000007);
1571 if(pad_size) memset(dst_pixel, 0, pad_size);
1572 dst_start += dst->stride / 4;
1573 src_start += src->stride / 2;
1576 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
1578 for(y = src_rect->top; y < src_rect->bottom; y++)
1580 dst_pixel = dst_start;
1581 src_pixel = src_start;
1582 for(x = src_rect->left; x < src_rect->right; x++)
1584 src_val = *src_pixel++;
1585 *dst_pixel++ = (((src_val >> src->red_shift) << 19) & 0xf80000) |
1586 (((src_val >> src->red_shift) << 14) & 0x070000) |
1587 (((src_val >> src->green_shift) << 11) & 0x00f800) |
1588 (((src_val >> src->green_shift) << 6) & 0x000700) |
1589 (((src_val >> src->blue_shift) << 3) & 0x0000f8) |
1590 (((src_val >> src->blue_shift) >> 2) & 0x000007);
1592 if(pad_size) memset(dst_pixel, 0, pad_size);
1593 dst_start += dst->stride / 4;
1594 src_start += src->stride / 2;
1597 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
1599 for(y = src_rect->top; y < src_rect->bottom; y++)
1601 dst_pixel = dst_start;
1602 src_pixel = src_start;
1603 for(x = src_rect->left; x < src_rect->right; x++)
1605 src_val = *src_pixel++;
1606 *dst_pixel++ = (((src_val >> src->red_shift) << 19) & 0xf80000) |
1607 (((src_val >> src->red_shift) << 14) & 0x070000) |
1608 (((src_val >> src->green_shift) << 10) & 0x00fc00) |
1609 (((src_val >> src->green_shift) << 4) & 0x000300) |
1610 (((src_val >> src->blue_shift) << 3) & 0x0000f8) |
1611 (((src_val >> src->blue_shift) >> 2) & 0x000007);
1613 if(pad_size) memset(dst_pixel, 0, pad_size);
1614 dst_start += dst->stride / 4;
1615 src_start += src->stride / 2;
1620 for(y = src_rect->top; y < src_rect->bottom; y++)
1622 dst_pixel = dst_start;
1623 src_pixel = src_start;
1624 for(x = src_rect->left; x < src_rect->right; x++)
1626 src_val = *src_pixel++;
1627 *dst_pixel++ = (get_field( src_val, src->red_shift, src->red_len ) << 16 |
1628 get_field( src_val, src->green_shift, src->green_len ) << 8 |
1629 get_field( src_val, src->blue_shift, src->blue_len ));
1631 if(pad_size) memset(dst_pixel, 0, pad_size);
1632 dst_start += dst->stride / 4;
1633 src_start += src->stride / 2;
1641 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
1642 for(y = src_rect->top; y < src_rect->bottom; y++)
1644 dst_pixel = dst_start;
1645 src_pixel = src_start;
1646 for(x = src_rect->left; x < src_rect->right; x++)
1648 RGBQUAD rgb = src->color_table[*src_pixel++];
1649 *dst_pixel++ = rgb.rgbRed << 16 | rgb.rgbGreen << 8 | rgb.rgbBlue;
1651 if(pad_size) memset(dst_pixel, 0, pad_size);
1652 dst_start += dst->stride / 4;
1653 src_start += src->stride;
1660 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
1661 for(y = src_rect->top; y < src_rect->bottom; y++)
1663 dst_pixel = dst_start;
1664 src_pixel = src_start;
1665 for(x = src_rect->left; x < src_rect->right; x++)
1669 rgb = src->color_table[*src_pixel++ & 0xf];
1671 rgb = src->color_table[*src_pixel >> 4];
1672 *dst_pixel++ = rgb.rgbRed << 16 | rgb.rgbGreen << 8 | rgb.rgbBlue;
1674 if(pad_size) memset(dst_pixel, 0, pad_size);
1675 dst_start += dst->stride / 4;
1676 src_start += src->stride;
1683 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
1684 for(y = src_rect->top; y < src_rect->bottom; y++)
1686 dst_pixel = dst_start;
1687 src_pixel = src_start;
1688 for(x = src_rect->left; x < src_rect->right; x++)
1691 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
1692 if((x % 8) == 7) src_pixel++;
1693 rgb = src->color_table[src_val];
1694 *dst_pixel++ = rgb.rgbRed << 16 | rgb.rgbGreen << 8 | rgb.rgbBlue;
1696 if(pad_size) memset(dst_pixel, 0, pad_size);
1697 dst_start += dst->stride / 4;
1698 src_start += src->stride;
1705 static void convert_to_32(dib_info *dst, const dib_info *src, const RECT *src_rect)
1707 DWORD *dst_start = get_pixel_ptr_32(dst, 0, 0), *dst_pixel, src_val;
1708 int x, y, pad_size = (dst->width - (src_rect->right - src_rect->left)) * 4;
1710 switch(src->bit_count)
1714 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1716 if(src->funcs == &funcs_8888)
1718 for(y = src_rect->top; y < src_rect->bottom; y++)
1720 dst_pixel = dst_start;
1721 src_pixel = src_start;
1722 for(x = src_rect->left; x < src_rect->right; x++)
1724 src_val = *src_pixel++;
1725 *dst_pixel++ = put_field(src_val >> 16, dst->red_shift, dst->red_len) |
1726 put_field(src_val >> 8, dst->green_shift, dst->green_len) |
1727 put_field(src_val, dst->blue_shift, dst->blue_len);
1729 if(pad_size) memset(dst_pixel, 0, pad_size);
1730 dst_start += dst->stride / 4;
1731 src_start += src->stride / 4;
1734 else if(bit_fields_match(src, dst))
1736 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
1737 memcpy(dst_start, src_start, (src_rect->bottom - src_rect->top) * src->stride);
1740 for(y = src_rect->top; y < src_rect->bottom; y++)
1742 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 4);
1743 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
1744 dst_start += dst->stride / 4;
1745 src_start += src->stride / 4;
1749 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8 &&
1750 dst->red_len == 8 && dst->green_len == 8 && dst->blue_len == 8)
1752 for(y = src_rect->top; y < src_rect->bottom; y++)
1754 dst_pixel = dst_start;
1755 src_pixel = src_start;
1756 for(x = src_rect->left; x < src_rect->right; x++)
1758 src_val = *src_pixel++;
1759 *dst_pixel++ = (((src_val >> src->red_shift) & 0xff) << dst->red_shift) |
1760 (((src_val >> src->green_shift) & 0xff) << dst->green_shift) |
1761 (((src_val >> src->blue_shift) & 0xff) << dst->blue_shift);
1763 if(pad_size) memset(dst_pixel, 0, pad_size);
1764 dst_start += dst->stride / 4;
1765 src_start += src->stride / 4;
1770 for(y = src_rect->top; y < src_rect->bottom; y++)
1772 dst_pixel = dst_start;
1773 src_pixel = src_start;
1774 for(x = src_rect->left; x < src_rect->right; x++)
1776 src_val = *src_pixel++;
1777 *dst_pixel++ = put_field(get_field(src_val, src->red_shift, src->red_len ), dst->red_shift, dst->red_len) |
1778 put_field(get_field(src_val, src->green_shift, src->green_len ), dst->green_shift, dst->green_len) |
1779 put_field(get_field(src_val, src->blue_shift, src->blue_len ), dst->blue_shift, dst->blue_len);
1781 if(pad_size) memset(dst_pixel, 0, pad_size);
1782 dst_start += dst->stride / 4;
1783 src_start += src->stride / 4;
1791 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
1793 for(y = src_rect->top; y < src_rect->bottom; y++)
1795 dst_pixel = dst_start;
1796 src_pixel = src_start;
1797 for(x = src_rect->left; x < src_rect->right; x++)
1800 rgb.rgbBlue = *src_pixel++;
1801 rgb.rgbGreen = *src_pixel++;
1802 rgb.rgbRed = *src_pixel++;
1804 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1805 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1806 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1808 if(pad_size) memset(dst_pixel, 0, pad_size);
1809 dst_start += dst->stride / 4;
1810 src_start += src->stride;
1817 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
1818 if(src->funcs == &funcs_555)
1820 for(y = src_rect->top; y < src_rect->bottom; y++)
1822 dst_pixel = dst_start;
1823 src_pixel = src_start;
1824 for(x = src_rect->left; x < src_rect->right; x++)
1826 src_val = *src_pixel++;
1827 *dst_pixel++ = put_field(((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07), dst->red_shift, dst->red_len) |
1828 put_field(((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07), dst->green_shift, dst->green_len) |
1829 put_field(((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1831 if(pad_size) memset(dst_pixel, 0, pad_size);
1832 dst_start += dst->stride / 4;
1833 src_start += src->stride / 2;
1836 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
1838 for(y = src_rect->top; y < src_rect->bottom; y++)
1840 dst_pixel = dst_start;
1841 src_pixel = src_start;
1842 for(x = src_rect->left; x < src_rect->right; x++)
1844 src_val = *src_pixel++;
1845 *dst_pixel++ = put_field( (((src_val >> src->red_shift) << 3) & 0xf8) |
1846 (((src_val >> src->red_shift) >> 2) & 0x07), dst->red_shift, dst->red_len ) |
1847 put_field( (((src_val >> src->green_shift) << 3) & 0xf8) |
1848 (((src_val >> src->green_shift) >> 2) & 0x07), dst->green_shift, dst->green_len ) |
1849 put_field( (((src_val >> src->blue_shift) << 3) & 0xf8) |
1850 (((src_val >> src->blue_shift) >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1852 if(pad_size) memset(dst_pixel, 0, pad_size);
1853 dst_start += dst->stride / 4;
1854 src_start += src->stride / 2;
1857 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
1859 for(y = src_rect->top; y < src_rect->bottom; y++)
1861 dst_pixel = dst_start;
1862 src_pixel = src_start;
1863 for(x = src_rect->left; x < src_rect->right; x++)
1865 src_val = *src_pixel++;
1866 *dst_pixel++ = put_field( (((src_val >> src->red_shift) << 3) & 0xf8) |
1867 (((src_val >> src->red_shift) >> 2) & 0x07), dst->red_shift, dst->red_len ) |
1868 put_field( (((src_val >> src->green_shift) << 2) & 0xfc) |
1869 (((src_val >> src->green_shift) >> 4) & 0x03), dst->green_shift, dst->green_len ) |
1870 put_field( (((src_val >> src->blue_shift) << 3) & 0xf8) |
1871 (((src_val >> src->blue_shift) >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1873 if(pad_size) memset(dst_pixel, 0, pad_size);
1874 dst_start += dst->stride / 4;
1875 src_start += src->stride / 2;
1880 for(y = src_rect->top; y < src_rect->bottom; y++)
1882 dst_pixel = dst_start;
1883 src_pixel = src_start;
1884 for(x = src_rect->left; x < src_rect->right; x++)
1886 src_val = *src_pixel++;
1887 *dst_pixel++ = put_field(get_field(src_val, src->red_shift, src->red_len ), dst->red_shift, dst->red_len) |
1888 put_field(get_field(src_val, src->green_shift, src->green_len ), dst->green_shift, dst->green_len) |
1889 put_field(get_field(src_val, src->blue_shift, src->blue_len ), dst->blue_shift, dst->blue_len);
1891 if(pad_size) memset(dst_pixel, 0, pad_size);
1892 dst_start += dst->stride / 4;
1893 src_start += src->stride / 2;
1901 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
1902 for(y = src_rect->top; y < src_rect->bottom; y++)
1904 dst_pixel = dst_start;
1905 src_pixel = src_start;
1906 for(x = src_rect->left; x < src_rect->right; x++)
1908 RGBQUAD rgb = src->color_table[*src_pixel++];
1909 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1910 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1911 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1913 if(pad_size) memset(dst_pixel, 0, pad_size);
1914 dst_start += dst->stride / 4;
1915 src_start += src->stride;
1922 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
1923 for(y = src_rect->top; y < src_rect->bottom; y++)
1925 dst_pixel = dst_start;
1926 src_pixel = src_start;
1927 for(x = src_rect->left; x < src_rect->right; x++)
1931 rgb = src->color_table[*src_pixel++ & 0xf];
1933 rgb = src->color_table[*src_pixel >> 4];
1934 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1935 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1936 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1938 if(pad_size) memset(dst_pixel, 0, pad_size);
1939 dst_start += dst->stride / 4;
1940 src_start += src->stride;
1947 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
1948 for(y = src_rect->top; y < src_rect->bottom; y++)
1950 dst_pixel = dst_start;
1951 src_pixel = src_start;
1952 for(x = src_rect->left; x < src_rect->right; x++)
1955 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
1956 if((x % 8) == 7) src_pixel++;
1957 rgb = src->color_table[src_val];
1958 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
1959 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1960 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
1962 if(pad_size) memset(dst_pixel, 0, pad_size);
1963 dst_start += dst->stride / 4;
1964 src_start += src->stride;
1971 static void convert_to_24(dib_info *dst, const dib_info *src, const RECT *src_rect)
1973 BYTE *dst_start = get_pixel_ptr_24(dst, 0, 0), *dst_pixel;
1975 int x, y, pad_size = ((dst->width * 3 + 3) & ~3) - (src_rect->right - src_rect->left) * 3;
1977 switch(src->bit_count)
1981 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1982 if(src->funcs == &funcs_8888)
1984 for(y = src_rect->top; y < src_rect->bottom; y++)
1986 dst_pixel = dst_start;
1987 src_pixel = src_start;
1988 for(x = src_rect->left; x < src_rect->right; x++)
1990 src_val = *src_pixel++;
1991 *dst_pixel++ = src_val & 0xff;
1992 *dst_pixel++ = (src_val >> 8) & 0xff;
1993 *dst_pixel++ = (src_val >> 16) & 0xff;
1995 if(pad_size) memset(dst_pixel, 0, pad_size);
1996 dst_start += dst->stride;
1997 src_start += src->stride / 4;
2000 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
2002 for(y = src_rect->top; y < src_rect->bottom; y++)
2004 dst_pixel = dst_start;
2005 src_pixel = src_start;
2006 for(x = src_rect->left; x < src_rect->right; x++)
2008 src_val = *src_pixel++;
2009 *dst_pixel++ = (src_val >> src->blue_shift) & 0xff;
2010 *dst_pixel++ = (src_val >> src->green_shift) & 0xff;
2011 *dst_pixel++ = (src_val >> src->red_shift) & 0xff;
2013 if(pad_size) memset(dst_pixel, 0, pad_size);
2014 dst_start += dst->stride;
2015 src_start += src->stride / 4;
2020 for(y = src_rect->top; y < src_rect->bottom; y++)
2022 dst_pixel = dst_start;
2023 src_pixel = src_start;
2024 for(x = src_rect->left; x < src_rect->right; x++)
2026 src_val = *src_pixel++;
2027 *dst_pixel++ = get_field( src_val, src->blue_shift, src->blue_len );
2028 *dst_pixel++ = get_field( src_val, src->green_shift, src->green_len );
2029 *dst_pixel++ = get_field( src_val, src->red_shift, src->red_len );
2031 if(pad_size) memset(dst_pixel, 0, pad_size);
2032 dst_start += dst->stride;
2033 src_start += src->stride / 4;
2041 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top);
2043 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
2044 memcpy(dst_start, src_start, (src_rect->bottom - src_rect->top) * src->stride);
2047 for(y = src_rect->top; y < src_rect->bottom; y++)
2049 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 3);
2050 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left) * 3, 0, pad_size);
2051 dst_start += dst->stride;
2052 src_start += src->stride;
2060 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2061 if(src->funcs == &funcs_555)
2063 for(y = src_rect->top; y < src_rect->bottom; y++)
2065 dst_pixel = dst_start;
2066 src_pixel = src_start;
2067 for(x = src_rect->left; x < src_rect->right; x++)
2069 src_val = *src_pixel++;
2070 *dst_pixel++ = ((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07);
2071 *dst_pixel++ = ((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07);
2072 *dst_pixel++ = ((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07);
2074 if(pad_size) memset(dst_pixel, 0, pad_size);
2075 dst_start += dst->stride;
2076 src_start += src->stride / 2;
2079 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2081 for(y = src_rect->top; y < src_rect->bottom; y++)
2083 dst_pixel = dst_start;
2084 src_pixel = src_start;
2085 for(x = src_rect->left; x < src_rect->right; x++)
2087 src_val = *src_pixel++;
2088 *dst_pixel++ = (((src_val >> src->blue_shift) << 3) & 0xf8) |
2089 (((src_val >> src->blue_shift) >> 2) & 0x07);
2090 *dst_pixel++ = (((src_val >> src->green_shift) << 3) & 0xf8) |
2091 (((src_val >> src->green_shift) >> 2) & 0x07);
2092 *dst_pixel++ = (((src_val >> src->red_shift) << 3) & 0xf8) |
2093 (((src_val >> src->red_shift) >> 2) & 0x07);
2095 if(pad_size) memset(dst_pixel, 0, pad_size);
2096 dst_start += dst->stride;
2097 src_start += src->stride / 2;
2100 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2102 for(y = src_rect->top; y < src_rect->bottom; y++)
2104 dst_pixel = dst_start;
2105 src_pixel = src_start;
2106 for(x = src_rect->left; x < src_rect->right; x++)
2108 src_val = *src_pixel++;
2109 *dst_pixel++ = (((src_val >> src->blue_shift) << 3) & 0xf8) |
2110 (((src_val >> src->blue_shift) >> 2) & 0x07);
2111 *dst_pixel++ = (((src_val >> src->green_shift) << 2) & 0xfc) |
2112 (((src_val >> src->green_shift) >> 4) & 0x03);
2113 *dst_pixel++ = (((src_val >> src->red_shift) << 3) & 0xf8) |
2114 (((src_val >> src->red_shift) >> 2) & 0x07);
2116 if(pad_size) memset(dst_pixel, 0, pad_size);
2117 dst_start += dst->stride;
2118 src_start += src->stride / 2;
2123 for(y = src_rect->top; y < src_rect->bottom; y++)
2125 dst_pixel = dst_start;
2126 src_pixel = src_start;
2127 for(x = src_rect->left; x < src_rect->right; x++)
2129 src_val = *src_pixel++;
2130 *dst_pixel++ = get_field(src_val, src->blue_shift, src->blue_len );
2131 *dst_pixel++ = get_field(src_val, src->green_shift, src->green_len );
2132 *dst_pixel++ = get_field(src_val, src->red_shift, src->red_len );
2134 if(pad_size) memset(dst_pixel, 0, pad_size);
2135 dst_start += dst->stride;
2136 src_start += src->stride / 2;
2144 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
2145 for(y = src_rect->top; y < src_rect->bottom; y++)
2147 dst_pixel = dst_start;
2148 src_pixel = src_start;
2149 for(x = src_rect->left; x < src_rect->right; x++)
2151 RGBQUAD rgb = src->color_table[*src_pixel++];
2152 *dst_pixel++ = rgb.rgbBlue;
2153 *dst_pixel++ = rgb.rgbGreen;
2154 *dst_pixel++ = rgb.rgbRed;
2156 if(pad_size) memset(dst_pixel, 0, pad_size);
2157 dst_start += dst->stride;
2158 src_start += src->stride;
2165 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
2166 for(y = src_rect->top; y < src_rect->bottom; y++)
2168 dst_pixel = dst_start;
2169 src_pixel = src_start;
2170 for(x = src_rect->left; x < src_rect->right; x++)
2174 rgb = src->color_table[*src_pixel++ & 0xf];
2176 rgb = src->color_table[*src_pixel >> 4];
2177 *dst_pixel++ = rgb.rgbBlue;
2178 *dst_pixel++ = rgb.rgbGreen;
2179 *dst_pixel++ = rgb.rgbRed;
2181 if(pad_size) memset(dst_pixel, 0, pad_size);
2182 dst_start += dst->stride;
2183 src_start += src->stride;
2190 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
2191 for(y = src_rect->top; y < src_rect->bottom; y++)
2193 dst_pixel = dst_start;
2194 src_pixel = src_start;
2195 for(x = src_rect->left; x < src_rect->right; x++)
2198 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
2199 if((x % 8) == 7) src_pixel++;
2200 rgb = src->color_table[src_val];
2201 *dst_pixel++ = rgb.rgbBlue;
2202 *dst_pixel++ = rgb.rgbGreen;
2203 *dst_pixel++ = rgb.rgbRed;
2205 if(pad_size) memset(dst_pixel, 0, pad_size);
2206 dst_start += dst->stride;
2207 src_start += src->stride;
2214 static void convert_to_555(dib_info *dst, const dib_info *src, const RECT *src_rect)
2216 WORD *dst_start = get_pixel_ptr_16(dst, 0, 0), *dst_pixel;
2217 INT x, y, pad_size = ((dst->width + 1) & ~1) * 2 - (src_rect->right - src_rect->left) * 2;
2220 switch(src->bit_count)
2224 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
2226 if(src->funcs == &funcs_8888)
2228 for(y = src_rect->top; y < src_rect->bottom; y++)
2230 dst_pixel = dst_start;
2231 src_pixel = src_start;
2232 for(x = src_rect->left; x < src_rect->right; x++)
2234 src_val = *src_pixel++;
2235 *dst_pixel++ = ((src_val >> 9) & 0x7c00) |
2236 ((src_val >> 6) & 0x03e0) |
2237 ((src_val >> 3) & 0x001f);
2239 if(pad_size) memset(dst_pixel, 0, pad_size);
2240 dst_start += dst->stride / 2;
2241 src_start += src->stride / 4;
2244 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
2246 for(y = src_rect->top; y < src_rect->bottom; y++)
2248 dst_pixel = dst_start;
2249 src_pixel = src_start;
2250 for(x = src_rect->left; x < src_rect->right; x++)
2252 src_val = *src_pixel++;
2253 *dst_pixel++ = (((src_val >> src->red_shift) << 7) & 0x7c00) |
2254 (((src_val >> src->green_shift) << 2) & 0x03e0) |
2255 (((src_val >> src->blue_shift) >> 3) & 0x001f);
2257 if(pad_size) memset(dst_pixel, 0, pad_size);
2258 dst_start += dst->stride / 2;
2259 src_start += src->stride / 4;
2264 for(y = src_rect->top; y < src_rect->bottom; y++)
2266 dst_pixel = dst_start;
2267 src_pixel = src_start;
2268 for(x = src_rect->left; x < src_rect->right; x++)
2270 src_val = *src_pixel++;
2271 *dst_pixel++ = (((get_field(src_val, src->red_shift, src->red_len ) << 7) & 0x7c00) |
2272 ((get_field(src_val, src->green_shift, src->green_len ) << 2) & 0x03e0) |
2273 ( get_field(src_val, src->blue_shift, src->blue_len ) >> 3));
2275 if(pad_size) memset(dst_pixel, 0, pad_size);
2276 dst_start += dst->stride / 2;
2277 src_start += src->stride / 4;
2285 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
2287 for(y = src_rect->top; y < src_rect->bottom; y++)
2289 dst_pixel = dst_start;
2290 src_pixel = src_start;
2291 for(x = src_rect->left; x < src_rect->right; x++)
2294 rgb.rgbBlue = *src_pixel++;
2295 rgb.rgbGreen = *src_pixel++;
2296 rgb.rgbRed = *src_pixel++;
2298 *dst_pixel++ = ((rgb.rgbRed << 7) & 0x7c00) |
2299 ((rgb.rgbGreen << 2) & 0x03e0) |
2300 ((rgb.rgbBlue >> 3) & 0x001f);
2302 if(pad_size) memset(dst_pixel, 0, pad_size);
2303 dst_start += dst->stride / 2;
2304 src_start += src->stride;
2311 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2312 if(src->funcs == &funcs_555)
2314 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
2315 memcpy(dst_start, src_start, (src_rect->bottom - src_rect->top) * src->stride);
2318 for(y = src_rect->top; y < src_rect->bottom; y++)
2320 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 2);
2321 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
2322 dst_start += dst->stride / 2;
2323 src_start += src->stride / 2;
2327 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2329 for(y = src_rect->top; y < src_rect->bottom; y++)
2331 dst_pixel = dst_start;
2332 src_pixel = src_start;
2333 for(x = src_rect->left; x < src_rect->right; x++)
2335 src_val = *src_pixel++;
2336 *dst_pixel++ = (((src_val >> src->red_shift) << 10) & 0x7c00) |
2337 (((src_val >> src->green_shift) << 5) & 0x03e0) |
2338 ( (src_val >> src->blue_shift) & 0x001f);
2340 if(pad_size) memset(dst_pixel, 0, pad_size);
2341 dst_start += dst->stride / 2;
2342 src_start += src->stride / 2;
2345 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2347 for(y = src_rect->top; y < src_rect->bottom; y++)
2349 dst_pixel = dst_start;
2350 src_pixel = src_start;
2351 for(x = src_rect->left; x < src_rect->right; x++)
2353 src_val = *src_pixel++;
2354 *dst_pixel++ = (((src_val >> src->red_shift) << 10) & 0x7c00) |
2355 (((src_val >> src->green_shift) << 4) & 0x03e0) |
2356 ( (src_val >> src->blue_shift) & 0x001f);
2358 if(pad_size) memset(dst_pixel, 0, pad_size);
2359 dst_start += dst->stride / 2;
2360 src_start += src->stride / 2;
2365 for(y = src_rect->top; y < src_rect->bottom; y++)
2367 dst_pixel = dst_start;
2368 src_pixel = src_start;
2369 for(x = src_rect->left; x < src_rect->right; x++)
2371 src_val = *src_pixel++;
2372 *dst_pixel++ = (((get_field(src_val, src->red_shift, src->red_len) << 7) & 0x7c00) |
2373 ((get_field(src_val, src->green_shift, src->green_len) << 2) & 0x03e0) |
2374 ( get_field(src_val, src->blue_shift, src->blue_len) >> 3));
2376 if(pad_size) memset(dst_pixel, 0, pad_size);
2377 dst_start += dst->stride / 2;
2378 src_start += src->stride / 2;
2386 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
2387 for(y = src_rect->top; y < src_rect->bottom; y++)
2389 dst_pixel = dst_start;
2390 src_pixel = src_start;
2391 for(x = src_rect->left; x < src_rect->right; x++)
2393 RGBQUAD rgb = src->color_table[*src_pixel++];
2394 *dst_pixel++ = ((rgb.rgbRed << 7) & 0x7c00) |
2395 ((rgb.rgbGreen << 2) & 0x03e0) |
2396 ((rgb.rgbBlue >> 3) & 0x001f);
2398 if(pad_size) memset(dst_pixel, 0, pad_size);
2399 dst_start += dst->stride / 2;
2400 src_start += src->stride;
2407 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
2408 for(y = src_rect->top; y < src_rect->bottom; y++)
2410 dst_pixel = dst_start;
2411 src_pixel = src_start;
2412 for(x = src_rect->left; x < src_rect->right; x++)
2416 rgb = src->color_table[*src_pixel++ & 0xf];
2418 rgb = src->color_table[*src_pixel >> 4];
2419 *dst_pixel++ = ((rgb.rgbRed << 7) & 0x7c00) |
2420 ((rgb.rgbGreen << 2) & 0x03e0) |
2421 ((rgb.rgbBlue >> 3) & 0x001f);
2423 if(pad_size) memset(dst_pixel, 0, pad_size);
2424 dst_start += dst->stride / 2;
2425 src_start += src->stride;
2432 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
2433 for(y = src_rect->top; y < src_rect->bottom; y++)
2435 dst_pixel = dst_start;
2436 src_pixel = src_start;
2437 for(x = src_rect->left; x < src_rect->right; x++)
2440 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
2441 if((x % 8) == 7) src_pixel++;
2442 rgb = src->color_table[src_val];
2443 *dst_pixel++ = ((rgb.rgbRed << 7) & 0x7c00) |
2444 ((rgb.rgbGreen << 2) & 0x03e0) |
2445 ((rgb.rgbBlue >> 3) & 0x001f);
2447 if(pad_size) memset(dst_pixel, 0, pad_size);
2448 dst_start += dst->stride / 2;
2449 src_start += src->stride;
2456 static void convert_to_16(dib_info *dst, const dib_info *src, const RECT *src_rect)
2458 WORD *dst_start = get_pixel_ptr_16(dst, 0, 0), *dst_pixel;
2459 INT x, y, pad_size = ((dst->width + 1) & ~1) * 2 - (src_rect->right - src_rect->left) * 2;
2462 switch(src->bit_count)
2466 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
2468 if(src->funcs == &funcs_8888)
2470 for(y = src_rect->top; y < src_rect->bottom; y++)
2472 dst_pixel = dst_start;
2473 src_pixel = src_start;
2474 for(x = src_rect->left; x < src_rect->right; x++)
2476 src_val = *src_pixel++;
2477 *dst_pixel++ = put_field(src_val >> 16, dst->red_shift, dst->red_len) |
2478 put_field(src_val >> 8, dst->green_shift, dst->green_len) |
2479 put_field(src_val, dst->blue_shift, dst->blue_len);
2481 if(pad_size) memset(dst_pixel, 0, pad_size);
2482 dst_start += dst->stride / 2;
2483 src_start += src->stride / 4;
2486 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
2488 for(y = src_rect->top; y < src_rect->bottom; y++)
2490 dst_pixel = dst_start;
2491 src_pixel = src_start;
2492 for(x = src_rect->left; x < src_rect->right; x++)
2494 src_val = *src_pixel++;
2495 *dst_pixel++ = put_field(src_val >> src->red_shift, dst->red_shift, dst->red_len) |
2496 put_field(src_val >> src->green_shift, dst->green_shift, dst->green_len) |
2497 put_field(src_val >> src->blue_shift, dst->blue_shift, dst->blue_len);
2499 if(pad_size) memset(dst_pixel, 0, pad_size);
2500 dst_start += dst->stride / 2;
2501 src_start += src->stride / 4;
2506 for(y = src_rect->top; y < src_rect->bottom; y++)
2508 dst_pixel = dst_start;
2509 src_pixel = src_start;
2510 for(x = src_rect->left; x < src_rect->right; x++)
2512 src_val = *src_pixel++;
2513 *dst_pixel++ = put_field(get_field(src_val, src->red_shift, src->red_len ), dst->red_shift, dst->red_len) |
2514 put_field(get_field(src_val, src->green_shift, src->green_len ), dst->green_shift, dst->green_len) |
2515 put_field(get_field(src_val, src->blue_shift, src->blue_len ), dst->blue_shift, dst->blue_len);
2517 if(pad_size) memset(dst_pixel, 0, pad_size);
2518 dst_start += dst->stride / 2;
2519 src_start += src->stride / 4;
2527 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
2529 for(y = src_rect->top; y < src_rect->bottom; y++)
2531 dst_pixel = dst_start;
2532 src_pixel = src_start;
2533 for(x = src_rect->left; x < src_rect->right; x++)
2536 rgb.rgbBlue = *src_pixel++;
2537 rgb.rgbGreen = *src_pixel++;
2538 rgb.rgbRed = *src_pixel++;
2540 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
2541 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
2542 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
2544 if(pad_size) memset(dst_pixel, 0, pad_size);
2545 dst_start += dst->stride / 2;
2546 src_start += src->stride;
2553 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2554 if(src->funcs == &funcs_555)
2556 for(y = src_rect->top; y < src_rect->bottom; y++)
2558 dst_pixel = dst_start;
2559 src_pixel = src_start;
2560 for(x = src_rect->left; x < src_rect->right; x++)
2562 src_val = *src_pixel++;
2563 *dst_pixel++ = put_field(((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07), dst->red_shift, dst->red_len) |
2564 put_field(((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07), dst->green_shift, dst->green_len) |
2565 put_field(((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07), dst->blue_shift, dst->blue_len);
2567 if(pad_size) memset(dst_pixel, 0, pad_size);
2568 dst_start += dst->stride / 2;
2569 src_start += src->stride / 2;
2572 else if(bit_fields_match(src, dst))
2574 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
2575 memcpy(dst_start, src_start, (src_rect->bottom - src_rect->top) * src->stride);
2578 for(y = src_rect->top; y < src_rect->bottom; y++)
2580 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 2);
2581 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
2582 dst_start += dst->stride / 2;
2583 src_start += src->stride / 2;
2587 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2589 for(y = src_rect->top; y < src_rect->bottom; y++)
2591 dst_pixel = dst_start;
2592 src_pixel = src_start;
2593 for(x = src_rect->left; x < src_rect->right; x++)
2595 src_val = *src_pixel++;
2596 *dst_pixel++ = put_field( (((src_val >> src->red_shift) << 3) & 0xf8) |
2597 (((src_val >> src->red_shift) >> 2) & 0x07), dst->red_shift, dst->red_len ) |
2598 put_field( (((src_val >> src->green_shift) << 3) & 0xf8) |
2599 (((src_val >> src->green_shift) >> 2) & 0x07), dst->green_shift, dst->green_len ) |
2600 put_field( (((src_val >> src->blue_shift) << 3) & 0xf8) |
2601 (((src_val >> src->blue_shift) >> 2) & 0x07), dst->blue_shift, dst->blue_len);
2603 if(pad_size) memset(dst_pixel, 0, pad_size);
2604 dst_start += dst->stride / 2;
2605 src_start += src->stride / 2;
2608 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2610 for(y = src_rect->top; y < src_rect->bottom; y++)
2612 dst_pixel = dst_start;
2613 src_pixel = src_start;
2614 for(x = src_rect->left; x < src_rect->right; x++)
2616 src_val = *src_pixel++;
2617 *dst_pixel++ = put_field( (((src_val >> src->red_shift) << 3) & 0xf8) |
2618 (((src_val >> src->red_shift) >> 2) & 0x07), dst->red_shift, dst->red_len ) |
2619 put_field( (((src_val >> src->green_shift) << 2) & 0xfc) |
2620 (((src_val >> src->green_shift) >> 4) & 0x03), dst->green_shift, dst->green_len ) |
2621 put_field( (((src_val >> src->blue_shift) << 3) & 0xf8) |
2622 (((src_val >> src->blue_shift) >> 2) & 0x07), dst->blue_shift, dst->blue_len);
2624 if(pad_size) memset(dst_pixel, 0, pad_size);
2625 dst_start += dst->stride / 2;
2626 src_start += src->stride / 2;
2631 for(y = src_rect->top; y < src_rect->bottom; y++)
2633 dst_pixel = dst_start;
2634 src_pixel = src_start;
2635 for(x = src_rect->left; x < src_rect->right; x++)
2637 src_val = *src_pixel++;
2638 *dst_pixel++ = put_field(get_field(src_val, src->red_shift, src->red_len ), dst->red_shift, dst->red_len) |
2639 put_field(get_field(src_val, src->green_shift, src->green_len ), dst->green_shift, dst->green_len) |
2640 put_field(get_field(src_val, src->blue_shift, src->blue_len ), dst->blue_shift, dst->blue_len);
2642 if(pad_size) memset(dst_pixel, 0, pad_size);
2643 dst_start += dst->stride / 2;
2644 src_start += src->stride / 2;
2652 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
2653 for(y = src_rect->top; y < src_rect->bottom; y++)
2655 dst_pixel = dst_start;
2656 src_pixel = src_start;
2657 for(x = src_rect->left; x < src_rect->right; x++)
2659 RGBQUAD rgb = src->color_table[*src_pixel++];
2660 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
2661 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
2662 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
2664 if(pad_size) memset(dst_pixel, 0, pad_size);
2665 dst_start += dst->stride / 2;
2666 src_start += src->stride;
2673 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
2674 for(y = src_rect->top; y < src_rect->bottom; y++)
2676 dst_pixel = dst_start;
2677 src_pixel = src_start;
2678 for(x = src_rect->left; x < src_rect->right; x++)
2682 rgb = src->color_table[*src_pixel++ & 0xf];
2684 rgb = src->color_table[*src_pixel >> 4];
2685 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
2686 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
2687 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
2689 if(pad_size) memset(dst_pixel, 0, pad_size);
2690 dst_start += dst->stride / 2;
2691 src_start += src->stride;
2698 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
2699 for(y = src_rect->top; y < src_rect->bottom; y++)
2701 dst_pixel = dst_start;
2702 src_pixel = src_start;
2703 for(x = src_rect->left; x < src_rect->right; x++)
2706 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
2707 if((x % 8) == 7) src_pixel++;
2708 rgb = src->color_table[src_val];
2709 *dst_pixel++ = put_field(rgb.rgbRed, dst->red_shift, dst->red_len) |
2710 put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
2711 put_field(rgb.rgbBlue, dst->blue_shift, dst->blue_len);
2713 if(pad_size) memset(dst_pixel, 0, pad_size);
2714 dst_start += dst->stride / 2;
2715 src_start += src->stride;
2722 static inline BOOL color_tables_match(const dib_info *d1, const dib_info *d2)
2724 return !memcmp(d1->color_table, d2->color_table, (1 << d1->bit_count) * sizeof(d1->color_table[0]));
2727 static inline DWORD rgb_lookup_colortable(const dib_info *dst, BYTE r, BYTE g, BYTE b)
2729 /* Windows reduces precision to 5 bits, probably in order to build some sort of lookup cache */
2730 return rgb_to_pixel_colortable( dst, (r & ~7) + 4, (g & ~7) + 4, (b & ~7) + 4 );
2733 static void convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rect)
2735 BYTE *dst_start = get_pixel_ptr_8(dst, 0, 0), *dst_pixel;
2736 INT x, y, pad_size = ((dst->width + 3) & ~3) - (src_rect->right - src_rect->left);
2739 switch(src->bit_count)
2743 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
2745 if(src->funcs == &funcs_8888)
2747 for(y = src_rect->top; y < src_rect->bottom; y++)
2749 dst_pixel = dst_start;
2750 src_pixel = src_start;
2751 for(x = src_rect->left; x < src_rect->right; x++)
2753 src_val = *src_pixel++;
2754 *dst_pixel++ = rgb_lookup_colortable(dst, src_val >> 16, src_val >> 8, src_val );
2756 if(pad_size) memset(dst_pixel, 0, pad_size);
2757 dst_start += dst->stride;
2758 src_start += src->stride / 4;
2761 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
2763 for(y = src_rect->top; y < src_rect->bottom; y++)
2765 dst_pixel = dst_start;
2766 src_pixel = src_start;
2767 for(x = src_rect->left; x < src_rect->right; x++)
2769 src_val = *src_pixel++;
2770 *dst_pixel++ = rgb_lookup_colortable(dst,
2771 src_val >> src->red_shift,
2772 src_val >> src->green_shift,
2773 src_val >> src->blue_shift );
2775 if(pad_size) memset(dst_pixel, 0, pad_size);
2776 dst_start += dst->stride;
2777 src_start += src->stride / 4;
2782 for(y = src_rect->top; y < src_rect->bottom; y++)
2784 dst_pixel = dst_start;
2785 src_pixel = src_start;
2786 for(x = src_rect->left; x < src_rect->right; x++)
2788 src_val = *src_pixel++;
2789 *dst_pixel++ = rgb_lookup_colortable(dst,
2790 get_field(src_val, src->red_shift, src->red_len),
2791 get_field(src_val, src->green_shift, src->green_len),
2792 get_field(src_val, src->blue_shift, src->blue_len));
2794 if(pad_size) memset(dst_pixel, 0, pad_size);
2795 dst_start += dst->stride;
2796 src_start += src->stride / 4;
2804 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
2806 for(y = src_rect->top; y < src_rect->bottom; y++)
2808 dst_pixel = dst_start;
2809 src_pixel = src_start;
2810 for(x = src_rect->left; x < src_rect->right; x++, src_pixel += 3)
2812 *dst_pixel++ = rgb_lookup_colortable(dst, src_pixel[2], src_pixel[1], src_pixel[0] );
2814 if(pad_size) memset(dst_pixel, 0, pad_size);
2815 dst_start += dst->stride;
2816 src_start += src->stride;
2823 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2824 if(src->funcs == &funcs_555)
2826 for(y = src_rect->top; y < src_rect->bottom; y++)
2828 dst_pixel = dst_start;
2829 src_pixel = src_start;
2830 for(x = src_rect->left; x < src_rect->right; x++)
2832 src_val = *src_pixel++;
2833 *dst_pixel++ = rgb_lookup_colortable(dst,
2834 ((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07),
2835 ((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07),
2836 ((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07) );
2838 if(pad_size) memset(dst_pixel, 0, pad_size);
2839 dst_start += dst->stride;
2840 src_start += src->stride / 2;
2843 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2845 for(y = src_rect->top; y < src_rect->bottom; y++)
2847 dst_pixel = dst_start;
2848 src_pixel = src_start;
2849 for(x = src_rect->left; x < src_rect->right; x++)
2851 src_val = *src_pixel++;
2852 *dst_pixel++ = rgb_lookup_colortable(dst,
2853 (((src_val >> src->red_shift) << 3) & 0xf8) |
2854 (((src_val >> src->red_shift) >> 2) & 0x07),
2855 (((src_val >> src->green_shift) << 3) & 0xf8) |
2856 (((src_val >> src->green_shift) >> 2) & 0x07),
2857 (((src_val >> src->blue_shift) << 3) & 0xf8) |
2858 (((src_val >> src->blue_shift) >> 2) & 0x07) );
2860 if(pad_size) memset(dst_pixel, 0, pad_size);
2861 dst_start += dst->stride;
2862 src_start += src->stride / 2;
2865 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2867 for(y = src_rect->top; y < src_rect->bottom; y++)
2869 dst_pixel = dst_start;
2870 src_pixel = src_start;
2871 for(x = src_rect->left; x < src_rect->right; x++)
2873 src_val = *src_pixel++;
2874 *dst_pixel++ = rgb_lookup_colortable(dst,
2875 (((src_val >> src->red_shift) << 3) & 0xf8) |
2876 (((src_val >> src->red_shift) >> 2) & 0x07),
2877 (((src_val >> src->green_shift) << 2) & 0xfc) |
2878 (((src_val >> src->green_shift) >> 4) & 0x03),
2879 (((src_val >> src->blue_shift) << 3) & 0xf8) |
2880 (((src_val >> src->blue_shift) >> 2) & 0x07) );
2882 if(pad_size) memset(dst_pixel, 0, pad_size);
2883 dst_start += dst->stride;
2884 src_start += src->stride / 2;
2889 for(y = src_rect->top; y < src_rect->bottom; y++)
2891 dst_pixel = dst_start;
2892 src_pixel = src_start;
2893 for(x = src_rect->left; x < src_rect->right; x++)
2895 src_val = *src_pixel++;
2896 *dst_pixel++ = rgb_lookup_colortable(dst,
2897 get_field(src_val, src->red_shift, src->red_len),
2898 get_field(src_val, src->green_shift, src->green_len),
2899 get_field(src_val, src->blue_shift, src->blue_len));
2901 if(pad_size) memset(dst_pixel, 0, pad_size);
2902 dst_start += dst->stride;
2903 src_start += src->stride / 2;
2911 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
2913 if(color_tables_match(dst, src))
2915 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
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);
2922 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
2923 dst_start += dst->stride;
2924 src_start += src->stride;
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 RGBQUAD rgb = src->color_table[*src_pixel++];
2937 *dst_pixel++ = rgb_to_pixel_colortable(dst, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
2939 if(pad_size) memset(dst_pixel, 0, pad_size);
2940 dst_start += dst->stride;
2941 src_start += src->stride;
2949 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
2950 for(y = src_rect->top; y < src_rect->bottom; y++)
2952 dst_pixel = dst_start;
2953 src_pixel = src_start;
2954 for(x = src_rect->left; x < src_rect->right; x++)
2958 rgb = src->color_table[*src_pixel++ & 0xf];
2960 rgb = src->color_table[*src_pixel >> 4];
2961 *dst_pixel++ = rgb_to_pixel_colortable(dst, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
2963 if(pad_size) memset(dst_pixel, 0, pad_size);
2964 dst_start += dst->stride;
2965 src_start += src->stride;
2972 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
2973 for(y = src_rect->top; y < src_rect->bottom; y++)
2975 dst_pixel = dst_start;
2976 src_pixel = src_start;
2977 for(x = src_rect->left; x < src_rect->right; x++)
2980 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
2981 if((x % 8) == 7) src_pixel++;
2982 rgb = src->color_table[src_val];
2983 *dst_pixel++ = rgb_to_pixel_colortable(dst, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
2985 if(pad_size) memset(dst_pixel, 0, pad_size);
2986 dst_start += dst->stride;
2987 src_start += src->stride;
2994 static void convert_to_4(dib_info *dst, const dib_info *src, const RECT *src_rect)
2996 BYTE *dst_start = get_pixel_ptr_4(dst, 0, 0), *dst_pixel, dst_val;
2997 INT x, y, pad_size = ((dst->width + 7) & ~7) / 2 - (src_rect->right - src_rect->left + 1) / 2;
3000 switch(src->bit_count)
3004 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
3006 if(src->funcs == &funcs_8888)
3008 for(y = src_rect->top; y < src_rect->bottom; y++)
3010 dst_pixel = dst_start;
3011 src_pixel = src_start;
3012 for(x = src_rect->left; x < src_rect->right; x++)
3014 src_val = *src_pixel++;
3015 dst_val = rgb_to_pixel_colortable(dst, src_val >> 16, src_val >> 8, src_val);
3016 if((x - src_rect->left) & 1)
3018 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3022 *dst_pixel = (dst_val << 4) & 0xf0;
3026 if((x - src_rect->left) & 1) dst_pixel++;
3027 memset(dst_pixel, 0, pad_size);
3029 dst_start += dst->stride;
3030 src_start += src->stride / 4;
3033 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
3035 for(y = src_rect->top; y < src_rect->bottom; y++)
3037 dst_pixel = dst_start;
3038 src_pixel = src_start;
3039 for(x = src_rect->left; x < src_rect->right; x++)
3041 src_val = *src_pixel++;
3042 dst_val = rgb_to_pixel_colortable(dst,
3043 src_val >> src->red_shift,
3044 src_val >> src->green_shift,
3045 src_val >> src->blue_shift);
3046 if((x - src_rect->left) & 1)
3048 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3052 *dst_pixel = (dst_val << 4) & 0xf0;
3056 if((x - src_rect->left) & 1) dst_pixel++;
3057 memset(dst_pixel, 0, pad_size);
3059 dst_start += dst->stride;
3060 src_start += src->stride / 4;
3065 for(y = src_rect->top; y < src_rect->bottom; y++)
3067 dst_pixel = dst_start;
3068 src_pixel = src_start;
3069 for(x = src_rect->left; x < src_rect->right; x++)
3071 src_val = *src_pixel++;
3072 dst_val = rgb_to_pixel_colortable(dst,
3073 get_field(src_val, src->red_shift, src->red_len),
3074 get_field(src_val, src->green_shift, src->green_len),
3075 get_field(src_val, src->blue_shift, src->blue_len));
3076 if((x - src_rect->left) & 1)
3078 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3082 *dst_pixel = (dst_val << 4) & 0xf0;
3086 if((x - src_rect->left) & 1) dst_pixel++;
3087 memset(dst_pixel, 0, pad_size);
3089 dst_start += dst->stride;
3090 src_start += src->stride / 4;
3098 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
3100 for(y = src_rect->top; y < src_rect->bottom; y++)
3102 dst_pixel = dst_start;
3103 src_pixel = src_start;
3104 for(x = src_rect->left; x < src_rect->right; x++, src_pixel += 3)
3106 dst_val = rgb_to_pixel_colortable(dst, src_pixel[2], src_pixel[1], src_pixel[0]);
3108 if((x - src_rect->left) & 1)
3110 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3114 *dst_pixel = (dst_val << 4) & 0xf0;
3118 if((x - src_rect->left) & 1) dst_pixel++;
3119 memset(dst_pixel, 0, pad_size);
3121 dst_start += dst->stride;
3122 src_start += src->stride;
3129 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
3130 if(src->funcs == &funcs_555)
3132 for(y = src_rect->top; y < src_rect->bottom; y++)
3134 dst_pixel = dst_start;
3135 src_pixel = src_start;
3136 for(x = src_rect->left; x < src_rect->right; x++)
3138 src_val = *src_pixel++;
3139 dst_val = rgb_to_pixel_colortable(dst,
3140 ((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07),
3141 ((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07),
3142 ((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07) );
3143 if((x - src_rect->left) & 1)
3145 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3149 *dst_pixel = (dst_val << 4) & 0xf0;
3153 if((x - src_rect->left) & 1) dst_pixel++;
3154 memset(dst_pixel, 0, pad_size);
3156 dst_start += dst->stride;
3157 src_start += src->stride / 2;
3160 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
3162 for(y = src_rect->top; y < src_rect->bottom; y++)
3164 dst_pixel = dst_start;
3165 src_pixel = src_start;
3166 for(x = src_rect->left; x < src_rect->right; x++)
3168 src_val = *src_pixel++;
3169 dst_val = rgb_to_pixel_colortable(dst,
3170 (((src_val >> src->red_shift) << 3) & 0xf8) |
3171 (((src_val >> src->red_shift) >> 2) & 0x07),
3172 (((src_val >> src->green_shift) << 3) & 0xf8) |
3173 (((src_val >> src->green_shift) >> 2) & 0x07),
3174 (((src_val >> src->blue_shift) << 3) & 0xf8) |
3175 (((src_val >> src->blue_shift) >> 2) & 0x07) );
3176 if((x - src_rect->left) & 1)
3178 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3182 *dst_pixel = (dst_val << 4) & 0xf0;
3186 if((x - src_rect->left) & 1) dst_pixel++;
3187 memset(dst_pixel, 0, pad_size);
3189 dst_start += dst->stride;
3190 src_start += src->stride / 2;
3193 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
3195 for(y = src_rect->top; y < src_rect->bottom; y++)
3197 dst_pixel = dst_start;
3198 src_pixel = src_start;
3199 for(x = src_rect->left; x < src_rect->right; x++)
3201 src_val = *src_pixel++;
3202 dst_val = rgb_to_pixel_colortable(dst,
3203 (((src_val >> src->red_shift) << 3) & 0xf8) |
3204 (((src_val >> src->red_shift) >> 2) & 0x07),
3205 (((src_val >> src->green_shift) << 2) & 0xfc) |
3206 (((src_val >> src->green_shift) >> 4) & 0x03),
3207 (((src_val >> src->blue_shift) << 3) & 0xf8) |
3208 (((src_val >> src->blue_shift) >> 2) & 0x07) );
3209 if((x - src_rect->left) & 1)
3211 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3215 *dst_pixel = (dst_val << 4) & 0xf0;
3219 if((x - src_rect->left) & 1) dst_pixel++;
3220 memset(dst_pixel, 0, pad_size);
3222 dst_start += dst->stride;
3223 src_start += src->stride / 2;
3228 for(y = src_rect->top; y < src_rect->bottom; y++)
3230 dst_pixel = dst_start;
3231 src_pixel = src_start;
3232 for(x = src_rect->left; x < src_rect->right; x++)
3234 src_val = *src_pixel++;
3235 dst_val = rgb_to_pixel_colortable(dst,
3236 get_field(src_val, src->red_shift, src->red_len),
3237 get_field(src_val, src->green_shift, src->green_len),
3238 get_field(src_val, src->blue_shift, src->blue_len));
3239 if((x - src_rect->left) & 1)
3241 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3245 *dst_pixel = (dst_val << 4) & 0xf0;
3249 if((x - src_rect->left) & 1) dst_pixel++;
3250 memset(dst_pixel, 0, pad_size);
3252 dst_start += dst->stride;
3253 src_start += src->stride / 2;
3261 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
3263 for(y = src_rect->top; y < src_rect->bottom; y++)
3265 dst_pixel = dst_start;
3266 src_pixel = src_start;
3267 for(x = src_rect->left; x < src_rect->right; x++)
3269 RGBQUAD rgb = src->color_table[*src_pixel++];
3270 dst_val = rgb_to_pixel_colortable(dst, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
3271 if((x - src_rect->left) & 1)
3273 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3277 *dst_pixel = (dst_val << 4) & 0xf0;
3281 if((x - src_rect->left) & 1) dst_pixel++;
3282 memset(dst_pixel, 0, pad_size);
3284 dst_start += dst->stride;
3285 src_start += src->stride;
3292 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
3294 if(color_tables_match(dst, src) && (src_rect->left & 1) == 0)
3296 if(src->stride > 0 && dst->stride > 0 && src_rect->left == 0 && src_rect->right == src->width)
3297 memcpy(dst_start, src_start, (src_rect->bottom - src_rect->top) * src->stride);
3300 for(y = src_rect->top; y < src_rect->bottom; y++)
3302 memcpy(dst_start, src_start, (src_rect->right - src_rect->left + 1) / 2);
3303 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left + 1) / 2, 0, pad_size);
3304 dst_start += dst->stride;
3305 src_start += src->stride;
3311 for(y = src_rect->top; y < src_rect->bottom; y++)
3313 dst_pixel = dst_start;
3314 src_pixel = src_start;
3315 for(x = src_rect->left; x < src_rect->right; x++)
3319 rgb = src->color_table[*src_pixel++ & 0xf];
3321 rgb = src->color_table[*src_pixel >> 4];
3322 dst_val = rgb_to_pixel_colortable(dst, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
3323 if((x - src_rect->left) & 1)
3325 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3329 *dst_pixel = (dst_val << 4) & 0xf0;
3333 if((x - src_rect->left) & 1) dst_pixel++;
3334 memset(dst_pixel, 0, pad_size);
3336 dst_start += dst->stride;
3337 src_start += src->stride;
3345 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
3346 for(y = src_rect->top; y < src_rect->bottom; y++)
3348 dst_pixel = dst_start;
3349 src_pixel = src_start;
3350 for(x = src_rect->left; x < src_rect->right; x++)
3353 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
3354 if((x % 8) == 7) src_pixel++;
3355 rgb = src->color_table[src_val];
3356 dst_val = rgb_to_pixel_colortable(dst, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
3357 if((x - src_rect->left) & 1)
3359 *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3363 *dst_pixel = (dst_val << 4) & 0xf0;
3367 if((x - src_rect->left) & 1) dst_pixel++;
3368 memset(dst_pixel, 0, pad_size);
3370 dst_start += dst->stride;
3371 src_start += src->stride;
3378 static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rect)
3380 BYTE *dst_start = get_pixel_ptr_1(dst, 0, 0), *dst_pixel, dst_val;
3381 INT x, y, pad_size = ((dst->width + 31) & ~31) / 8 - (src_rect->right - src_rect->left + 7) / 8;
3385 /* FIXME: Brushes should be dithered. */
3387 switch(src->bit_count)
3391 DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
3393 if(src->funcs == &funcs_8888)
3395 for(y = src_rect->top; y < src_rect->bottom; y++)
3397 dst_pixel = dst_start;
3398 src_pixel = src_start;
3399 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3401 src_val = *src_pixel++;
3402 dst_val = rgb_to_pixel_colortable(dst, src_val >> 16, src_val >> 8, src_val) ? 0xff : 0;
3404 if(bit_pos == 0) *dst_pixel = 0;
3405 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3415 if(bit_pos != 0) dst_pixel++;
3416 memset(dst_pixel, 0, pad_size);
3418 dst_start += dst->stride;
3419 src_start += src->stride / 4;
3422 else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
3424 for(y = src_rect->top; y < src_rect->bottom; y++)
3426 dst_pixel = dst_start;
3427 src_pixel = src_start;
3428 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3430 src_val = *src_pixel++;
3431 dst_val = rgb_to_pixel_colortable(dst,
3432 src_val >> src->red_shift,
3433 src_val >> src->green_shift,
3434 src_val >> src->blue_shift) ? 0xff : 0;
3436 if(bit_pos == 0) *dst_pixel = 0;
3437 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3447 if(bit_pos != 0) dst_pixel++;
3448 memset(dst_pixel, 0, pad_size);
3450 dst_start += dst->stride;
3451 src_start += src->stride / 4;
3456 for(y = src_rect->top; y < src_rect->bottom; y++)
3458 dst_pixel = dst_start;
3459 src_pixel = src_start;
3460 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3462 src_val = *src_pixel++;
3463 dst_val = rgb_to_pixel_colortable(dst,
3464 get_field(src_val, src->red_shift, src->red_len),
3465 get_field(src_val, src->green_shift, src->green_len),
3466 get_field(src_val, src->blue_shift, src->blue_len)) ? 0xff : 0;
3468 if(bit_pos == 0) *dst_pixel = 0;
3469 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3479 if(bit_pos != 0) dst_pixel++;
3480 memset(dst_pixel, 0, pad_size);
3482 dst_start += dst->stride;
3483 src_start += src->stride / 4;
3491 BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
3493 for(y = src_rect->top; y < src_rect->bottom; y++)
3495 dst_pixel = dst_start;
3496 src_pixel = src_start;
3497 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++, src_pixel += 3)
3499 dst_val = rgb_to_pixel_colortable(dst, src_pixel[2], src_pixel[1], src_pixel[0]) ? 0xff : 0;
3501 if(bit_pos == 0) *dst_pixel = 0;
3502 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3512 if(bit_pos != 0) dst_pixel++;
3513 memset(dst_pixel, 0, pad_size);
3515 dst_start += dst->stride;
3516 src_start += src->stride;
3523 WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
3524 if(src->funcs == &funcs_555)
3526 for(y = src_rect->top; y < src_rect->bottom; y++)
3528 dst_pixel = dst_start;
3529 src_pixel = src_start;
3530 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3532 src_val = *src_pixel++;
3533 dst_val = rgb_to_pixel_colortable(dst,
3534 ((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07),
3535 ((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07),
3536 ((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07) ) ? 0xff : 0;
3538 if(bit_pos == 0) *dst_pixel = 0;
3539 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3549 if(bit_pos != 0) dst_pixel++;
3550 memset(dst_pixel, 0, pad_size);
3552 dst_start += dst->stride;
3553 src_start += src->stride / 2;
3556 else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
3558 for(y = src_rect->top; y < src_rect->bottom; y++)
3560 dst_pixel = dst_start;
3561 src_pixel = src_start;
3562 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3564 src_val = *src_pixel++;
3565 dst_val = rgb_to_pixel_colortable(dst,
3566 (((src_val >> src->red_shift) << 3) & 0xf8) |
3567 (((src_val >> src->red_shift) >> 2) & 0x07),
3568 (((src_val >> src->green_shift) << 3) & 0xf8) |
3569 (((src_val >> src->green_shift) >> 2) & 0x07),
3570 (((src_val >> src->blue_shift) << 3) & 0xf8) |
3571 (((src_val >> src->blue_shift) >> 2) & 0x07) ) ? 0xff : 0;
3572 if(bit_pos == 0) *dst_pixel = 0;
3573 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3583 if(bit_pos != 0) dst_pixel++;
3584 memset(dst_pixel, 0, pad_size);
3586 dst_start += dst->stride;
3587 src_start += src->stride / 2;
3590 else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
3592 for(y = src_rect->top; y < src_rect->bottom; y++)
3594 dst_pixel = dst_start;
3595 src_pixel = src_start;
3596 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3598 src_val = *src_pixel++;
3599 dst_val = rgb_to_pixel_colortable(dst,
3600 (((src_val >> src->red_shift) << 3) & 0xf8) |
3601 (((src_val >> src->red_shift) >> 2) & 0x07),
3602 (((src_val >> src->green_shift) << 2) & 0xfc) |
3603 (((src_val >> src->green_shift) >> 4) & 0x03),
3604 (((src_val >> src->blue_shift) << 3) & 0xf8) |
3605 (((src_val >> src->blue_shift) >> 2) & 0x07) ) ? 0xff : 0;
3606 if(bit_pos == 0) *dst_pixel = 0;
3607 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3617 if(bit_pos != 0) dst_pixel++;
3618 memset(dst_pixel, 0, pad_size);
3620 dst_start += dst->stride;
3621 src_start += src->stride / 2;
3626 for(y = src_rect->top; y < src_rect->bottom; y++)
3628 dst_pixel = dst_start;
3629 src_pixel = src_start;
3630 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3632 src_val = *src_pixel++;
3633 dst_val = rgb_to_pixel_colortable(dst,
3634 get_field(src_val, src->red_shift, src->red_len),
3635 get_field(src_val, src->green_shift, src->green_len),
3636 get_field(src_val, src->blue_shift, src->blue_len)) ? 0xff : 0;
3637 if(bit_pos == 0) *dst_pixel = 0;
3638 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3648 if(bit_pos != 0) dst_pixel++;
3649 memset(dst_pixel, 0, pad_size);
3651 dst_start += dst->stride;
3652 src_start += src->stride / 2;
3660 BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
3662 for(y = src_rect->top; y < src_rect->bottom; y++)
3664 dst_pixel = dst_start;
3665 src_pixel = src_start;
3666 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3668 RGBQUAD rgb = src->color_table[*src_pixel++];
3669 dst_val = rgb_to_pixel_colortable(dst, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue) ? 0xff : 0;
3671 if(bit_pos == 0) *dst_pixel = 0;
3672 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3682 if(bit_pos != 0) dst_pixel++;
3683 memset(dst_pixel, 0, pad_size);
3685 dst_start += dst->stride;
3686 src_start += src->stride;
3693 BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
3695 for(y = src_rect->top; y < src_rect->bottom; y++)
3697 dst_pixel = dst_start;
3698 src_pixel = src_start;
3699 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3703 rgb = src->color_table[*src_pixel++ & 0xf];
3705 rgb = src->color_table[*src_pixel >> 4];
3706 dst_val = rgb_to_pixel_colortable(dst, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue) ? 0xff : 0;
3708 if(bit_pos == 0) *dst_pixel = 0;
3709 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3719 if(bit_pos != 0) dst_pixel++;
3720 memset(dst_pixel, 0, pad_size);
3722 dst_start += dst->stride;
3723 src_start += src->stride;
3728 /* Note that while MSDN states that a 1 bpp dib brush -> mono dc
3729 uses text/bkgnd colours instead of the dib's colour table, this
3730 doesn't appear to be the case for a dc backed by a
3735 BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top), *src_pixel;
3736 for(y = src_rect->top; y < src_rect->bottom; y++)
3738 dst_pixel = dst_start;
3739 src_pixel = src_start;
3740 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3743 src_val = (*src_pixel & pixel_masks_1[x % 8]) ? 1 : 0;
3744 if((x % 8) == 7) src_pixel++;
3745 rgb = src->color_table[src_val];
3746 dst_val = rgb_to_pixel_colortable(dst, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue) ? 0xff : 0;
3748 if(bit_pos == 0) *dst_pixel = 0;
3749 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3759 if(bit_pos != 0) dst_pixel++;
3760 memset(dst_pixel, 0, pad_size);
3762 dst_start += dst->stride;
3763 src_start += src->stride;
3770 static void convert_to_null(dib_info *dst, const dib_info *src, const RECT *src_rect)
3774 static inline BYTE blend_color(BYTE dst, BYTE src, DWORD alpha)
3776 return (src * alpha + dst * (255 - alpha) + 127) / 255;
3779 static inline DWORD blend_argb_constant_alpha( DWORD dst, DWORD src, DWORD alpha )
3781 return (blend_color( dst, src, alpha ) |
3782 blend_color( dst >> 8, src >> 8, alpha ) << 8 |
3783 blend_color( dst >> 16, src >> 16, alpha ) << 16 |
3784 blend_color( dst >> 24, src >> 24, alpha ) << 24);
3787 static inline DWORD blend_argb( DWORD dst, DWORD src )
3790 BYTE g = (BYTE)(src >> 8);
3791 BYTE r = (BYTE)(src >> 16);
3792 DWORD alpha = (BYTE)(src >> 24);
3793 return ((b + ((BYTE)dst * (255 - alpha) + 127) / 255) |
3794 (g + ((BYTE)(dst >> 8) * (255 - alpha) + 127) / 255) << 8 |
3795 (r + ((BYTE)(dst >> 16) * (255 - alpha) + 127) / 255) << 16 |
3796 (alpha + ((BYTE)(dst >> 24) * (255 - alpha) + 127) / 255) << 24);
3799 static inline DWORD blend_argb_alpha( DWORD dst, DWORD src, DWORD alpha )
3801 BYTE b = ((BYTE)src * alpha + 127) / 255;
3802 BYTE g = ((BYTE)(src >> 8) * alpha + 127) / 255;
3803 BYTE r = ((BYTE)(src >> 16) * alpha + 127) / 255;
3804 alpha = ((BYTE)(src >> 24) * alpha + 127) / 255;
3805 return ((b + ((BYTE)dst * (255 - alpha) + 127) / 255) |
3806 (g + ((BYTE)(dst >> 8) * (255 - alpha) + 127) / 255) << 8 |
3807 (r + ((BYTE)(dst >> 16) * (255 - alpha) + 127) / 255) << 16 |
3808 (alpha + ((BYTE)(dst >> 24) * (255 - alpha) + 127) / 255) << 24);
3811 static inline DWORD blend_rgb( BYTE dst_r, BYTE dst_g, BYTE dst_b, DWORD src, BLENDFUNCTION blend )
3813 if (blend.AlphaFormat & AC_SRC_ALPHA)
3815 DWORD alpha = blend.SourceConstantAlpha;
3816 BYTE src_b = ((BYTE)src * alpha + 127) / 255;
3817 BYTE src_g = ((BYTE)(src >> 8) * alpha + 127) / 255;
3818 BYTE src_r = ((BYTE)(src >> 16) * alpha + 127) / 255;
3819 alpha = ((BYTE)(src >> 24) * alpha + 127) / 255;
3820 return ((src_b + (dst_b * (255 - alpha) + 127) / 255) |
3821 (src_g + (dst_g * (255 - alpha) + 127) / 255) << 8 |
3822 (src_r + (dst_r * (255 - alpha) + 127) / 255) << 16);
3824 return (blend_color( dst_b, src, blend.SourceConstantAlpha ) |
3825 blend_color( dst_g, src >> 8, blend.SourceConstantAlpha ) << 8 |
3826 blend_color( dst_r, src >> 16, blend.SourceConstantAlpha ) << 16);
3829 static void blend_rect_8888(const dib_info *dst, const RECT *rc,
3830 const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
3832 DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
3833 DWORD *dst_ptr = get_pixel_ptr_32( dst, rc->left, rc->top );
3836 if (blend.AlphaFormat & AC_SRC_ALPHA)
3838 if (blend.SourceConstantAlpha == 255)
3839 for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
3840 for (x = 0; x < rc->right - rc->left; x++)
3841 dst_ptr[x] = blend_argb( dst_ptr[x], src_ptr[x] );
3843 for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
3844 for (x = 0; x < rc->right - rc->left; x++)
3845 dst_ptr[x] = blend_argb_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
3848 for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
3849 for (x = 0; x < rc->right - rc->left; x++)
3850 dst_ptr[x] = blend_argb_constant_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
3853 static void blend_rect_32(const dib_info *dst, const RECT *rc,
3854 const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
3856 DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
3857 DWORD *dst_ptr = get_pixel_ptr_32( dst, rc->left, rc->top );
3860 if (dst->red_len == 8 && dst->green_len == 8 && dst->blue_len == 8)
3862 for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
3864 for (x = 0; x < rc->right - rc->left; x++)
3866 DWORD val = blend_rgb( dst_ptr[x] >> dst->red_shift,
3867 dst_ptr[x] >> dst->green_shift,
3868 dst_ptr[x] >> dst->blue_shift,
3869 src_ptr[x], blend );
3870 dst_ptr[x] = ((( val & 0xff) << dst->blue_shift) |
3871 (((val >> 8) & 0xff) << dst->green_shift) |
3872 (((val >> 16) & 0xff) << dst->red_shift));
3878 for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
3880 for (x = 0; x < rc->right - rc->left; x++)
3882 DWORD val = blend_rgb( get_field( dst_ptr[x], dst->red_shift, dst->red_len ),
3883 get_field( dst_ptr[x], dst->green_shift, dst->green_len ),
3884 get_field( dst_ptr[x], dst->blue_shift, dst->blue_len ),
3885 src_ptr[x], blend );
3886 dst_ptr[x] = (put_field( val >> 16, dst->red_shift, dst->red_len ) |
3887 put_field( val >> 8, dst->green_shift, dst->green_len ) |
3888 put_field( val, dst->blue_shift, dst->blue_len ));
3894 static void blend_rect_24(const dib_info *dst, const RECT *rc,
3895 const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
3897 DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
3898 BYTE *dst_ptr = get_pixel_ptr_24( dst, rc->left, rc->top );
3901 for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
3903 for (x = 0; x < rc->right - rc->left; x++)
3905 DWORD val = blend_rgb( dst_ptr[x * 3 + 2], dst_ptr[x * 3 + 1], dst_ptr[x * 3],
3906 src_ptr[x], blend );
3907 dst_ptr[x * 3] = val;
3908 dst_ptr[x * 3 + 1] = val >> 8;
3909 dst_ptr[x * 3 + 2] = val >> 16;
3914 static void blend_rect_555(const dib_info *dst, const RECT *rc,
3915 const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
3917 DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
3918 WORD *dst_ptr = get_pixel_ptr_16( dst, rc->left, rc->top );
3921 for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 2, src_ptr += src->stride / 4)
3923 for (x = 0; x < rc->right - rc->left; x++)
3925 DWORD val = blend_rgb( ((dst_ptr[x] >> 7) & 0xf8) | ((dst_ptr[x] >> 12) & 0x07),
3926 ((dst_ptr[x] >> 2) & 0xf8) | ((dst_ptr[x] >> 7) & 0x07),
3927 ((dst_ptr[x] << 3) & 0xf8) | ((dst_ptr[x] >> 2) & 0x07),
3928 src_ptr[x], blend );
3929 dst_ptr[x] = ((val >> 9) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 3) & 0x001f);
3934 static void blend_rect_16(const dib_info *dst, const RECT *rc,
3935 const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
3937 DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
3938 WORD *dst_ptr = get_pixel_ptr_16( dst, rc->left, rc->top );
3941 for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 2, src_ptr += src->stride / 4)
3943 for (x = 0; x < rc->right - rc->left; x++)
3945 DWORD val = blend_rgb( get_field( dst_ptr[x], dst->red_shift, dst->red_len ),
3946 get_field( dst_ptr[x], dst->green_shift, dst->green_len ),
3947 get_field( dst_ptr[x], dst->blue_shift, dst->blue_len ),
3948 src_ptr[x], blend );
3949 dst_ptr[x] = (put_field((val >> 16), dst->red_shift, dst->red_len) |
3950 put_field((val >> 8), dst->green_shift, dst->green_len) |
3951 put_field( val, dst->blue_shift, dst->blue_len));
3956 static void blend_rect_8(const dib_info *dst, const RECT *rc,
3957 const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
3959 DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
3960 BYTE *dst_ptr = get_pixel_ptr_8( dst, rc->left, rc->top );
3963 for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
3965 for (x = 0; x < rc->right - rc->left; x++)
3967 RGBQUAD rgb = dst->color_table[dst_ptr[x]];
3968 DWORD val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[x], blend );
3969 dst_ptr[x] = rgb_lookup_colortable( dst, val >> 16, val >> 8, val );
3974 static void blend_rect_4(const dib_info *dst, const RECT *rc,
3975 const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
3977 DWORD *src_ptr = get_pixel_ptr_32( src, origin->x - rc->left, origin->y );
3978 BYTE *dst_ptr = get_pixel_ptr_4( dst, 0, rc->top );
3981 for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
3983 for (x = rc->left; x < rc->right; x++)
3985 DWORD val = ((x & 1) ? dst_ptr[x / 2] : (dst_ptr[x / 2] >> 4)) & 0x0f;
3986 RGBQUAD rgb = dst->color_table[val];
3987 val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[x], blend );
3988 val = rgb_lookup_colortable( dst, val >> 16, val >> 8, val );
3990 dst_ptr[x / 2] = val | (dst_ptr[x / 2] & 0xf0);
3992 dst_ptr[x / 2] = (val << 4) | (dst_ptr[x / 2] & 0x0f);
3997 static void blend_rect_1(const dib_info *dst, const RECT *rc,
3998 const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
4000 DWORD *src_ptr = get_pixel_ptr_32( src, origin->x - rc->left, origin->y );
4001 BYTE *dst_ptr = get_pixel_ptr_1( dst, 0, rc->top );
4004 for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
4006 for (x = rc->left; x < rc->right; x++)
4008 DWORD val = (dst_ptr[x / 8] & pixel_masks_1[x % 8]) ? 1 : 0;
4009 RGBQUAD rgb = dst->color_table[val];
4010 val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[x], blend );
4011 val = rgb_to_pixel_colortable(dst, val >> 16, val >> 8, val) ? 0xff : 0;
4012 dst_ptr[x / 8] = (dst_ptr[x / 8] & ~pixel_masks_1[x % 8]) | (val & pixel_masks_1[x % 8]);
4017 static void blend_rect_null(const dib_info *dst, const RECT *rc,
4018 const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
4022 static inline DWORD gradient_rgb_8888( const TRIVERTEX *v, unsigned int pos, unsigned int len )
4025 r = (v[0].Red * (len - pos) + v[1].Red * pos) / len / 256;
4026 g = (v[0].Green * (len - pos) + v[1].Green * pos) / len / 256;
4027 b = (v[0].Blue * (len - pos) + v[1].Blue * pos) / len / 256;
4028 a = (v[0].Alpha * (len - pos) + v[1].Alpha * pos) / len / 256;
4029 return a << 24 | r << 16 | g << 8 | b;
4032 static inline DWORD gradient_rgb_24( const TRIVERTEX *v, unsigned int pos, unsigned int len )
4035 r = (v[0].Red * (len - pos) + v[1].Red * pos) / len / 256;
4036 g = (v[0].Green * (len - pos) + v[1].Green * pos) / len / 256;
4037 b = (v[0].Blue * (len - pos) + v[1].Blue * pos) / len / 256;
4038 return r << 16 | g << 8 | b;
4041 static inline WORD gradient_rgb_555( const TRIVERTEX *v, unsigned int pos, unsigned int len,
4042 unsigned int x, unsigned int y )
4044 int r = (v[0].Red * (len - pos) + v[1].Red * pos) / len / 128 + bayer_4x4[y % 4][x % 4];
4045 int g = (v[0].Green * (len - pos) + v[1].Green * pos) / len / 128 + bayer_4x4[y % 4][x % 4];
4046 int b = (v[0].Blue * (len - pos) + v[1].Blue * pos) / len / 128 + bayer_4x4[y % 4][x % 4];
4047 r = min( 31, max( 0, r / 16 ));
4048 g = min( 31, max( 0, g / 16 ));
4049 b = min( 31, max( 0, b / 16 ));
4050 return (r << 10) | (g << 5) | b;
4053 static inline BYTE gradient_rgb_8( const dib_info *dib, const TRIVERTEX *v,
4054 unsigned int pos, unsigned int len, unsigned int x, unsigned int y )
4056 BYTE r = ((v[0].Red * (len - pos) + v[1].Red * pos) / len / 128 + bayer_16x16[y % 16][x % 16]) / 256;
4057 BYTE g = ((v[0].Green * (len - pos) + v[1].Green * pos) / len / 128 + bayer_16x16[y % 16][x % 16]) / 256;
4058 BYTE b = ((v[0].Blue * (len - pos) + v[1].Blue * pos) / len / 128 + bayer_16x16[y % 16][x % 16]) / 256;
4059 return rgb_to_pixel_colortable( dib, r * 127, g * 127, b * 127 );
4062 /* compute the left/right triangle limit for row y */
4063 static inline void triangle_coords( const TRIVERTEX *v, const RECT *rc, int y, int *left, int *right )
4067 if (y < v[1].y) x1 = edge_coord( y, v[0].x, v[0].y, v[1].x, v[1].y );
4068 else x1 = edge_coord( y, v[1].x, v[1].y, v[2].x, v[2].y );
4070 x2 = edge_coord( y, v[0].x, v[0].y, v[2].x, v[2].y );
4072 *left = max( rc->left, min( x1, x2 ) );
4073 *right = min( rc->right, max( x1, x2 ) );
4076 /* compute the matrix determinant for triangular barycentric coordinates (constant across the triangle) */
4077 static inline int triangle_det( const TRIVERTEX *v )
4079 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);
4082 /* compute the barycentric weights for a given point inside the triangle */
4083 static inline void triangle_weights( const TRIVERTEX *v, int x, int y, INT64 *l1, INT64 *l2 )
4085 *l1 = (v[1].y - v[2].y) * (x - v[2].x) - (v[1].x - v[2].x) * (y - v[2].y);
4086 *l2 = (v[2].y - v[0].y) * (x - v[2].x) - (v[2].x - v[0].x) * (y - v[2].y);
4089 static inline DWORD gradient_triangle_8888( const TRIVERTEX *v, int x, int y, int det )
4094 triangle_weights( v, x, y, &l1, &l2 );
4095 r = (v[0].Red * l1 + v[1].Red * l2 + v[2].Red * (det - l1 - l2)) / det / 256;
4096 g = (v[0].Green * l1 + v[1].Green * l2 + v[2].Green * (det - l1 - l2)) / det / 256;
4097 b = (v[0].Blue * l1 + v[1].Blue * l2 + v[2].Blue * (det - l1 - l2)) / det / 256;
4098 a = (v[0].Alpha * l1 + v[1].Alpha * l2 + v[2].Alpha * (det - l1 - l2)) / det / 256;
4099 return a << 24 | r << 16 | g << 8 | b;
4102 static inline DWORD gradient_triangle_24( const TRIVERTEX *v, int x, int y, int det )
4107 triangle_weights( v, x, y, &l1, &l2 );
4108 r = (v[0].Red * l1 + v[1].Red * l2 + v[2].Red * (det - l1 - l2)) / det / 256;
4109 g = (v[0].Green * l1 + v[1].Green * l2 + v[2].Green * (det - l1 - l2)) / det / 256;
4110 b = (v[0].Blue * l1 + v[1].Blue * l2 + v[2].Blue * (det - l1 - l2)) / det / 256;
4111 return r << 16 | g << 8 | b;
4114 static inline DWORD gradient_triangle_555( const TRIVERTEX *v, int x, int y, int det )
4119 triangle_weights( v, x, y, &l1, &l2 );
4120 r = (v[0].Red * l1 + v[1].Red * l2 + v[2].Red * (det - l1 - l2)) / det / 128 + bayer_4x4[y % 4][x % 4];
4121 g = (v[0].Green * l1 + v[1].Green * l2 + v[2].Green * (det - l1 - l2)) / det / 128 + bayer_4x4[y % 4][x % 4];
4122 b = (v[0].Blue * l1 + v[1].Blue * l2 + v[2].Blue * (det - l1 - l2)) / det / 128 + bayer_4x4[y % 4][x % 4];
4123 r = min( 31, max( 0, r / 16 ));
4124 g = min( 31, max( 0, g / 16 ));
4125 b = min( 31, max( 0, b / 16 ));
4126 return (r << 10) | (g << 5) | b;
4129 static inline DWORD gradient_triangle_8( const dib_info *dib, const TRIVERTEX *v, int x, int y, int det )
4134 triangle_weights( v, x, y, &l1, &l2 );
4135 r = ((v[0].Red * l1 + v[1].Red * l2 + v[2].Red * (det - l1 - l2)) / det / 128 + bayer_16x16[y % 16][x % 16]) / 256;
4136 g = ((v[0].Green * l1 + v[1].Green * l2 + v[2].Green * (det - l1 - l2)) / det / 128 + bayer_16x16[y % 16][x % 16]) / 256;
4137 b = ((v[0].Blue * l1 + v[1].Blue * l2 + v[2].Blue * (det - l1 - l2)) / det / 128 + bayer_16x16[y % 16][x % 16]) / 256;
4138 return rgb_to_pixel_colortable( dib, r * 127, g * 127, b * 127 );
4141 static BOOL gradient_rect_8888( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4143 DWORD *ptr = get_pixel_ptr_32( dib, 0, rc->top );
4144 int x, y, left, right, det;
4148 case GRADIENT_FILL_RECT_H:
4149 for (x = rc->left; x < rc->right; x++)
4150 ptr[x] = gradient_rgb_8888( v, x - v[0].x, v[1].x - v[0].x );
4152 for (y = rc->top + 1, ptr += rc->left; y < rc->bottom; y++, ptr += dib->stride / 4)
4153 memcpy( ptr + dib->stride / 4, ptr, (rc->right - rc->left) * 4 );
4156 case GRADIENT_FILL_RECT_V:
4157 for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride / 4)
4159 DWORD val = gradient_rgb_8888( v, y - v[0].y, v[1].y - v[0].y );
4160 for (x = rc->left; x < rc->right; x++) ptr[x] = val;
4164 case GRADIENT_FILL_TRIANGLE:
4165 if (!(det = triangle_det( v ))) return FALSE;
4166 for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride / 4)
4168 triangle_coords( v, rc, y, &left, &right );
4169 for (x = left; x < right; x++) ptr[x] = gradient_triangle_8888( v, x, y, det );
4176 static BOOL gradient_rect_32( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4178 DWORD *ptr = get_pixel_ptr_32( dib, 0, rc->top );
4179 int x, y, left, right, det;
4183 case GRADIENT_FILL_RECT_H:
4184 if (dib->red_len == 8 && dib->green_len == 8 && dib->blue_len == 8)
4186 for (x = rc->left; x < rc->right; x++)
4188 DWORD val = gradient_rgb_24( v, x - v[0].x, v[1].x - v[0].x );
4189 ptr[x] = ((( val & 0xff) << dib->blue_shift) |
4190 (((val >> 8) & 0xff) << dib->green_shift) |
4191 (((val >> 16) & 0xff) << dib->red_shift));
4196 for (x = rc->left; x < rc->right; x++)
4198 DWORD val = gradient_rgb_24( v, x - v[0].x, v[1].x - v[0].x );
4199 ptr[x] = (put_field( val >> 16, dib->red_shift, dib->red_len ) |
4200 put_field( val >> 8, dib->green_shift, dib->green_len ) |
4201 put_field( val, dib->blue_shift, dib->blue_len ));
4205 for (y = rc->top + 1, ptr += rc->left; y < rc->bottom; y++, ptr += dib->stride / 4)
4206 memcpy( ptr + dib->stride / 4, ptr, (rc->right - rc->left) * 4 );
4209 case GRADIENT_FILL_RECT_V:
4210 for (y = rc->top; y < rc->bottom; y++)
4212 DWORD val = gradient_rgb_24( v, y - v[0].y, v[1].y - v[0].y );
4213 if (dib->red_len == 8 && dib->green_len == 8 && dib->blue_len == 8)
4214 val = ((( val & 0xff) << dib->blue_shift) |
4215 (((val >> 8) & 0xff) << dib->green_shift) |
4216 (((val >> 16) & 0xff) << dib->red_shift));
4218 val = (put_field( val >> 16, dib->red_shift, dib->red_len ) |
4219 put_field( val >> 8, dib->green_shift, dib->green_len ) |
4220 put_field( val, dib->blue_shift, dib->blue_len ));
4222 for (x = rc->left; x < rc->right; x++) ptr[x] = val;
4223 ptr += dib->stride / 4;
4227 case GRADIENT_FILL_TRIANGLE:
4228 if (!(det = triangle_det( v ))) return FALSE;
4229 for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride / 4)
4231 triangle_coords( v, rc, y, &left, &right );
4233 if (dib->red_len == 8 && dib->green_len == 8 && dib->blue_len == 8)
4234 for (x = left; x < right; x++)
4236 DWORD val = gradient_triangle_24( v, x, y, det );
4237 ptr[x] = ((( val & 0xff) << dib->blue_shift) |
4238 (((val >> 8) & 0xff) << dib->green_shift) |
4239 (((val >> 16) & 0xff) << dib->red_shift));
4242 for (x = left; x < right; x++)
4244 DWORD val = gradient_triangle_24( v, x, y, det );
4245 ptr[x] = (put_field( val >> 16, dib->red_shift, dib->red_len ) |
4246 put_field( val >> 8, dib->green_shift, dib->green_len ) |
4247 put_field( val, dib->blue_shift, dib->blue_len ));
4255 static BOOL gradient_rect_24( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4257 BYTE *ptr = get_pixel_ptr_24( dib, 0, rc->top );
4258 int x, y, left, right, det;
4262 case GRADIENT_FILL_RECT_H:
4263 for (x = rc->left; x < rc->right; x++)
4265 DWORD val = gradient_rgb_24( v, x - v[0].x, v[1].x - v[0].x );
4267 ptr[x * 3 + 1] = val >> 8;
4268 ptr[x * 3 + 2] = val >> 16;
4271 for (y = rc->top + 1, ptr += rc->left * 3; y < rc->bottom; y++, ptr += dib->stride)
4272 memcpy( ptr + dib->stride, ptr, (rc->right - rc->left) * 3 );
4275 case GRADIENT_FILL_RECT_V:
4276 for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride)
4278 DWORD val = gradient_rgb_24( v, y - v[0].y, v[1].y - v[0].y );
4279 for (x = rc->left; x < rc->right; x++)
4282 ptr[x * 3 + 1] = val >> 8;
4283 ptr[x * 3 + 2] = val >> 16;
4288 case GRADIENT_FILL_TRIANGLE:
4289 if (!(det = triangle_det( v ))) return FALSE;
4290 for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride)
4292 triangle_coords( v, rc, y, &left, &right );
4293 for (x = left; x < right; x++)
4295 DWORD val = gradient_triangle_24( v, x, y, det );
4297 ptr[x * 3 + 1] = val >> 8;
4298 ptr[x * 3 + 2] = val >> 16;
4306 static BOOL gradient_rect_555( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4308 WORD *ptr = get_pixel_ptr_16( dib, 0, rc->top );
4309 int x, y, left, right, det;
4313 case GRADIENT_FILL_RECT_H:
4314 for (y = rc->top; y < min( rc->top + 4, rc->bottom ); y++, ptr += dib->stride / 2)
4315 for (x = rc->left; x < rc->right; x++)
4316 ptr[x] = gradient_rgb_555( v, x - v[0].x, v[1].x - v[0].x, x, y );
4317 for (ptr += rc->left; y < rc->bottom; y++, ptr += dib->stride / 2)
4318 memcpy( ptr, ptr - dib->stride * 2, (rc->right - rc->left) * 2 );
4321 case GRADIENT_FILL_RECT_V:
4322 for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride / 2)
4325 for (x = 0; x < 4; x++) values[x] = gradient_rgb_555( v, y - v[0].y, v[1].y - v[0].y, x, y );
4326 for (x = rc->left; x < rc->right; x++) ptr[x] = values[x % 4];
4330 case GRADIENT_FILL_TRIANGLE:
4331 if (!(det = triangle_det( v ))) return FALSE;
4332 for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride / 2)
4334 triangle_coords( v, rc, y, &left, &right );
4335 for (x = left; x < right; x++) ptr[x] = gradient_triangle_555( v, x, y, det );
4342 static BOOL gradient_rect_16( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4344 WORD *ptr = get_pixel_ptr_16( dib, 0, rc->top );
4345 int x, y, left, right, det;
4349 case GRADIENT_FILL_RECT_H:
4350 for (y = rc->top; y < min( rc->top + 4, rc->bottom ); y++, ptr += dib->stride / 2)
4351 for (x = rc->left; x < rc->right; x++)
4353 WORD val = gradient_rgb_555( v, x - v[0].x, v[1].x - v[0].x, x, y );
4354 ptr[x] = (put_field(((val >> 7) & 0xf8) | ((val >> 12) & 0x07), dib->red_shift, dib->red_len) |
4355 put_field(((val >> 2) & 0xf8) | ((val >> 7) & 0x07), dib->green_shift, dib->green_len) |
4356 put_field(((val << 3) & 0xf8) | ((val >> 2) & 0x07), dib->blue_shift, dib->blue_len));
4358 for (ptr += rc->left; y < rc->bottom; y++, ptr += dib->stride / 2)
4359 memcpy( ptr, ptr - dib->stride * 2, (rc->right - rc->left) * 2 );
4362 case GRADIENT_FILL_RECT_V:
4363 for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride / 2)
4366 for (x = 0; x < 4; x++)
4368 WORD val = gradient_rgb_555( v, y - v[0].y, v[1].y - v[0].y, x, y );
4369 values[x] = (put_field(((val >> 7) & 0xf8) | ((val >> 12) & 0x07), dib->red_shift, dib->red_len) |
4370 put_field(((val >> 2) & 0xf8) | ((val >> 7) & 0x07), dib->green_shift, dib->green_len) |
4371 put_field(((val << 3) & 0xf8) | ((val >> 2) & 0x07), dib->blue_shift, dib->blue_len));
4373 for (x = rc->left; x < rc->right; x++) ptr[x] = values[x % 4];
4377 case GRADIENT_FILL_TRIANGLE:
4378 if (!(det = triangle_det( v ))) return FALSE;
4379 for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride / 2)
4381 triangle_coords( v, rc, y, &left, &right );
4382 for (x = left; x < right; x++)
4384 WORD val = gradient_triangle_555( v, x, y, det );
4385 ptr[x] = (put_field(((val >> 7) & 0xf8) | ((val >> 12) & 0x07), dib->red_shift, dib->red_len) |
4386 put_field(((val >> 2) & 0xf8) | ((val >> 7) & 0x07), dib->green_shift, dib->green_len) |
4387 put_field(((val << 3) & 0xf8) | ((val >> 2) & 0x07), dib->blue_shift, dib->blue_len));
4395 static BOOL gradient_rect_8( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4397 BYTE *ptr = get_pixel_ptr_8( dib, 0, rc->top );
4398 int x, y, left, right, det;
4402 case GRADIENT_FILL_RECT_H:
4403 for (y = rc->top; y < min( rc->top + 16, rc->bottom ); y++, ptr += dib->stride)
4404 for (x = rc->left; x < rc->right; x++)
4405 ptr[x] = gradient_rgb_8( dib, v, x - v[0].x, v[1].x - v[0].x, x, y );
4406 for (ptr += rc->left; y < rc->bottom; y++, ptr += dib->stride)
4407 memcpy( ptr, ptr - dib->stride * 16, rc->right - rc->left );
4410 case GRADIENT_FILL_RECT_V:
4411 for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride)
4414 for (x = 0; x < 16; x++)
4415 values[x] = gradient_rgb_8( dib, v, y - v[0].y, v[1].y - v[0].y, x, y );
4416 for (x = rc->left; x < rc->right; x++) ptr[x] = values[x % 16];
4420 case GRADIENT_FILL_TRIANGLE:
4421 if (!(det = triangle_det( v ))) return FALSE;
4422 for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride)
4424 triangle_coords( v, rc, y, &left, &right );
4425 for (x = left; x < right; x++) ptr[x] = gradient_triangle_8( dib, v, x, y, det );
4432 static BOOL gradient_rect_4( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4434 BYTE *ptr = get_pixel_ptr_4( dib, 0, rc->top );
4435 int x, y, left, right, det;
4439 case GRADIENT_FILL_RECT_H:
4440 for (y = rc->top; y < min( rc->top + 16, rc->bottom ); y++, ptr += dib->stride)
4442 for (x = rc->left; x < rc->right; x++)
4444 BYTE val = gradient_rgb_8( dib, v, x - v[0].x, v[1].x - v[0].x, x, y );
4446 ptr[x / 2] = val | (ptr[x / 2] & 0xf0);
4448 ptr[x / 2] = (val << 4) | (ptr[x / 2] & 0x0f);
4451 for ( ; y < rc->bottom; y++, ptr += dib->stride)
4456 ptr[x / 2] = (ptr[x / 2 - 16 * dib->stride] & 0x0f) | (ptr[x / 2] & 0xf0);
4459 for (; x < rc->right - 1; x += 2) ptr[x / 2] = ptr[x / 2 - 16 * dib->stride];
4461 ptr[x / 2] = (ptr[x / 2] & 0x0f) | (ptr[x / 2 - 16 * dib->stride] & 0xf0);
4465 case GRADIENT_FILL_RECT_V:
4466 for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride)
4469 for (x = 0; x < 16; x++)
4470 values[x] = gradient_rgb_8( dib, v, y - v[0].y, v[1].y - v[0].y, x, y );
4471 for (x = rc->left; x < rc->right; x++)
4473 ptr[x / 2] = values[x % 16] | (ptr[x / 2] & 0xf0);
4475 ptr[x / 2] = (values[x % 16] << 4) | (ptr[x / 2] & 0x0f);
4479 case GRADIENT_FILL_TRIANGLE:
4480 if (!(det = triangle_det( v ))) return FALSE;
4481 for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride)
4483 triangle_coords( v, rc, y, &left, &right );
4484 for (x = left; x < right; x++)
4486 BYTE val = gradient_triangle_8( dib, v, x, y, det );
4488 ptr[x / 2] = val | (ptr[x / 2] & 0xf0);
4490 ptr[x / 2] = (val << 4) | (ptr[x / 2] & 0x0f);
4498 static BOOL gradient_rect_1( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4500 BYTE *ptr = get_pixel_ptr_1( dib, 0, rc->top );
4501 int x, y, left, right, det;
4505 case GRADIENT_FILL_RECT_H:
4506 for (y = rc->top; y < min( rc->top + 16, rc->bottom ); y++, ptr += dib->stride)
4508 for (x = rc->left; x < rc->right; x++)
4510 BYTE val = gradient_rgb_8( dib, v, x - v[0].x, v[1].x - v[0].x, x, y ) ? 0xff : 0;
4511 ptr[x / 8] = (ptr[x / 8] & ~pixel_masks_1[x % 8]) | (val & pixel_masks_1[x % 8]);
4514 for ( ; y < rc->bottom; y++, ptr += dib->stride)
4515 for (x = rc->left; x < rc->right; x++)
4516 ptr[x / 8] = (ptr[x / 8] & ~pixel_masks_1[x % 8]) |
4517 (ptr[x / 8 - 16 * dib->stride] & pixel_masks_1[x % 8]);
4520 case GRADIENT_FILL_RECT_V:
4521 for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride)
4524 for (x = 0; x < 16; x++)
4525 values[x] = gradient_rgb_8( dib, v, y - v[0].y, v[1].y - v[0].y, x, y ) ? 0xff : 0;
4526 for (x = rc->left; x < rc->right; x++)
4527 ptr[x / 8] = (ptr[x / 8] & ~pixel_masks_1[x % 8]) | (values[x % 16] & pixel_masks_1[x % 8]);
4531 case GRADIENT_FILL_TRIANGLE:
4532 if (!(det = triangle_det( v ))) return FALSE;
4533 for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride)
4535 triangle_coords( v, rc, y, &left, &right );
4536 for (x = left; x < right; x++)
4538 BYTE val = gradient_triangle_8( dib, v, x, y, det ) ? 0xff : 0;
4539 ptr[x / 8] = (ptr[x / 8] & ~pixel_masks_1[x % 8]) | (val & pixel_masks_1[x % 8]);
4547 static BOOL gradient_rect_null( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4552 static inline BYTE aa_color( BYTE dst, BYTE text, BYTE min_comp, BYTE max_comp )
4554 if (dst == text) return dst;
4558 DWORD diff = dst - text;
4559 DWORD range = max_comp - text;
4560 dst = text + (diff * range ) / (0xff - text);
4565 DWORD diff = text - dst;
4566 DWORD range = text - min_comp;
4567 dst = text - (diff * range) / text;
4572 static inline DWORD aa_rgb( BYTE r_dst, BYTE g_dst, BYTE b_dst, DWORD text, const struct intensity_range *range )
4574 return (aa_color( b_dst, text, range->b_min, range->b_max ) |
4575 aa_color( g_dst, text >> 8, range->g_min, range->g_max ) << 8 |
4576 aa_color( r_dst, text >> 16, range->r_min, range->r_max ) << 16);
4579 static void draw_glyph_8888( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4580 const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4582 DWORD *dst_ptr = get_pixel_ptr_32( dib, rect->left, rect->top );
4583 const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
4586 for (y = rect->top; y < rect->bottom; y++)
4588 for (x = 0; x < rect->right - rect->left; x++)
4590 if (glyph_ptr[x] <= 1) continue;
4591 if (glyph_ptr[x] >= 16) { dst_ptr[x] = text_pixel; continue; }
4592 dst_ptr[x] = aa_rgb( dst_ptr[x] >> 16, dst_ptr[x] >> 8, dst_ptr[x], text_pixel, ranges + glyph_ptr[x] );
4594 dst_ptr += dib->stride / 4;
4595 glyph_ptr += glyph->stride;
4599 static void draw_glyph_32( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4600 const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4602 DWORD *dst_ptr = get_pixel_ptr_32( dib, rect->left, rect->top );
4603 const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
4607 text = get_field( text_pixel, dib->red_shift, dib->red_len ) << 16 |
4608 get_field( text_pixel, dib->green_shift, dib->green_len ) << 8 |
4609 get_field( text_pixel, dib->blue_shift, dib->blue_len );
4611 for (y = rect->top; y < rect->bottom; y++)
4613 for (x = 0; x < rect->right - rect->left; x++)
4615 if (glyph_ptr[x] <= 1) continue;
4616 if (glyph_ptr[x] >= 16) { dst_ptr[x] = text_pixel; continue; }
4617 val = aa_rgb( get_field(dst_ptr[x], dib->red_shift, dib->red_len),
4618 get_field(dst_ptr[x], dib->green_shift, dib->green_len),
4619 get_field(dst_ptr[x], dib->blue_shift, dib->blue_len),
4620 text, ranges + glyph_ptr[x] );
4621 dst_ptr[x] = (put_field( val >> 16, dib->red_shift, dib->red_len ) |
4622 put_field( val >> 8, dib->green_shift, dib->green_len ) |
4623 put_field( val, dib->blue_shift, dib->blue_len ));
4625 dst_ptr += dib->stride / 4;
4626 glyph_ptr += glyph->stride;
4630 static void draw_glyph_24( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4631 const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4633 BYTE *dst_ptr = get_pixel_ptr_24( dib, rect->left, rect->top );
4634 const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
4638 for (y = rect->top; y < rect->bottom; y++)
4640 for (x = 0; x < rect->right - rect->left; x++)
4642 if (glyph_ptr[x] <= 1) continue;
4643 if (glyph_ptr[x] >= 16)
4646 val = aa_rgb( dst_ptr[x * 3 + 2], dst_ptr[x * 3 + 1], dst_ptr[x * 3],
4647 text_pixel, ranges + glyph_ptr[x] );
4648 dst_ptr[x * 3] = val;
4649 dst_ptr[x * 3 + 1] = val >> 8;
4650 dst_ptr[x * 3 + 2] = val >> 16;
4652 dst_ptr += dib->stride;
4653 glyph_ptr += glyph->stride;
4657 static void draw_glyph_555( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4658 const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4660 WORD *dst_ptr = get_pixel_ptr_16( dib, rect->left, rect->top );
4661 const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
4665 text = ((text_pixel << 9) & 0xf80000) | ((text_pixel << 4) & 0x070000) |
4666 ((text_pixel << 6) & 0x00f800) | ((text_pixel << 1) & 0x000700) |
4667 ((text_pixel << 3) & 0x0000f8) | ((text_pixel >> 2) & 0x000007);
4669 for (y = rect->top; y < rect->bottom; y++)
4671 for (x = 0; x < rect->right - rect->left; x++)
4673 if (glyph_ptr[x] <= 1) continue;
4674 if (glyph_ptr[x] >= 16) { dst_ptr[x] = text_pixel; continue; }
4675 val = aa_rgb( ((dst_ptr[x] >> 7) & 0xf8) | ((dst_ptr[x] >> 12) & 0x07),
4676 ((dst_ptr[x] >> 2) & 0xf8) | ((dst_ptr[x] >> 7) & 0x07),
4677 ((dst_ptr[x] << 3) & 0xf8) | ((dst_ptr[x] >> 2) & 0x07),
4678 text, ranges + glyph_ptr[x] );
4679 dst_ptr[x] = ((val >> 9) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 3) & 0x001f);
4681 dst_ptr += dib->stride / 2;
4682 glyph_ptr += glyph->stride;
4686 static void draw_glyph_16( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4687 const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4689 WORD *dst_ptr = get_pixel_ptr_16( dib, rect->left, rect->top );
4690 const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
4694 text = get_field( text_pixel, dib->red_shift, dib->red_len ) << 16 |
4695 get_field( text_pixel, dib->green_shift, dib->green_len ) << 8 |
4696 get_field( text_pixel, dib->blue_shift, dib->blue_len );
4698 for (y = rect->top; y < rect->bottom; y++)
4700 for (x = 0; x < rect->right - rect->left; x++)
4702 if (glyph_ptr[x] <= 1) continue;
4703 if (glyph_ptr[x] >= 16) { dst_ptr[x] = text_pixel; continue; }
4704 val = aa_rgb( get_field(dst_ptr[x], dib->red_shift, dib->red_len),
4705 get_field(dst_ptr[x], dib->green_shift, dib->green_len),
4706 get_field(dst_ptr[x], dib->blue_shift, dib->blue_len),
4707 text, ranges + glyph_ptr[x] );
4708 dst_ptr[x] = (put_field( val >> 16, dib->red_shift, dib->red_len ) |
4709 put_field( val >> 8, dib->green_shift, dib->green_len ) |
4710 put_field( val, dib->blue_shift, dib->blue_len ));
4712 dst_ptr += dib->stride / 2;
4713 glyph_ptr += glyph->stride;
4717 static void draw_glyph_8( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4718 const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4720 BYTE *dst_ptr = get_pixel_ptr_8( dib, rect->left, rect->top );
4721 const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
4724 for (y = rect->top; y < rect->bottom; y++)
4726 for (x = 0; x < rect->right - rect->left; x++)
4728 /* no antialiasing, glyph should only contain 0 or 16. */
4729 if (glyph_ptr[x] >= 16)
4730 dst_ptr[x] = text_pixel;
4732 dst_ptr += dib->stride;
4733 glyph_ptr += glyph->stride;
4737 static void draw_glyph_4( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4738 const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4740 BYTE *dst_ptr = get_pixel_ptr_4( dib, 0, rect->top );
4741 const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x - rect->left, origin->y );
4744 for (y = rect->top; y < rect->bottom; y++)
4746 for (x = rect->left; x < rect->right; x++)
4748 /* no antialiasing, glyph should only contain 0 or 16. */
4749 if (glyph_ptr[x] >= 16)
4752 dst_ptr[x / 2] = text_pixel | (dst_ptr[x / 2] & 0xf0);
4754 dst_ptr[x / 2] = (text_pixel << 4) | (dst_ptr[x / 2] & 0x0f);
4757 dst_ptr += dib->stride;
4758 glyph_ptr += glyph->stride;
4762 static void draw_glyph_1( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4763 const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4765 BYTE *dst_ptr = get_pixel_ptr_1( dib, 0, rect->top );
4766 const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x - rect->left, origin->y );
4768 BYTE text = (text_pixel & 1) ? 0xff : 0;
4770 for (y = rect->top; y < rect->bottom; y++)
4772 for (x = rect->left; x < rect->right; x++)
4774 /* no antialiasing, glyph should only contain 0 or 16. */
4775 if (glyph_ptr[x] >= 16)
4776 dst_ptr[x / 8] = (dst_ptr[x / 8] & ~pixel_masks_1[x % 8]) | (text & pixel_masks_1[x % 8]);
4778 dst_ptr += dib->stride;
4779 glyph_ptr += glyph->stride;
4783 static void draw_glyph_null( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4784 const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4789 static BOOL create_rop_masks_32(const dib_info *dib, const dib_info *hatch, const rop_mask *fg, const rop_mask *bg, rop_mask_bits *bits)
4791 BYTE *hatch_start = get_pixel_ptr_1(hatch, 0, 0), *hatch_ptr;
4792 DWORD mask_start = 0, mask_offset;
4793 DWORD *and_bits = bits->and, *xor_bits = bits->xor;
4796 for(y = 0; y < hatch->height; y++)
4798 hatch_ptr = hatch_start;
4799 mask_offset = mask_start;
4800 for(x = 0; x < hatch->width; x++)
4802 if(*hatch_ptr & pixel_masks_1[x % 8])
4804 and_bits[mask_offset] = fg->and;
4805 xor_bits[mask_offset] = fg->xor;
4809 and_bits[mask_offset] = bg->and;
4810 xor_bits[mask_offset] = bg->xor;
4812 if(x % 8 == 7) hatch_ptr++;
4815 hatch_start += hatch->stride;
4816 mask_start += dib->stride / 4;
4822 static BOOL create_rop_masks_24(const dib_info *dib, const dib_info *hatch, const rop_mask *fg, const rop_mask *bg, rop_mask_bits *bits)
4824 BYTE *hatch_start = get_pixel_ptr_1(hatch, 0, 0), *hatch_ptr;
4825 DWORD mask_start = 0, mask_offset;
4826 BYTE *and_bits = bits->and, *xor_bits = bits->xor;
4829 for(y = 0; y < hatch->height; y++)
4831 hatch_ptr = hatch_start;
4832 mask_offset = mask_start;
4833 for(x = 0; x < hatch->width; x++)
4835 if(*hatch_ptr & pixel_masks_1[x % 8])
4837 and_bits[mask_offset] = fg->and & 0xff;
4838 xor_bits[mask_offset++] = fg->xor & 0xff;
4839 and_bits[mask_offset] = (fg->and >> 8) & 0xff;
4840 xor_bits[mask_offset++] = (fg->xor >> 8) & 0xff;
4841 and_bits[mask_offset] = (fg->and >> 16) & 0xff;
4842 xor_bits[mask_offset++] = (fg->xor >> 16) & 0xff;
4846 and_bits[mask_offset] = bg->and & 0xff;
4847 xor_bits[mask_offset++] = bg->xor & 0xff;
4848 and_bits[mask_offset] = (bg->and >> 8) & 0xff;
4849 xor_bits[mask_offset++] = (bg->xor >> 8) & 0xff;
4850 and_bits[mask_offset] = (bg->and >> 16) & 0xff;
4851 xor_bits[mask_offset++] = (bg->xor >> 16) & 0xff;
4853 if(x % 8 == 7) hatch_ptr++;
4855 hatch_start += hatch->stride;
4856 mask_start += dib->stride;
4862 static BOOL create_rop_masks_16(const dib_info *dib, const dib_info *hatch, const rop_mask *fg, const rop_mask *bg, rop_mask_bits *bits)
4864 BYTE *hatch_start = get_pixel_ptr_1(hatch, 0, 0), *hatch_ptr;
4865 DWORD mask_start = 0, mask_offset;
4866 WORD *and_bits = bits->and, *xor_bits = bits->xor;
4869 for(y = 0; y < hatch->height; y++)
4871 hatch_ptr = hatch_start;
4872 mask_offset = mask_start;
4873 for(x = 0; x < hatch->width; x++)
4875 if(*hatch_ptr & pixel_masks_1[x % 8])
4877 and_bits[mask_offset] = fg->and;
4878 xor_bits[mask_offset] = fg->xor;
4882 and_bits[mask_offset] = bg->and;
4883 xor_bits[mask_offset] = bg->xor;
4885 if(x % 8 == 7) hatch_ptr++;
4888 hatch_start += hatch->stride;
4889 mask_start += dib->stride / 2;
4895 static BOOL create_rop_masks_8(const dib_info *dib, const dib_info *hatch, const rop_mask *fg, const rop_mask *bg, rop_mask_bits *bits)
4897 BYTE *hatch_start = get_pixel_ptr_1(hatch, 0, 0), *hatch_ptr;
4898 DWORD mask_start = 0, mask_offset;
4899 BYTE *and_bits = bits->and, *xor_bits = bits->xor;
4902 for(y = 0; y < hatch->height; y++)
4904 hatch_ptr = hatch_start;
4905 mask_offset = mask_start;
4906 for(x = 0; x < hatch->width; x++)
4908 if(*hatch_ptr & pixel_masks_1[x % 8])
4910 and_bits[mask_offset] = fg->and;
4911 xor_bits[mask_offset] = fg->xor;
4915 and_bits[mask_offset] = bg->and;
4916 xor_bits[mask_offset] = bg->xor;
4918 if(x % 8 == 7) hatch_ptr++;
4921 hatch_start += hatch->stride;
4922 mask_start += dib->stride;
4928 static BOOL create_rop_masks_4(const dib_info *dib, const dib_info *hatch, const rop_mask *fg, const rop_mask *bg, rop_mask_bits *bits)
4930 BYTE *hatch_start = get_pixel_ptr_1(hatch, 0, 0), *hatch_ptr;
4931 DWORD mask_start = 0, mask_offset;
4932 BYTE *and_bits = bits->and, *xor_bits = bits->xor;
4933 const rop_mask *rop_mask;
4936 for(y = 0; y < hatch->height; y++)
4938 hatch_ptr = hatch_start;
4939 mask_offset = mask_start;
4940 for(x = 0; x < hatch->width; x++)
4942 if(*hatch_ptr & pixel_masks_1[x % 8])
4949 and_bits[mask_offset] = (rop_mask->and & 0x0f) | (and_bits[mask_offset] & 0xf0);
4950 xor_bits[mask_offset] = (rop_mask->xor & 0x0f) | (xor_bits[mask_offset] & 0xf0);
4955 and_bits[mask_offset] = (rop_mask->and << 4) & 0xf0;
4956 xor_bits[mask_offset] = (rop_mask->xor << 4) & 0xf0;
4959 if(x % 8 == 7) hatch_ptr++;
4961 hatch_start += hatch->stride;
4962 mask_start += dib->stride;
4968 static BOOL create_rop_masks_1(const dib_info *dib, const dib_info *hatch, const rop_mask *fg, const rop_mask *bg, rop_mask_bits *bits)
4970 BYTE *hatch_start = get_pixel_ptr_1(hatch, 0, 0), *hatch_ptr;
4971 DWORD mask_start = 0, mask_offset;
4972 BYTE *and_bits = bits->and, *xor_bits = bits->xor;
4976 for(y = 0; y < hatch->height; y++)
4978 hatch_ptr = hatch_start;
4979 mask_offset = mask_start;
4980 for(x = 0, bit_pos = 0; x < hatch->width; x++)
4982 if(*hatch_ptr & pixel_masks_1[x % 8])
4984 rop_mask.and = (fg->and & 1) ? 0xff : 0;
4985 rop_mask.xor = (fg->xor & 1) ? 0xff : 0;
4989 rop_mask.and = (bg->and & 1) ? 0xff : 0;
4990 rop_mask.xor = (bg->xor & 1) ? 0xff : 0;
4993 if(bit_pos == 0) and_bits[mask_offset] = xor_bits[mask_offset] = 0;
4995 and_bits[mask_offset] = (rop_mask.and & pixel_masks_1[bit_pos]) | (and_bits[mask_offset] & ~pixel_masks_1[bit_pos]);
4996 xor_bits[mask_offset] = (rop_mask.xor & pixel_masks_1[bit_pos]) | (xor_bits[mask_offset] & ~pixel_masks_1[bit_pos]);
5005 hatch_start += hatch->stride;
5006 mask_start += dib->stride;
5012 static BOOL create_rop_masks_null(const dib_info *dib, const dib_info *hatch, const rop_mask *fg, const rop_mask *bg, rop_mask_bits *bits)
5017 static inline void rop_codes_from_stretch_mode( int mode, struct rop_codes *codes )
5022 case STRETCH_DELETESCANS:
5023 get_rop_codes( R2_COPYPEN, codes );
5025 case STRETCH_ORSCANS:
5026 get_rop_codes( R2_MERGEPEN, codes );
5028 case STRETCH_ANDSCANS:
5029 get_rop_codes( R2_MASKPEN, codes );
5035 static void stretch_row_32(const dib_info *dst_dib, const POINT *dst_start,
5036 const dib_info *src_dib, const POINT *src_start,
5037 const struct stretch_params *params, int mode,
5040 DWORD *dst_ptr = get_pixel_ptr_32( dst_dib, dst_start->x, dst_start->y );
5041 DWORD *src_ptr = get_pixel_ptr_32( src_dib, src_start->x, src_start->y );
5042 int err = params->err_start;
5044 struct rop_codes codes;
5046 rop_codes_from_stretch_mode( mode, &codes );
5047 for (width = params->length; width; width--)
5049 do_rop_codes_32( dst_ptr, *src_ptr, &codes );
5050 dst_ptr += params->dst_inc;
5053 src_ptr += params->src_inc;
5054 err += params->err_add_1;
5056 else err += params->err_add_2;
5060 static void stretch_row_24(const dib_info *dst_dib, const POINT *dst_start,
5061 const dib_info *src_dib, const POINT *src_start,
5062 const struct stretch_params *params, int mode,
5065 BYTE *dst_ptr = get_pixel_ptr_24( dst_dib, dst_start->x, dst_start->y );
5066 BYTE *src_ptr = get_pixel_ptr_24( src_dib, src_start->x, src_start->y );
5067 int err = params->err_start;
5069 struct rop_codes codes;
5071 rop_codes_from_stretch_mode( mode, &codes );
5072 for (width = params->length; width; width--)
5074 do_rop_codes_8( dst_ptr, *src_ptr, &codes );
5075 do_rop_codes_8( dst_ptr + 1, *(src_ptr + 1), &codes );
5076 do_rop_codes_8( dst_ptr + 2, *(src_ptr + 2), &codes );
5077 dst_ptr += 3 * params->dst_inc;
5080 src_ptr += 3 * params->src_inc;
5081 err += params->err_add_1;
5083 else err += params->err_add_2;
5087 static void stretch_row_16(const dib_info *dst_dib, const POINT *dst_start,
5088 const dib_info *src_dib, const POINT *src_start,
5089 const struct stretch_params *params, int mode,
5092 WORD *dst_ptr = get_pixel_ptr_16( dst_dib, dst_start->x, dst_start->y );
5093 WORD *src_ptr = get_pixel_ptr_16( src_dib, src_start->x, src_start->y );
5094 int err = params->err_start;
5096 struct rop_codes codes;
5098 rop_codes_from_stretch_mode( mode, &codes );
5099 for (width = params->length; width; width--)
5101 do_rop_codes_16( dst_ptr, *src_ptr, &codes );
5102 dst_ptr += params->dst_inc;
5105 src_ptr += params->src_inc;
5106 err += params->err_add_1;
5108 else err += params->err_add_2;
5112 static void stretch_row_8(const dib_info *dst_dib, const POINT *dst_start,
5113 const dib_info *src_dib, const POINT *src_start,
5114 const struct stretch_params *params, int mode,
5117 BYTE *dst_ptr = get_pixel_ptr_8( dst_dib, dst_start->x, dst_start->y );
5118 BYTE *src_ptr = get_pixel_ptr_8( src_dib, src_start->x, src_start->y );
5119 int err = params->err_start;
5121 struct rop_codes codes;
5123 rop_codes_from_stretch_mode( mode, &codes );
5124 for (width = params->length; width; width--)
5126 do_rop_codes_8( dst_ptr, *src_ptr, &codes );
5127 dst_ptr += params->dst_inc;
5130 src_ptr += params->src_inc;
5131 err += params->err_add_1;
5133 else err += params->err_add_2;
5137 static void stretch_row_4(const dib_info *dst_dib, const POINT *dst_start,
5138 const dib_info *src_dib, const POINT *src_start,
5139 const struct stretch_params *params, int mode,
5142 BYTE *dst_ptr = get_pixel_ptr_4( dst_dib, dst_start->x, dst_start->y );
5143 BYTE *src_ptr = get_pixel_ptr_4( src_dib, src_start->x, src_start->y );
5144 int err = params->err_start;
5145 int width, dst_x = dst_start->x, src_x = src_start->x;
5146 struct rop_codes codes;
5149 rop_codes_from_stretch_mode( mode, &codes );
5150 for (width = params->length; width; width--)
5152 if (src_x & 1) src_val = (*src_ptr & 0x0f) | (*src_ptr << 4);
5153 else src_val = (*src_ptr & 0xf0) | (*src_ptr >> 4);
5155 do_rop_codes_mask_8( dst_ptr, src_val, &codes, (dst_x & 1) ? 0x0f : 0xf0 );
5157 if ((dst_x & ~1) != ((dst_x + params->dst_inc) & ~1))
5158 dst_ptr += params->dst_inc;
5159 dst_x += params->dst_inc;
5163 if ((src_x & ~1) != ((src_x + params->src_inc) & ~1))
5164 src_ptr += params->src_inc;
5165 src_x += params->src_inc;
5166 err += params->err_add_1;
5168 else err += params->err_add_2;
5172 static void stretch_row_1(const dib_info *dst_dib, const POINT *dst_start,
5173 const dib_info *src_dib, const POINT *src_start,
5174 const struct stretch_params *params, int mode,
5177 BYTE *dst_ptr = get_pixel_ptr_1( dst_dib, dst_start->x, dst_start->y );
5178 BYTE *src_ptr = get_pixel_ptr_1( src_dib, src_start->x, src_start->y );
5179 int err = params->err_start;
5180 int width, dst_x = dst_start->x, src_x = src_start->x;
5181 struct rop_codes codes;
5184 rop_codes_from_stretch_mode( mode, &codes );
5185 for (width = params->length; width; width--)
5187 src_val = *src_ptr & pixel_masks_1[src_x % 8] ? 0xff : 0;
5188 do_rop_codes_mask_8( dst_ptr, src_val, &codes, pixel_masks_1[dst_x % 8] );
5190 if ((dst_x & ~7) != ((dst_x + params->dst_inc) & ~7))
5191 dst_ptr += params->dst_inc;
5192 dst_x += params->dst_inc;
5196 if ((src_x & ~7) != ((src_x + params->src_inc) & ~7))
5197 src_ptr += params->src_inc;
5198 src_x += params->src_inc;
5199 err += params->err_add_1;
5201 else err += params->err_add_2;
5205 static void stretch_row_null(const dib_info *dst_dib, const POINT *dst_start,
5206 const dib_info *src_dib, const POINT *src_start,
5207 const struct stretch_params *params, int mode,
5210 FIXME("bit count %d\n", dst_dib->bit_count);
5214 static void shrink_row_32(const dib_info *dst_dib, const POINT *dst_start,
5215 const dib_info *src_dib, const POINT *src_start,
5216 const struct stretch_params *params, int mode,
5219 DWORD *dst_ptr = get_pixel_ptr_32( dst_dib, dst_start->x, dst_start->y );
5220 DWORD *src_ptr = get_pixel_ptr_32( src_dib, src_start->x, src_start->y );
5221 int err = params->err_start;
5223 struct rop_codes codes;
5224 DWORD init_val = (mode == STRETCH_ANDSCANS) ? ~0u : 0u;
5225 BOOL new_pix = TRUE;
5227 rop_codes_from_stretch_mode( mode, &codes );
5228 for (width = params->length; width; width--)
5230 if (new_pix && !keep_dst) *dst_ptr = init_val;
5231 do_rop_codes_32( dst_ptr, *src_ptr, &codes );
5233 src_ptr += params->src_inc;
5236 dst_ptr += params->dst_inc;
5238 err += params->err_add_1;
5240 else err += params->err_add_2;
5244 static void shrink_row_24(const dib_info *dst_dib, const POINT *dst_start,
5245 const dib_info *src_dib, const POINT *src_start,
5246 const struct stretch_params *params, int mode,
5249 BYTE *dst_ptr = get_pixel_ptr_24( dst_dib, dst_start->x, dst_start->y );
5250 BYTE *src_ptr = get_pixel_ptr_24( src_dib, src_start->x, src_start->y );
5251 int err = params->err_start;
5253 struct rop_codes codes;
5254 BYTE init_val = (mode == STRETCH_ANDSCANS) ? ~0u : 0u;
5255 BOOL new_pix = TRUE;
5257 rop_codes_from_stretch_mode( mode, &codes );
5258 for (width = params->length; width; width--)
5260 if (new_pix && !keep_dst) memset( dst_ptr, init_val, 3 );
5261 do_rop_codes_8( dst_ptr, *src_ptr, &codes );
5262 do_rop_codes_8( dst_ptr + 1, *(src_ptr + 1), &codes );
5263 do_rop_codes_8( dst_ptr + 2, *(src_ptr + 2), &codes );
5265 src_ptr += 3 * params->src_inc;
5268 dst_ptr += 3 * params->dst_inc;
5270 err += params->err_add_1;
5272 else err += params->err_add_2;
5276 static void shrink_row_16(const dib_info *dst_dib, const POINT *dst_start,
5277 const dib_info *src_dib, const POINT *src_start,
5278 const struct stretch_params *params, int mode,
5281 WORD *dst_ptr = get_pixel_ptr_16( dst_dib, dst_start->x, dst_start->y );
5282 WORD *src_ptr = get_pixel_ptr_16( src_dib, src_start->x, src_start->y );
5283 int err = params->err_start;
5285 struct rop_codes codes;
5286 WORD init_val = (mode == STRETCH_ANDSCANS) ? ~0u : 0u;
5287 BOOL new_pix = TRUE;
5289 rop_codes_from_stretch_mode( mode, &codes );
5290 for (width = params->length; width; width--)
5292 if (new_pix && !keep_dst) *dst_ptr = init_val;
5293 do_rop_codes_16( dst_ptr, *src_ptr, &codes );
5295 src_ptr += params->src_inc;
5298 dst_ptr += params->dst_inc;
5300 err += params->err_add_1;
5302 else err += params->err_add_2;
5306 static void shrink_row_8(const dib_info *dst_dib, const POINT *dst_start,
5307 const dib_info *src_dib, const POINT *src_start,
5308 const struct stretch_params *params, int mode,
5311 BYTE *dst_ptr = get_pixel_ptr_8( dst_dib, dst_start->x, dst_start->y );
5312 BYTE *src_ptr = get_pixel_ptr_8( src_dib, src_start->x, src_start->y );
5313 int err = params->err_start;
5315 struct rop_codes codes;
5316 BYTE init_val = (mode == STRETCH_ANDSCANS) ? ~0u : 0u;
5317 BOOL new_pix = TRUE;
5319 rop_codes_from_stretch_mode( mode, &codes );
5320 for (width = params->length; width; width--)
5322 if (new_pix && !keep_dst) *dst_ptr = init_val;
5323 do_rop_codes_8( dst_ptr, *src_ptr, &codes );
5325 src_ptr += params->src_inc;
5328 dst_ptr += params->dst_inc;
5330 err += params->err_add_1;
5332 else err += params->err_add_2;
5336 static void shrink_row_4(const dib_info *dst_dib, const POINT *dst_start,
5337 const dib_info *src_dib, const POINT *src_start,
5338 const struct stretch_params *params, int mode,
5341 BYTE *dst_ptr = get_pixel_ptr_4( dst_dib, dst_start->x, dst_start->y );
5342 BYTE *src_ptr = get_pixel_ptr_4( src_dib, src_start->x, src_start->y );
5343 int err = params->err_start;
5344 int width, dst_x = dst_start->x, src_x = src_start->x;
5345 struct rop_codes codes;
5346 BYTE src_val, init_val = (mode == STRETCH_ANDSCANS) ? ~0u : 0u;
5347 BOOL new_pix = TRUE;
5349 rop_codes_from_stretch_mode( mode, &codes );
5350 for (width = params->length; width; width--)
5352 if (new_pix && !keep_dst) do_rop_mask_8( dst_ptr, 0, init_val, (dst_x & 1) ? 0x0f : 0xf0 );
5354 if (src_x & 1) src_val = (*src_ptr & 0x0f) | (*src_ptr << 4);
5355 else src_val = (*src_ptr & 0xf0) | (*src_ptr >> 4);
5357 do_rop_codes_mask_8( dst_ptr, src_val, &codes, (dst_x & 1) ? 0x0f : 0xf0 );
5360 if ((src_x & ~1) != ((src_x + params->src_inc) & ~1))
5361 src_ptr += params->src_inc;
5362 src_x += params->src_inc;
5366 if ((dst_x & ~1) != ((dst_x + params->dst_inc) & ~1))
5367 dst_ptr += params->dst_inc;
5368 dst_x += params->dst_inc;
5370 err += params->err_add_1;
5372 else err += params->err_add_2;
5376 static void shrink_row_1(const dib_info *dst_dib, const POINT *dst_start,
5377 const dib_info *src_dib, const POINT *src_start,
5378 const struct stretch_params *params, int mode,
5381 BYTE *dst_ptr = get_pixel_ptr_1( dst_dib, dst_start->x, dst_start->y );
5382 BYTE *src_ptr = get_pixel_ptr_1( src_dib, src_start->x, src_start->y );
5383 int err = params->err_start;
5384 int width, dst_x = dst_start->x, src_x = src_start->x;
5385 struct rop_codes codes;
5386 BYTE src_val, init_val = (mode == STRETCH_ANDSCANS) ? ~0u : 0u;
5387 BOOL new_pix = TRUE;
5389 rop_codes_from_stretch_mode( mode, &codes );
5390 for (width = params->length; width; width--)
5392 if (new_pix && !keep_dst) do_rop_mask_8( dst_ptr, 0, init_val, pixel_masks_1[dst_x % 8] );
5393 src_val = *src_ptr & pixel_masks_1[src_x % 8] ? 0xff : 0;
5394 do_rop_codes_mask_8( dst_ptr, src_val, &codes, pixel_masks_1[dst_x % 8] );
5397 if ((src_x & ~7) != ((src_x + params->src_inc) & ~7))
5398 src_ptr += params->src_inc;
5399 src_x += params->src_inc;
5403 if ((dst_x & ~7) != ((dst_x + params->dst_inc) & ~7))
5404 dst_ptr += params->dst_inc;
5405 dst_x += params->dst_inc;
5407 err += params->err_add_1;
5409 else err += params->err_add_2;
5413 static void shrink_row_null(const dib_info *dst_dib, const POINT *dst_start,
5414 const dib_info *src_dib, const POINT *src_start,
5415 const struct stretch_params *params, int mode,
5418 FIXME("bit count %d\n", dst_dib->bit_count);
5422 const primitive_funcs funcs_8888 =
5432 colorref_to_pixel_888,
5433 pixel_to_colorref_888,
5435 create_rop_masks_32,
5440 const primitive_funcs funcs_32 =
5450 colorref_to_pixel_masks,
5451 pixel_to_colorref_masks,
5453 create_rop_masks_32,
5458 const primitive_funcs funcs_24 =
5468 colorref_to_pixel_888,
5469 pixel_to_colorref_888,
5471 create_rop_masks_24,
5476 const primitive_funcs funcs_555 =
5486 colorref_to_pixel_555,
5487 pixel_to_colorref_555,
5489 create_rop_masks_16,
5494 const primitive_funcs funcs_16 =
5504 colorref_to_pixel_masks,
5505 pixel_to_colorref_masks,
5507 create_rop_masks_16,
5512 const primitive_funcs funcs_8 =
5522 colorref_to_pixel_colortable,
5523 pixel_to_colorref_colortable,
5530 const primitive_funcs funcs_4 =
5540 colorref_to_pixel_colortable,
5541 pixel_to_colorref_colortable,
5548 const primitive_funcs funcs_1 =
5558 colorref_to_pixel_colortable,
5559 pixel_to_colorref_colortable,
5566 const primitive_funcs funcs_null =
5576 colorref_to_pixel_null,
5577 pixel_to_colorref_null,
5579 create_rop_masks_null,