mstask: Implement GetTargetComputer.
[wine] / dlls / gdi32 / dibdrv / primitives.c
1 /*
2  * DIB driver primitives.
3  *
4  * Copyright 2011 Huw Davies
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <assert.h>
22
23 #include "gdi_private.h"
24 #include "dibdrv.h"
25
26 #include "wine/debug.h"
27
28 WINE_DEFAULT_DEBUG_CHANNEL(dib);
29
30 /* Bayer matrices for dithering */
31
32 static const BYTE bayer_4x4[4][4] =
33 {
34     {  0,  8,  2, 10 },
35     { 12,  4, 14,  6 },
36     {  3, 11,  1,  9 },
37     { 15,  7, 13,  5 }
38 };
39
40 static const BYTE bayer_8x8[8][8] =
41 {
42     {   0,  32,   8,  40,   2,  34,  10,  42 },
43     {  48,  16,  56,  24,  50,  18,  58,  26 },
44     {  12,  44,   4,  36,  14,  46,   6,  38 },
45     {  60,  28,  52,  20,  62,  30,  54,  22 },
46     {   3,  35,  11,  43,   1,  33,   9,  41 },
47     {  51,  19,  59,  27,  49,  17,  57,  25 },
48     {  15,  47,   7,  39,  13,  45,   5,  37 },
49     {  63,  31,  55,  23,  61,  29,  53,  21 }
50 };
51
52 static const BYTE bayer_16x16[16][16] =
53 {
54     {   0, 128,  32, 160,   8, 136,  40, 168,   2, 130,  34, 162,  10, 138,  42, 170 },
55     { 192,  64, 224,  96, 200,  72, 232, 104, 194,  66, 226,  98, 202,  74, 234, 106 },
56     {  48, 176,  16, 144,  56, 184,  24, 152,  50, 178,  18, 146,  58, 186,  26, 154 },
57     { 240, 112, 208,  80, 248, 120, 216,  88, 242, 114, 210,  82, 250, 122, 218,  90 },
58     {  12, 140,  44, 172,   4, 132,  36, 164,  14, 142,  46, 174,   6, 134,  38, 166 },
59     { 204,  76, 236, 108, 196,  68, 228, 100, 206,  78, 238, 110, 198,  70, 230, 102 },
60     {  60, 188,  28, 156,  52, 180,  20, 148,  62, 190,  30, 158,  54, 182,  22, 150 },
61     { 252, 124, 220,  92, 244, 116, 212,  84, 254, 126, 222,  94, 246, 118, 214,  86 },
62     {   3, 131,  35, 163,  11, 139,  43, 171,   1, 129,  33, 161,   9, 137,  41, 169 },
63     { 195,  67, 227,  99, 203,  75, 235, 107, 193,  65, 225,  97, 201,  73, 233, 105 },
64     {  51, 179,  19, 147,  59, 187,  27, 155,  49, 177,  17, 145,  57, 185,  25, 153 },
65     { 243, 115, 211,  83, 251, 123, 219,  91, 241, 113, 209,  81, 249, 121, 217,  89 },
66     {  15, 143,  47, 175,   7, 135,  39, 167,  13, 141,  45, 173,   5, 133,  37, 165 },
67     { 207,  79, 239, 111, 199,  71, 231, 103, 205,  77, 237, 109, 197,  69, 229, 101 },
68     {  63, 191,  31, 159,  55, 183,  23, 151,  61, 189,  29, 157,  53, 181,  21, 149 },
69     { 255, 127, 223,  95, 247, 119, 215,  87, 253, 125, 221,  93, 245, 117, 213,  85 },
70 };
71
72 static inline DWORD *get_pixel_ptr_32(const dib_info *dib, int x, int y)
73 {
74     return (DWORD *)((BYTE*)dib->bits.ptr + (dib->rect.top + y) * dib->stride + (dib->rect.left + x) * 4);
75 }
76
77 static inline DWORD *get_pixel_ptr_24_dword(const dib_info *dib, int x, int y)
78 {
79     return (DWORD *)((BYTE*)dib->bits.ptr + (dib->rect.top + y) * dib->stride) + (dib->rect.left + x) * 3 / 4;
80 }
81
82 static inline BYTE *get_pixel_ptr_24(const dib_info *dib, int x, int y)
83 {
84     return (BYTE*)dib->bits.ptr + (dib->rect.top + y) * dib->stride + (dib->rect.left + x) * 3;
85 }
86
87 static inline WORD *get_pixel_ptr_16(const dib_info *dib, int x, int y)
88 {
89     return (WORD *)((BYTE*)dib->bits.ptr + (dib->rect.top + y) * dib->stride + (dib->rect.left + x) * 2);
90 }
91
92 static inline BYTE *get_pixel_ptr_8(const dib_info *dib, int x, int y)
93 {
94     return (BYTE*)dib->bits.ptr + (dib->rect.top + y) * dib->stride + dib->rect.left + x;
95 }
96
97 static inline BYTE *get_pixel_ptr_4(const dib_info *dib, int x, int y)
98 {
99     return (BYTE*)dib->bits.ptr + (dib->rect.top + y) * dib->stride + (dib->rect.left + x) / 2;
100 }
101
102 static inline BYTE *get_pixel_ptr_1(const dib_info *dib, int x, int y)
103 {
104     return (BYTE*)dib->bits.ptr + (dib->rect.top + y) * dib->stride + (dib->rect.left + x) / 8;
105 }
106
107 static const BYTE pixel_masks_4[2] = {0xf0, 0x0f};
108 static const BYTE pixel_masks_1[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
109
110 static inline void do_rop_32(DWORD *ptr, DWORD and, DWORD xor)
111 {
112     *ptr = (*ptr & and) ^ xor;
113 }
114
115 static inline void do_rop_16(WORD *ptr, WORD and, WORD xor)
116 {
117     *ptr = (*ptr & and) ^ xor;
118 }
119
120 static inline void do_rop_8(BYTE *ptr, BYTE and, BYTE xor)
121 {
122     *ptr = (*ptr & and) ^ xor;
123 }
124
125 static inline void do_rop_mask_8(BYTE *ptr, BYTE and, BYTE xor, BYTE mask)
126 {
127     *ptr = (*ptr & (and | ~mask)) ^ (xor & mask);
128 }
129
130 static inline void do_rop_codes_32(DWORD *dst, DWORD src, struct rop_codes *codes)
131 {
132     do_rop_32( dst, (src & codes->a1) ^ codes->a2, (src & codes->x1) ^ codes->x2 );
133 }
134
135 static inline void do_rop_codes_16(WORD *dst, WORD src, struct rop_codes *codes)
136 {
137     do_rop_16( dst, (src & codes->a1) ^ codes->a2, (src & codes->x1) ^ codes->x2 );
138 }
139
140 static inline void do_rop_codes_8(BYTE *dst, BYTE src, struct rop_codes *codes)
141 {
142     do_rop_8( dst, (src & codes->a1) ^ codes->a2, (src & codes->x1) ^ codes->x2 );
143 }
144
145 static inline void do_rop_codes_mask_8(BYTE *dst, BYTE src, struct rop_codes *codes, BYTE mask)
146 {
147     do_rop_mask_8( dst, (src & codes->a1) ^ codes->a2, (src & codes->x1) ^ codes->x2, mask );
148 }
149
150 static inline void do_rop_codes_line_32(DWORD *dst, const DWORD *src, struct rop_codes *codes, int len)
151 {
152     for (; len > 0; len--, src++, dst++) do_rop_codes_32( dst, *src, codes );
153 }
154
155 static inline void do_rop_codes_line_rev_32(DWORD *dst, const DWORD *src, struct rop_codes *codes, int len)
156 {
157     for (src += len - 1, dst += len - 1; len > 0; len--, src--, dst--)
158         do_rop_codes_32( dst, *src, codes );
159 }
160
161 static inline void do_rop_codes_line_16(WORD *dst, const WORD *src, struct rop_codes *codes, int len)
162 {
163     for (; len > 0; len--, src++, dst++) do_rop_codes_16( dst, *src, codes );
164 }
165
166 static inline void do_rop_codes_line_rev_16(WORD *dst, const WORD *src, struct rop_codes *codes, int len)
167 {
168     for (src += len - 1, dst += len - 1; len > 0; len--, src--, dst--)
169         do_rop_codes_16( dst, *src, codes );
170 }
171
172 static inline void do_rop_codes_line_8(BYTE *dst, const BYTE *src, struct rop_codes *codes, int len)
173 {
174     for (; len > 0; len--, src++, dst++) do_rop_codes_8( dst, *src, codes );
175 }
176
177 static inline void do_rop_codes_line_rev_8(BYTE *dst, const BYTE *src, struct rop_codes *codes, int len)
178 {
179     for (src += len - 1, dst += len - 1; len > 0; len--, src--, dst--)
180         do_rop_codes_8( dst, *src, codes );
181 }
182
183 static inline void do_rop_codes_line_4(BYTE *dst, int dst_x, const BYTE *src, int src_x,
184                                       struct rop_codes *codes, int len)
185 {
186     BYTE src_val;
187
188     for (src += src_x / 2, dst += dst_x / 2; len > 0; len--, dst_x++, src_x++)
189     {
190         if (dst_x & 1)
191         {
192             if (src_x & 1) src_val = *src++;
193             else           src_val = *src >> 4;
194             do_rop_codes_mask_8( dst++, src_val, codes, 0x0f );
195         }
196         else
197         {
198             if (src_x & 1) src_val = *src++ << 4;
199             else           src_val = *src;
200             do_rop_codes_mask_8( dst, src_val, codes, 0xf0 );
201         }
202     }
203 }
204
205 static inline void do_rop_codes_line_rev_4(BYTE *dst, int dst_x, const BYTE *src, int src_x,
206                                           struct rop_codes *codes, int len)
207 {
208     BYTE src_val;
209
210     src_x += len - 1;
211     dst_x += len - 1;
212     for (src += src_x / 2, dst += dst_x / 2; len > 0; len--, dst_x--, src_x--)
213     {
214         if (dst_x & 1)
215         {
216             if (src_x & 1) src_val = *src;
217             else           src_val = *src-- >> 4;
218             do_rop_codes_mask_8( dst, src_val, codes, 0x0f );
219         }
220         else
221         {
222             if (src_x & 1) src_val = *src << 4;
223             else           src_val = *src--;
224             do_rop_codes_mask_8( dst--, src_val, codes, 0xf0 );
225         }
226     }
227 }
228
229 static inline void do_rop_codes_line_1(BYTE *dst, int dst_x, const BYTE *src, int src_x,
230                                       struct rop_codes *codes, int len)
231 {
232     BYTE src_val;
233
234     for (src += src_x / 8, dst += dst_x / 8; len > 0; len--, dst_x++, src_x++)
235     {
236         src_val = *src & pixel_masks_1[src_x & 7] ? 0xff : 0;
237         do_rop_codes_mask_8( dst, src_val, codes, pixel_masks_1[dst_x & 7] );
238         if ((src_x & 7) == 7) src++;
239         if ((dst_x & 7) == 7) dst++;
240     }
241 }
242
243 static inline void do_rop_codes_line_rev_1(BYTE *dst, int dst_x, const BYTE *src, int src_x,
244                                           struct rop_codes *codes, int len)
245 {
246     BYTE src_val;
247
248     src_x += len - 1;
249     dst_x += len - 1;
250     for (src += src_x / 8, dst += dst_x / 8; len > 0; len--, dst_x--, src_x--)
251     {
252         src_val = *src & pixel_masks_1[src_x & 7] ? 0xff : 0;
253         do_rop_codes_mask_8( dst, src_val, codes, pixel_masks_1[dst_x & 7] );
254         if ((src_x & 7) == 0) src--;
255         if ((dst_x & 7) == 0) dst--;
256     }
257 }
258
259 static void solid_rects_32(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
260 {
261     DWORD *ptr, *start;
262     int x, y, i;
263
264     for(i = 0; i < num; i++, rc++)
265     {
266         start = get_pixel_ptr_32(dib, rc->left, rc->top);
267         for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 4)
268             for(x = rc->left, ptr = start; x < rc->right; x++)
269                 do_rop_32(ptr++, and, xor);
270     }
271 }
272
273 static void solid_rects_24(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
274 {
275     DWORD *ptr, *start;
276     BYTE *byte_ptr, *byte_start;
277     int x, y, i;
278     DWORD and_masks[3], xor_masks[3];
279
280     and_masks[0] = ( and        & 0x00ffffff) | ((and << 24) & 0xff000000);
281     and_masks[1] = ((and >>  8) & 0x0000ffff) | ((and << 16) & 0xffff0000);
282     and_masks[2] = ((and >> 16) & 0x000000ff) | ((and <<  8) & 0xffffff00);
283     xor_masks[0] = ( xor        & 0x00ffffff) | ((xor << 24) & 0xff000000);
284     xor_masks[1] = ((xor >>  8) & 0x0000ffff) | ((xor << 16) & 0xffff0000);
285     xor_masks[2] = ((xor >> 16) & 0x000000ff) | ((xor <<  8) & 0xffffff00);
286
287     for(i = 0; i < num; i++, rc++)
288     {
289         int left = dib->rect.left + rc->left;
290         int right = dib->rect.left + rc->right;
291
292         if (left >= right) continue;
293
294         if ((left & ~3) == (right & ~3)) /* Special case for lines that start and end in the same DWORD triplet */
295         {
296             byte_start = get_pixel_ptr_24(dib, rc->left, rc->top);
297             for(y = rc->top; y < rc->bottom; y++, byte_start += dib->stride)
298             {
299                 for(x = left, byte_ptr = byte_start; x < right; x++)
300                 {
301                     do_rop_8(byte_ptr++, and_masks[0] & 0xff, xor_masks[0] & 0xff);
302                     do_rop_8(byte_ptr++, and_masks[1] & 0xff, xor_masks[1] & 0xff);
303                     do_rop_8(byte_ptr++, and_masks[2] & 0xff, xor_masks[2] & 0xff);
304                 }
305             }
306         }
307         else
308         {
309             start = get_pixel_ptr_24_dword(dib, rc->left, rc->top);
310             for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 4)
311             {
312                 ptr = start;
313
314                 switch(left & 3)
315                 {
316                 case 1:
317                     do_rop_32(ptr++, and_masks[0] | 0x00ffffff, xor_masks[0] & 0xff000000);
318                     do_rop_32(ptr++, and_masks[1], xor_masks[1]);
319                     do_rop_32(ptr++, and_masks[2], xor_masks[2]);
320                     break;
321                 case 2:
322                     do_rop_32(ptr++, and_masks[1] | 0x0000ffff, xor_masks[1] & 0xffff0000);
323                     do_rop_32(ptr++, and_masks[2], xor_masks[2]);
324                     break;
325                 case 3:
326                     do_rop_32(ptr++, and_masks[2] | 0x000000ff, xor_masks[2] & 0xffffff00);
327                     break;
328                 }
329
330                 for(x = (left + 3) & ~3; x < (right & ~3); x += 4)
331                 {
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], xor_masks[2]);
335                 }
336
337                 switch(right & 3)
338                 {
339                 case 1:
340                     do_rop_32(ptr, and_masks[0] | 0xff000000, xor_masks[0] & 0x00ffffff);
341                     break;
342                 case 2:
343                     do_rop_32(ptr++, and_masks[0], xor_masks[0]);
344                     do_rop_32(ptr,   and_masks[1] | 0xffff0000, xor_masks[1] & 0x0000ffff);
345                     break;
346                 case 3:
347                     do_rop_32(ptr++, and_masks[0], xor_masks[0]);
348                     do_rop_32(ptr++, and_masks[1], xor_masks[1]);
349                     do_rop_32(ptr,   and_masks[2] | 0xffffff00, xor_masks[2] & 0x000000ff);
350                     break;
351                 }
352             }
353         }
354     }
355 }
356
357 static void solid_rects_16(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
358 {
359     WORD *ptr, *start;
360     int x, y, i;
361
362     for(i = 0; i < num; i++, rc++)
363     {
364         start = get_pixel_ptr_16(dib, rc->left, rc->top);
365         for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 2)
366             for(x = rc->left, ptr = start; x < rc->right; x++)
367                 do_rop_16(ptr++, and, xor);
368     }
369 }
370
371 static void solid_rects_8(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
372 {
373     BYTE *ptr, *start;
374     int x, y, i;
375
376     for(i = 0; i < num; i++, rc++)
377     {
378         start = get_pixel_ptr_8(dib, rc->left, rc->top);
379         for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
380             for(x = rc->left, ptr = start; x < rc->right; x++)
381                 do_rop_8(ptr++, and, xor);
382     }
383 }
384
385 static void solid_rects_4(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
386 {
387     BYTE *ptr, *start;
388     int x, y, i;
389     BYTE byte_and = (and & 0xf) | ((and << 4) & 0xf0);
390     BYTE byte_xor = (xor & 0xf) | ((xor << 4) & 0xf0);
391
392     for(i = 0; i < num; i++, rc++)
393     {
394         int left = dib->rect.left + rc->left;
395         int right = dib->rect.left + rc->right;
396
397         if (left >= right) continue;
398         start = get_pixel_ptr_4(dib, rc->left, rc->top);
399         for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
400         {
401             ptr = start;
402             if(left & 1) /* upper nibble untouched */
403                 do_rop_8(ptr++, byte_and | 0xf0, byte_xor & 0x0f);
404
405             for(x = (left + 1) & ~1; x < (right & ~1); x += 2)
406                 do_rop_8(ptr++, byte_and, byte_xor);
407
408             if(right & 1) /* lower nibble untouched */
409                 do_rop_8(ptr, byte_and | 0x0f, byte_xor & 0xf0);
410         }
411     }
412 }
413
414 static void solid_rects_1(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
415 {
416     BYTE *ptr, *start;
417     int x, y, i;
418     BYTE byte_and = (and & 1) ? 0xff : 0;
419     BYTE byte_xor = (xor & 1) ? 0xff : 0;
420     BYTE start_and, start_xor, end_and, end_xor, mask;
421     static const BYTE masks[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
422
423     for(i = 0; i < num; i++, rc++)
424     {
425         int left = dib->rect.left + rc->left;
426         int right = dib->rect.left + rc->right;
427
428         if (left >= right) continue;
429
430         start = get_pixel_ptr_1(dib, rc->left, rc->top);
431
432         if ((left & ~7) == (right & ~7)) /* Special case for lines that start and end in the same byte */
433         {
434             mask = masks[left & 7] & ~masks[right & 7];
435
436             start_and = byte_and | ~mask;
437             start_xor = byte_xor & mask;
438             for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
439             {
440                 do_rop_8(start, start_and, start_xor);
441             }
442         }
443         else
444         {
445             mask = masks[left & 7];
446             start_and = byte_and | ~mask;
447             start_xor = byte_xor & mask;
448
449             mask = masks[right & 7];
450             /* This is inverted wrt to start mask, so end_and/xor assignments reflect this */
451             end_and = byte_and | mask;
452             end_xor = byte_xor & ~mask;
453
454             for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
455             {
456                 ptr = start;
457
458                 if(left & 7)
459                     do_rop_8(ptr++, start_and, start_xor);
460
461                 for(x = (left + 7) & ~7; x < (right & ~7); x += 8)
462                     do_rop_8(ptr++, byte_and, byte_xor);
463
464                 if(right & 7)
465                     do_rop_8(ptr, end_and, end_xor);
466             }
467         }
468     }
469 }
470
471 static void solid_rects_null(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
472 {
473     return;
474 }
475
476 static void solid_line_32(const dib_info *dib, const POINT *start, const struct line_params *params,
477                           DWORD and, DWORD xor)
478 {
479     DWORD *ptr = get_pixel_ptr_32( dib, start->x, start->y );
480     int len = params->length, err = params->err_start;
481     int major_inc, minor_inc;
482
483     if (params->x_major)
484     {
485         major_inc = params->x_inc;
486         minor_inc = (dib->stride * params->y_inc) / 4;
487     }
488     else
489     {
490         major_inc = (dib->stride * params->y_inc) / 4;
491         minor_inc = params->x_inc;
492     }
493
494     while (len--)
495     {
496         do_rop_32( ptr, and, xor );
497         if (err + params->bias > 0)
498         {
499             ptr += minor_inc;
500             err += params->err_add_1;
501         }
502         else err += params->err_add_2;
503         ptr += major_inc;
504     }
505 }
506
507 static void solid_line_24(const dib_info *dib, const POINT *start, const struct line_params *params,
508                          DWORD and, DWORD xor)
509 {
510     BYTE *ptr = get_pixel_ptr_24( dib, start->x, start->y );
511     int len = params->length, err = params->err_start;
512     int major_inc, minor_inc;
513
514     if (params->x_major)
515     {
516         major_inc = params->x_inc * 3;
517         minor_inc = dib->stride * params->y_inc;
518     }
519     else
520     {
521         major_inc = dib->stride * params->y_inc;
522         minor_inc = params->x_inc * 3;
523     }
524
525     while (len--)
526     {
527         do_rop_8( ptr,     and,       xor );
528         do_rop_8( ptr + 1, and >> 8,  xor >> 8 );
529         do_rop_8( ptr + 2, and >> 16, xor >> 16 );
530         if (err + params->bias > 0)
531         {
532             ptr += minor_inc;
533             err += params->err_add_1;
534         }
535         else err += params->err_add_2;
536         ptr += major_inc;
537     }
538 }
539
540 static void solid_line_16(const dib_info *dib, const POINT *start, const struct line_params *params,
541                           DWORD and, DWORD xor)
542 {
543     WORD *ptr = get_pixel_ptr_16( dib, start->x, start->y );
544     int len = params->length, err = params->err_start;
545     int major_inc, minor_inc;
546
547     if (params->x_major)
548     {
549         major_inc = params->x_inc;
550         minor_inc = (dib->stride * params->y_inc) / 2;
551     }
552     else
553     {
554         major_inc = (dib->stride * params->y_inc) / 2;
555         minor_inc = params->x_inc;
556     }
557
558     while (len--)
559     {
560         do_rop_16( ptr, and, xor );
561         if (err + params->bias > 0)
562         {
563             ptr += minor_inc;
564             err += params->err_add_1;
565         }
566         else err += params->err_add_2;
567         ptr += major_inc;
568     }
569 }
570
571 static void solid_line_8(const dib_info *dib, const POINT *start, const struct line_params *params,
572                          DWORD and, DWORD xor)
573 {
574     BYTE *ptr = get_pixel_ptr_8( dib, start->x, start->y );
575     int len = params->length, err = params->err_start;
576     int major_inc, minor_inc;
577
578     if (params->x_major)
579     {
580         major_inc = params->x_inc;
581         minor_inc = dib->stride * params->y_inc;
582     }
583     else
584     {
585         major_inc = dib->stride * params->y_inc;
586         minor_inc = params->x_inc;
587     }
588
589     while (len--)
590     {
591         do_rop_8( ptr, and, xor );
592         if (err + params->bias > 0)
593         {
594             ptr += minor_inc;
595             err += params->err_add_1;
596         }
597         else err += params->err_add_2;
598         ptr += major_inc;
599     }
600 }
601
602 static void solid_line_4(const dib_info *dib, const POINT *start, const struct line_params *params,
603                          DWORD and, DWORD xor)
604 {
605     BYTE *ptr = get_pixel_ptr_4( dib, start->x, start->y );
606     int len = params->length, err = params->err_start;
607     int x = dib->rect.left + start->x;
608
609     and = (and & 0x0f) | ((and << 4) & 0xf0);
610     xor = (xor & 0x0f) | ((xor << 4) & 0xf0);
611
612     if (params->x_major)
613     {
614         while (len--)
615         {
616             do_rop_mask_8( ptr, and, xor, pixel_masks_4[ x % 2 ] );
617             if (err + params->bias > 0)
618             {
619                 ptr += dib->stride * params->y_inc;
620                 err += params->err_add_1;
621             }
622             else err += params->err_add_2;
623             if ((x / 2) != ((x + params->x_inc) / 2))
624                 ptr += params->x_inc;
625             x += params->x_inc;
626         }
627     }
628     else
629     {
630         while (len--)
631         {
632             do_rop_mask_8( ptr, and, xor, pixel_masks_4[ x % 2 ] );
633             if (err + params->bias > 0)
634             {
635                 if ((x / 2) != ((x + params->x_inc) / 2))
636                     ptr += params->x_inc;
637                 x += params->x_inc;
638                 err += params->err_add_1;
639             }
640             else err += params->err_add_2;
641             ptr += dib->stride * params->y_inc;
642         }
643     }
644 }
645
646 static void solid_line_1(const dib_info *dib, const POINT *start, const struct line_params *params,
647                          DWORD and, DWORD xor)
648 {
649     BYTE *ptr = get_pixel_ptr_1( dib, start->x, start->y );
650     int len = params->length, err = params->err_start;
651     int x = dib->rect.left + start->x;
652
653     and = (and & 0x1) ? 0xff : 0;
654     xor = (xor & 0x1) ? 0xff : 0;
655
656     if (params->x_major)
657     {
658         while (len--)
659         {
660             do_rop_mask_8( ptr, and, xor, pixel_masks_1[ x % 8 ] );
661             if (err + params->bias > 0)
662             {
663                 ptr += dib->stride * params->y_inc;
664                 err += params->err_add_1;
665             }
666             else err += params->err_add_2;
667             if ((x / 8) != ((x + params->x_inc) / 8))
668                 ptr += params->x_inc;
669             x += params->x_inc;
670         }
671     }
672     else
673     {
674         while (len--)
675         {
676             do_rop_mask_8( ptr, and, xor, pixel_masks_1[ x % 8 ] );
677             if (err + params->bias > 0)
678             {
679                 if ((x / 8) != ((x + params->x_inc) / 8))
680                     ptr += params->x_inc;
681                 x += params->x_inc;
682                 err += params->err_add_1;
683             }
684             else err += params->err_add_2;
685             ptr += dib->stride * params->y_inc;
686         }
687     }
688 }
689
690 static void solid_line_null(const dib_info *dib, const POINT *start, const struct line_params *params,
691                             DWORD and, DWORD xor)
692 {
693     return;
694 }
695
696 static inline INT calc_offset(INT edge, INT size, INT origin)
697 {
698     INT offset;
699
700     if(edge - origin >= 0)
701         offset = (edge - origin) % size;
702     else
703     {
704         offset = (origin - edge) % size;
705         if(offset) offset = size - offset;
706     }
707     return offset;
708 }
709
710 static inline POINT calc_brush_offset(const RECT *rc, const dib_info *brush, const POINT *origin)
711 {
712     POINT offset;
713
714     offset.x = calc_offset(rc->left, brush->width,  origin->x);
715     offset.y = calc_offset(rc->top,  brush->height, origin->y);
716
717     return offset;
718 }
719
720 static void pattern_rects_32(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
721                              const dib_info *brush, const rop_mask_bits *bits)
722 {
723     DWORD *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
724     int x, y, i;
725     POINT offset;
726
727     for(i = 0; i < num; i++, rc++)
728     {
729         offset = calc_brush_offset(rc, brush, origin);
730
731         start = get_pixel_ptr_32(dib, rc->left, rc->top);
732         start_and = (DWORD*)bits->and + offset.y * brush->stride / 4;
733         start_xor = (DWORD*)bits->xor + offset.y * brush->stride / 4;
734
735         for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 4)
736         {
737             and_ptr = start_and + offset.x;
738             xor_ptr = start_xor + offset.x;
739
740             for(x = rc->left, ptr = start; x < rc->right; x++)
741             {
742                 do_rop_32(ptr++, *and_ptr++, *xor_ptr++);
743                 if(and_ptr == start_and + brush->width)
744                 {
745                     and_ptr = start_and;
746                     xor_ptr = start_xor;
747                 }
748             }
749
750             offset.y++;
751             if(offset.y == brush->height)
752             {
753                 start_and = bits->and;
754                 start_xor = bits->xor;
755                 offset.y = 0;
756             }
757             else
758             {
759                 start_and += brush->stride / 4;
760                 start_xor += brush->stride / 4;
761             }
762         }
763     }
764 }
765
766 static void pattern_rects_24(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
767                              const dib_info *brush, const rop_mask_bits *bits)
768 {
769     BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
770     int x, y, i;
771     POINT offset;
772
773     for(i = 0; i < num; i++, rc++)
774     {
775         offset = calc_brush_offset(rc, brush, origin);
776
777         start = get_pixel_ptr_24(dib, rc->left, rc->top);
778         start_and = (BYTE*)bits->and + offset.y * brush->stride;
779         start_xor = (BYTE*)bits->xor + offset.y * brush->stride;
780
781         for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
782         {
783             and_ptr = start_and + offset.x * 3;
784             xor_ptr = start_xor + offset.x * 3;
785
786             for(x = rc->left, ptr = start; x < rc->right; x++)
787             {
788                 do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
789                 do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
790                 do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
791                 if(and_ptr == start_and + brush->width * 3)
792                 {
793                     and_ptr = start_and;
794                     xor_ptr = start_xor;
795                 }
796             }
797
798             offset.y++;
799             if(offset.y == brush->height)
800             {
801                 start_and = bits->and;
802                 start_xor = bits->xor;
803                 offset.y = 0;
804             }
805             else
806             {
807                 start_and += brush->stride;
808                 start_xor += brush->stride;
809             }
810         }
811     }
812 }
813
814 static void pattern_rects_16(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
815                              const dib_info *brush, const rop_mask_bits *bits)
816 {
817     WORD *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
818     int x, y, i;
819     POINT offset;
820
821     for(i = 0; i < num; i++, rc++)
822     {
823         offset = calc_brush_offset(rc, brush, origin);
824
825         start = get_pixel_ptr_16(dib, rc->left, rc->top);
826         start_and = (WORD*)bits->and + offset.y * brush->stride / 2;
827         start_xor = (WORD*)bits->xor + offset.y * brush->stride / 2;
828
829         for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 2)
830         {
831             and_ptr = start_and + offset.x;
832             xor_ptr = start_xor + offset.x;
833
834             for(x = rc->left, ptr = start; x < rc->right; x++)
835             {
836                 do_rop_16(ptr++, *and_ptr++, *xor_ptr++);
837                 if(and_ptr == start_and + brush->width)
838                 {
839                     and_ptr = start_and;
840                     xor_ptr = start_xor;
841                 }
842             }
843
844             offset.y++;
845             if(offset.y == brush->height)
846             {
847                 start_and = bits->and;
848                 start_xor = bits->xor;
849                 offset.y = 0;
850             }
851             else
852             {
853                 start_and += brush->stride / 2;
854                 start_xor += brush->stride / 2;
855             }
856         }
857     }
858 }
859
860 static void pattern_rects_8(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
861                             const dib_info *brush, const rop_mask_bits *bits)
862 {
863     BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
864     int x, y, i;
865     POINT offset;
866
867     for(i = 0; i < num; i++, rc++)
868     {
869         offset = calc_brush_offset(rc, brush, origin);
870
871         start = get_pixel_ptr_8(dib, rc->left, rc->top);
872         start_and = (BYTE*)bits->and + offset.y * brush->stride;
873         start_xor = (BYTE*)bits->xor + offset.y * brush->stride;
874
875         for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
876         {
877             and_ptr = start_and + offset.x;
878             xor_ptr = start_xor + offset.x;
879
880             for(x = rc->left, ptr = start; x < rc->right; x++)
881             {
882                 do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
883                 if(and_ptr == start_and + brush->width)
884                 {
885                     and_ptr = start_and;
886                     xor_ptr = start_xor;
887                 }
888             }
889
890             offset.y++;
891             if(offset.y == brush->height)
892             {
893                 start_and = bits->and;
894                 start_xor = bits->xor;
895                 offset.y = 0;
896             }
897             else
898             {
899                 start_and += brush->stride;
900                 start_xor += brush->stride;
901             }
902         }
903     }
904 }
905
906 static void pattern_rects_4(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
907                             const dib_info *brush, const rop_mask_bits *bits)
908 {
909     BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
910     int x, y, i, left, right;
911     POINT offset;
912
913     for(i = 0; i < num; i++, rc++)
914     {
915         offset = calc_brush_offset(rc, brush, origin);
916         left = dib->rect.left + rc->left;
917         right = dib->rect.left + rc->right;
918
919         start = get_pixel_ptr_4(dib, rc->left, rc->top);
920         start_and = (BYTE*)bits->and + offset.y * brush->stride;
921         start_xor = (BYTE*)bits->xor + offset.y * brush->stride;
922
923         for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
924         {
925             INT brush_x = offset.x;
926             BYTE byte_and, byte_xor;
927
928             and_ptr = start_and + brush_x / 2;
929             xor_ptr = start_xor + brush_x / 2;
930
931             for(x = left, ptr = start; x < right; x++)
932             {
933                 /* FIXME: Two pixels at a time */
934                 if(x & 1) /* lower dst nibble */
935                 {
936                     if(brush_x & 1) /* lower pat nibble */
937                     {
938                         byte_and = *and_ptr++ | 0xf0;
939                         byte_xor = *xor_ptr++ & 0x0f;
940                     }
941                     else /* upper pat nibble */
942                     {
943                         byte_and = (*and_ptr >> 4) | 0xf0;
944                         byte_xor = (*xor_ptr >> 4) & 0x0f;
945                     }
946                 }
947                 else /* upper dst nibble */
948                 {
949                     if(brush_x & 1) /* lower pat nibble */
950                     {
951                         byte_and = (*and_ptr++ << 4) | 0x0f;
952                         byte_xor = (*xor_ptr++ << 4) & 0xf0;
953                     }
954                     else /* upper pat nibble */
955                     {
956                         byte_and = *and_ptr | 0x0f;
957                         byte_xor = *xor_ptr & 0xf0;
958                     }
959                 }
960                 do_rop_8(ptr, byte_and, byte_xor);
961
962                 if(x & 1) ptr++;
963
964                 if(++brush_x == brush->width)
965                 {
966                     brush_x = 0;
967                     and_ptr = start_and;
968                     xor_ptr = start_xor;
969                 }
970             }
971
972             offset.y++;
973             if(offset.y == brush->height)
974             {
975                 start_and = bits->and;
976                 start_xor = bits->xor;
977                 offset.y = 0;
978             }
979             else
980             {
981                 start_and += brush->stride;
982                 start_xor += brush->stride;
983             }
984         }
985     }
986 }
987
988 static void pattern_rects_1(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
989                             const dib_info *brush, const rop_mask_bits *bits)
990 {
991     BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
992     int x, y, i, left, right;
993     POINT offset;
994
995     for(i = 0; i < num; i++, rc++)
996     {
997         offset = calc_brush_offset(rc, brush, origin);
998         left = dib->rect.left + rc->left;
999         right = dib->rect.left + rc->right;
1000
1001         start = get_pixel_ptr_1(dib, rc->left, rc->top);
1002         start_and = (BYTE*)bits->and + offset.y * brush->stride;
1003         start_xor = (BYTE*)bits->xor + offset.y * brush->stride;
1004
1005         for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
1006         {
1007             INT brush_x = offset.x;
1008             BYTE byte_and, byte_xor;
1009
1010             and_ptr = start_and + brush_x / 8;
1011             xor_ptr = start_xor + brush_x / 8;
1012
1013             for(x = left, ptr = start; x < right; x++)
1014             {
1015                 byte_and = (*and_ptr & pixel_masks_1[brush_x % 8]) ? 0xff : 0;
1016                 byte_and |= ~pixel_masks_1[x % 8];
1017                 byte_xor = (*xor_ptr & pixel_masks_1[brush_x % 8]) ? 0xff : 0;
1018                 byte_xor &= pixel_masks_1[x % 8];
1019
1020                 do_rop_8(ptr, byte_and, byte_xor);
1021
1022                 if((x & 7) == 7) ptr++;
1023
1024                 if((brush_x & 7) == 7)
1025                 {
1026                     and_ptr++;
1027                     xor_ptr++;
1028                 }
1029
1030                 if(++brush_x == brush->width)
1031                 {
1032                     brush_x = 0;
1033                     and_ptr = start_and;
1034                     xor_ptr = start_xor;
1035                 }
1036             }
1037
1038             offset.y++;
1039             if(offset.y == brush->height)
1040             {
1041                 start_and = bits->and;
1042                 start_xor = bits->xor;
1043                 offset.y = 0;
1044             }
1045             else
1046             {
1047                 start_and += brush->stride;
1048                 start_xor += brush->stride;
1049             }
1050         }
1051     }
1052 }
1053
1054 static void pattern_rects_null(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
1055                                const dib_info *brush, const rop_mask_bits *bits)
1056 {
1057     return;
1058 }
1059
1060 static void copy_rect_32(const dib_info *dst, const RECT *rc,
1061                          const dib_info *src, const POINT *origin, int rop2, int overlap)
1062 {
1063     DWORD *dst_start, *src_start;
1064     struct rop_codes codes;
1065     int y, dst_stride, src_stride;
1066
1067     if (overlap & OVERLAP_BELOW)
1068     {
1069         dst_start = get_pixel_ptr_32(dst, rc->left, rc->bottom - 1);
1070         src_start = get_pixel_ptr_32(src, origin->x, origin->y + rc->bottom - rc->top - 1);
1071         dst_stride = -dst->stride / 4;
1072         src_stride = -src->stride / 4;
1073     }
1074     else
1075     {
1076         dst_start = get_pixel_ptr_32(dst, rc->left, rc->top);
1077         src_start = get_pixel_ptr_32(src, origin->x, origin->y);
1078         dst_stride = dst->stride / 4;
1079         src_stride = src->stride / 4;
1080     }
1081
1082     if (rop2 == R2_COPYPEN)
1083     {
1084         for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1085             memmove( dst_start, src_start, (rc->right - rc->left) * 4 );
1086         return;
1087     }
1088
1089     get_rop_codes( rop2, &codes );
1090     for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1091     {
1092         if (overlap & OVERLAP_RIGHT)
1093             do_rop_codes_line_rev_32( dst_start, src_start, &codes, rc->right - rc->left );
1094         else
1095             do_rop_codes_line_32( dst_start, src_start, &codes, rc->right - rc->left );
1096     }
1097 }
1098
1099 static void copy_rect_24(const dib_info *dst, const RECT *rc,
1100                          const dib_info *src, const POINT *origin, int rop2, int overlap)
1101 {
1102     BYTE *dst_start, *src_start;
1103     int y, dst_stride, src_stride;
1104     struct rop_codes codes;
1105
1106     if (overlap & OVERLAP_BELOW)
1107     {
1108         dst_start = get_pixel_ptr_24(dst, rc->left, rc->bottom - 1);
1109         src_start = get_pixel_ptr_24(src, origin->x, origin->y + rc->bottom - rc->top - 1);
1110         dst_stride = -dst->stride;
1111         src_stride = -src->stride;
1112     }
1113     else
1114     {
1115         dst_start = get_pixel_ptr_24(dst, rc->left, rc->top);
1116         src_start = get_pixel_ptr_24(src, origin->x, origin->y);
1117         dst_stride = dst->stride;
1118         src_stride = src->stride;
1119     }
1120
1121     if (rop2 == R2_COPYPEN)
1122     {
1123         for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1124             memmove( dst_start, src_start, (rc->right - rc->left) * 3 );
1125         return;
1126     }
1127
1128     get_rop_codes( rop2, &codes );
1129     for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1130     {
1131         if (overlap & OVERLAP_RIGHT)
1132             do_rop_codes_line_rev_8( dst_start, src_start, &codes, (rc->right - rc->left) * 3 );
1133         else
1134             do_rop_codes_line_8( dst_start, src_start, &codes, (rc->right - rc->left) * 3 );
1135     }
1136 }
1137
1138 static void copy_rect_16(const dib_info *dst, const RECT *rc,
1139                          const dib_info *src, const POINT *origin, int rop2, int overlap)
1140 {
1141     WORD *dst_start, *src_start;
1142     int y, dst_stride, src_stride;
1143     struct rop_codes codes;
1144
1145     if (overlap & OVERLAP_BELOW)
1146     {
1147         dst_start = get_pixel_ptr_16(dst, rc->left, rc->bottom - 1);
1148         src_start = get_pixel_ptr_16(src, origin->x, origin->y + rc->bottom - rc->top - 1);
1149         dst_stride = -dst->stride / 2;
1150         src_stride = -src->stride / 2;
1151     }
1152     else
1153     {
1154         dst_start = get_pixel_ptr_16(dst, rc->left, rc->top);
1155         src_start = get_pixel_ptr_16(src, origin->x, origin->y);
1156         dst_stride = dst->stride / 2;
1157         src_stride = src->stride / 2;
1158     }
1159
1160     if (rop2 == R2_COPYPEN)
1161     {
1162         for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1163             memmove( dst_start, src_start, (rc->right - rc->left) * 2 );
1164         return;
1165     }
1166
1167     get_rop_codes( rop2, &codes );
1168     for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1169     {
1170         if (overlap & OVERLAP_RIGHT)
1171             do_rop_codes_line_rev_16( dst_start, src_start, &codes, rc->right - rc->left );
1172         else
1173             do_rop_codes_line_16( dst_start, src_start, &codes, rc->right - rc->left );
1174     }
1175 }
1176
1177 static void copy_rect_8(const dib_info *dst, const RECT *rc,
1178                         const dib_info *src, const POINT *origin, int rop2, int overlap)
1179 {
1180     BYTE *dst_start, *src_start;
1181     int y, dst_stride, src_stride;
1182     struct rop_codes codes;
1183
1184     if (overlap & OVERLAP_BELOW)
1185     {
1186         dst_start = get_pixel_ptr_8(dst, rc->left, rc->bottom - 1);
1187         src_start = get_pixel_ptr_8(src, origin->x, origin->y + rc->bottom - rc->top - 1);
1188         dst_stride = -dst->stride;
1189         src_stride = -src->stride;
1190     }
1191     else
1192     {
1193         dst_start = get_pixel_ptr_8(dst, rc->left, rc->top);
1194         src_start = get_pixel_ptr_8(src, origin->x, origin->y);
1195         dst_stride = dst->stride;
1196         src_stride = src->stride;
1197     }
1198
1199     if (rop2 == R2_COPYPEN)
1200     {
1201         for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1202             memmove( dst_start, src_start, (rc->right - rc->left) );
1203         return;
1204     }
1205
1206     get_rop_codes( rop2, &codes );
1207     for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1208     {
1209         if (overlap & OVERLAP_RIGHT)
1210             do_rop_codes_line_rev_8( dst_start, src_start, &codes, rc->right - rc->left );
1211         else
1212             do_rop_codes_line_8( dst_start, src_start, &codes, rc->right - rc->left );
1213     }
1214 }
1215
1216 static void copy_rect_4(const dib_info *dst, const RECT *rc,
1217                         const dib_info *src, const POINT *origin, int rop2, int overlap)
1218 {
1219     BYTE *dst_start, *src_start;
1220     int y, dst_stride, src_stride;
1221     struct rop_codes codes;
1222     int left = dst->rect.left + rc->left;
1223     int right = dst->rect.left + rc->right;
1224     int org_x = src->rect.left + origin->x;
1225
1226     if (overlap & OVERLAP_BELOW)
1227     {
1228         dst_start = get_pixel_ptr_4(dst, rc->left, rc->bottom - 1);
1229         src_start = get_pixel_ptr_4(src, origin->x, origin->y + rc->bottom - rc->top - 1);
1230         dst_stride = -dst->stride;
1231         src_stride = -src->stride;
1232     }
1233     else
1234     {
1235         dst_start = get_pixel_ptr_4(dst, rc->left, rc->top);
1236         src_start = get_pixel_ptr_4(src, origin->x, origin->y);
1237         dst_stride = dst->stride;
1238         src_stride = src->stride;
1239     }
1240
1241     if (rop2 == R2_COPYPEN && (left & 1) == 0 && (org_x & 1) == 0 && (right & 1) == 0)
1242     {
1243         for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1244             memmove( dst_start, src_start, (right - left) / 2 );
1245         return;
1246     }
1247
1248     get_rop_codes( rop2, &codes );
1249     for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1250     {
1251         if (overlap & OVERLAP_RIGHT)
1252             do_rop_codes_line_rev_4( dst_start, left & 1, src_start, org_x & 1, &codes, right - left );
1253         else
1254             do_rop_codes_line_4( dst_start, left & 1, src_start, org_x & 1, &codes, right - left );
1255     }
1256 }
1257
1258 static void copy_rect_1(const dib_info *dst, const RECT *rc,
1259                         const dib_info *src, const POINT *origin, int rop2, int overlap)
1260 {
1261     BYTE *dst_start, *src_start;
1262     int y, dst_stride, src_stride;
1263     struct rop_codes codes;
1264     int left = dst->rect.left + rc->left;
1265     int right = dst->rect.left + rc->right;
1266     int org_x = src->rect.left + origin->x;
1267
1268     if (overlap & OVERLAP_BELOW)
1269     {
1270         dst_start = get_pixel_ptr_1(dst, rc->left, rc->bottom - 1);
1271         src_start = get_pixel_ptr_1(src, origin->x, origin->y + rc->bottom - rc->top - 1);
1272         dst_stride = -dst->stride;
1273         src_stride = -src->stride;
1274     }
1275     else
1276     {
1277         dst_start = get_pixel_ptr_1(dst, rc->left, rc->top);
1278         src_start = get_pixel_ptr_1(src, origin->x, origin->y);
1279         dst_stride = dst->stride;
1280         src_stride = src->stride;
1281     }
1282
1283     if (rop2 == R2_COPYPEN && (left & 7) == 0 && (org_x & 7) == 0 && (right & 7) == 0)
1284     {
1285         for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1286             memmove( dst_start, src_start, (right - left) / 8 );
1287         return;
1288     }
1289
1290     get_rop_codes( rop2, &codes );
1291     for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
1292     {
1293         if (overlap & OVERLAP_RIGHT)
1294             do_rop_codes_line_rev_1( dst_start, left & 7, src_start, org_x & 7, &codes, right - left );
1295         else
1296             do_rop_codes_line_1( dst_start, left & 7, src_start, org_x & 7, &codes, right - left );
1297     }
1298 }
1299
1300 static void copy_rect_null(const dib_info *dst, const RECT *rc,
1301                            const dib_info *src, const POINT *origin, int rop2, int overlap)
1302 {
1303     return;
1304 }
1305
1306 static DWORD get_pixel_32(const dib_info *dib, int x, int y)
1307 {
1308     DWORD *ptr = get_pixel_ptr_32( dib, x, y );
1309     return *ptr;
1310 }
1311
1312 static DWORD get_pixel_24(const dib_info *dib, int x, int y)
1313 {
1314     BYTE *ptr = get_pixel_ptr_24( dib, x, y );
1315     return ptr[0] | ((DWORD)ptr[1] << 8) | ((DWORD)ptr[2] << 16);
1316 }
1317
1318 static DWORD get_pixel_16(const dib_info *dib, int x, int y)
1319 {
1320     WORD *ptr = get_pixel_ptr_16( dib, x, y );
1321     return *ptr;
1322 }
1323
1324 static DWORD get_pixel_8(const dib_info *dib, int x, int y)
1325 {
1326     BYTE *ptr = get_pixel_ptr_8( dib, x, y );
1327     return *ptr;
1328 }
1329
1330 static DWORD get_pixel_4(const dib_info *dib, int x, int y)
1331 {
1332     BYTE *ptr = get_pixel_ptr_4( dib, x, y );
1333
1334     if ((dib->rect.left + x) & 1)
1335         return *ptr & 0x0f;
1336     else
1337         return (*ptr >> 4) & 0x0f;
1338 }
1339
1340 static DWORD get_pixel_1(const dib_info *dib, int x, int y)
1341 {
1342     BYTE *ptr = get_pixel_ptr_1( dib, x, y );
1343     return (*ptr & pixel_masks_1[(dib->rect.left + x) & 7]) ? 1 : 0;
1344 }
1345
1346 static DWORD get_pixel_null(const dib_info *dib, int x, int y)
1347 {
1348     return 0;
1349 }
1350
1351 static DWORD colorref_to_pixel_888(const dib_info *dib, COLORREF color)
1352 {
1353     return ( ((color >> 16) & 0xff) | (color & 0xff00) | ((color << 16) & 0xff0000) );
1354 }
1355
1356 static const DWORD field_masks[33] =
1357 {
1358     0x00,  /* should never happen */
1359     0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff,
1360     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1361     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1362     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1363 };
1364
1365 static inline DWORD get_field(DWORD field, int shift, int len)
1366 {
1367     shift = shift - (8 - len);
1368     if (shift < 0)
1369         field <<= -shift;
1370     else
1371         field >>= shift;
1372     field &= field_masks[len];
1373     field |= field >> len;
1374     return field;
1375 }
1376
1377 static inline DWORD put_field(DWORD field, int shift, int len)
1378 {
1379     shift = shift - (8 - len);
1380     field &= field_masks[len];
1381     if (shift < 0)
1382         field >>= -shift;
1383     else
1384         field <<= shift;
1385     return field;
1386 }
1387
1388 static DWORD colorref_to_pixel_masks(const dib_info *dib, COLORREF colour)
1389 {
1390     DWORD r,g,b;
1391
1392     r = GetRValue(colour);
1393     g = GetGValue(colour);
1394     b = GetBValue(colour);
1395
1396     return put_field(r, dib->red_shift,   dib->red_len) |
1397            put_field(g, dib->green_shift, dib->green_len) |
1398            put_field(b, dib->blue_shift,  dib->blue_len);
1399 }
1400
1401 static DWORD colorref_to_pixel_555(const dib_info *dib, COLORREF color)
1402 {
1403     return ( ((color >> 19) & 0x1f) | ((color >> 6) & 0x03e0) | ((color << 7) & 0x7c00) );
1404 }
1405
1406 static DWORD rgb_to_pixel_colortable(const dib_info *dib, BYTE r, BYTE g, BYTE b)
1407 {
1408     const RGBQUAD *color_table = get_dib_color_table( dib );
1409     int size = dib->color_table ? dib->color_table_size : 1 << dib->bit_count;
1410     int i, best_index = 0;
1411     DWORD diff, best_diff = 0xffffffff;
1412
1413     /* special case for conversion to 1-bpp without a color table:
1414      * we get a 1-entry table containing the background color
1415      */
1416     if (dib->bit_count == 1 && size == 1)
1417         return (r == color_table[0].rgbRed &&
1418                 g == color_table[0].rgbGreen &&
1419                 b == color_table[0].rgbBlue);
1420
1421     for(i = 0; i < size; i++)
1422     {
1423         const RGBQUAD *cur = color_table + i;
1424         diff = (r - cur->rgbRed)   * (r - cur->rgbRed)
1425             +  (g - cur->rgbGreen) * (g - cur->rgbGreen)
1426             +  (b - cur->rgbBlue)  * (b - cur->rgbBlue);
1427
1428         if(diff == 0)
1429         {
1430             best_index = i;
1431             break;
1432         }
1433
1434         if(diff < best_diff)
1435         {
1436             best_diff = diff;
1437             best_index = i;
1438         }
1439     }
1440     return best_index;
1441 }
1442
1443 static DWORD rgb_to_pixel_mono(const dib_info *dib, BOOL dither, int x, int y, BYTE r, BYTE g, BYTE b)
1444 {
1445     DWORD ret;
1446
1447     if (!dither)
1448         ret = rgb_to_pixel_colortable( dib, r, g, b );
1449     else
1450         ret = ((30 * r + 59 * g + 11 * b) / 100 + bayer_16x16[y % 16][x % 16]) > 255;
1451
1452     return ret ? 0xff : 0;
1453 }
1454
1455 static DWORD colorref_to_pixel_colortable(const dib_info *dib, COLORREF color)
1456 {
1457     return rgb_to_pixel_colortable( dib, GetRValue(color), GetGValue(color), GetBValue(color) );
1458 }
1459
1460 static DWORD colorref_to_pixel_null(const dib_info *dib, COLORREF color)
1461 {
1462     return 0;
1463 }
1464
1465 static COLORREF pixel_to_colorref_888(const dib_info *dib, DWORD pixel)
1466 {
1467     return ( ((pixel >> 16) & 0xff) | (pixel & 0xff00) | ((pixel << 16) & 0xff0000) );
1468 }
1469
1470 static COLORREF pixel_to_colorref_masks(const dib_info *dib, DWORD pixel)
1471 {
1472     return RGB( get_field( pixel, dib->red_shift,   dib->red_len ),
1473                 get_field( pixel, dib->green_shift, dib->green_len ),
1474                 get_field( pixel, dib->blue_shift,  dib->blue_len ) );
1475 }
1476
1477 static COLORREF pixel_to_colorref_555(const dib_info *dib, DWORD pixel)
1478 {
1479     return RGB( ((pixel >> 7) & 0xf8) | ((pixel >> 12) & 0x07),
1480                 ((pixel >> 2) & 0xf8) | ((pixel >>  7) & 0x07),
1481                 ((pixel << 3) & 0xf8) | ((pixel >>  2) & 0x07) );
1482 }
1483
1484 static COLORREF pixel_to_colorref_colortable(const dib_info *dib, DWORD pixel)
1485 {
1486     const RGBQUAD *color_table = get_dib_color_table( dib );
1487
1488     if (!dib->color_table || pixel < dib->color_table_size)
1489     {
1490         RGBQUAD quad = color_table[pixel];
1491         return RGB( quad.rgbRed, quad.rgbGreen, quad.rgbBlue );
1492     }
1493     return 0;
1494 }
1495
1496 static COLORREF pixel_to_colorref_null(const dib_info *dib, DWORD pixel)
1497 {
1498     return 0;
1499 }
1500
1501 static inline BOOL bit_fields_match(const dib_info *d1, const dib_info *d2)
1502 {
1503     assert( d1->bit_count > 8 && d1->bit_count == d2->bit_count );
1504
1505     return d1->red_mask   == d2->red_mask &&
1506            d1->green_mask == d2->green_mask &&
1507            d1->blue_mask  == d2->blue_mask;
1508 }
1509
1510 static void convert_to_8888(dib_info *dst, const dib_info *src, const RECT *src_rect, BOOL dither)
1511 {
1512     DWORD *dst_start = get_pixel_ptr_32(dst, 0, 0), *dst_pixel, src_val;
1513     int x, y, pad_size = (dst->width - (src_rect->right - src_rect->left)) * 4;
1514
1515     switch(src->bit_count)
1516     {
1517     case 32:
1518     {
1519         DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1520         if(src->funcs == &funcs_8888)
1521         {
1522             if (src->stride > 0 && src->stride == dst->stride && !pad_size)
1523                 memcpy(dst_start, src_start, (src_rect->bottom - src_rect->top) * src->stride);
1524             else
1525             {
1526                 for(y = src_rect->top; y < src_rect->bottom; y++)
1527                 {
1528                     memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 4);
1529                     if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
1530                     dst_start += dst->stride / 4;
1531                     src_start += src->stride / 4;
1532                 }
1533             }
1534         }
1535         else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
1536         {
1537             for(y = src_rect->top; y < src_rect->bottom; y++)
1538             {
1539                 dst_pixel = dst_start;
1540                 src_pixel = src_start;
1541                 for(x = src_rect->left; x < src_rect->right; x++)
1542                 {
1543                     src_val = *src_pixel++;
1544                     *dst_pixel++ = (((src_val >> src->red_shift)   & 0xff) << 16) |
1545                                    (((src_val >> src->green_shift) & 0xff) <<  8) |
1546                                     ((src_val >> src->blue_shift)  & 0xff);
1547                 }
1548                 if(pad_size) memset(dst_pixel, 0, pad_size);
1549                 dst_start += dst->stride / 4;
1550                 src_start += src->stride / 4;
1551             }
1552         }
1553         else
1554         {
1555             for(y = src_rect->top; y < src_rect->bottom; y++)
1556             {
1557                 dst_pixel = dst_start;
1558                 src_pixel = src_start;
1559                 for(x = src_rect->left; x < src_rect->right; x++)
1560                 {
1561                     src_val = *src_pixel++;
1562                     *dst_pixel++ = (get_field( src_val, src->red_shift, src->red_len ) << 16 |
1563                                     get_field( src_val, src->green_shift, src->green_len ) << 8 |
1564                                     get_field( src_val, src->blue_shift, src->blue_len ));
1565                 }
1566                 if(pad_size) memset(dst_pixel, 0, pad_size);
1567                 dst_start += dst->stride / 4;
1568                 src_start += src->stride / 4;
1569             }
1570         }
1571         break;
1572     }
1573
1574     case 24:
1575     {
1576         BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
1577
1578         for(y = src_rect->top; y < src_rect->bottom; y++)
1579         {
1580             dst_pixel = dst_start;
1581             src_pixel = src_start;
1582             for(x = src_rect->left; x < src_rect->right; x++)
1583             {
1584                 RGBQUAD rgb;
1585                 rgb.rgbBlue  = *src_pixel++;
1586                 rgb.rgbGreen = *src_pixel++;
1587                 rgb.rgbRed   = *src_pixel++;
1588
1589                 *dst_pixel++ = ((rgb.rgbRed << 16) & 0xff0000) | ((rgb.rgbGreen << 8) & 0x00ff00) | (rgb.rgbBlue & 0x0000ff);
1590             }
1591             if(pad_size) memset(dst_pixel, 0, pad_size);
1592             dst_start += dst->stride / 4;
1593             src_start += src->stride;
1594         }
1595         break;
1596     }
1597
1598     case 16:
1599     {
1600         WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
1601         if(src->funcs == &funcs_555)
1602         {
1603             for(y = src_rect->top; y < src_rect->bottom; y++)
1604             {
1605                 dst_pixel = dst_start;
1606                 src_pixel = src_start;
1607                 for(x = src_rect->left; x < src_rect->right; x++)
1608                 {
1609                     src_val = *src_pixel++;
1610                     *dst_pixel++ = ((src_val << 9) & 0xf80000) | ((src_val << 4) & 0x070000) |
1611                                    ((src_val << 6) & 0x00f800) | ((src_val << 1) & 0x000700) |
1612                                    ((src_val << 3) & 0x0000f8) | ((src_val >> 2) & 0x000007);
1613                 }
1614                 if(pad_size) memset(dst_pixel, 0, pad_size);
1615                 dst_start += dst->stride / 4;
1616                 src_start += src->stride / 2;
1617             }
1618         }
1619         else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
1620         {
1621             for(y = src_rect->top; y < src_rect->bottom; y++)
1622             {
1623                 dst_pixel = dst_start;
1624                 src_pixel = src_start;
1625                 for(x = src_rect->left; x < src_rect->right; x++)
1626                 {
1627                     src_val = *src_pixel++;
1628                     *dst_pixel++ = (((src_val >> src->red_shift)   << 19) & 0xf80000) |
1629                                    (((src_val >> src->red_shift)   << 14) & 0x070000) |
1630                                    (((src_val >> src->green_shift) << 11) & 0x00f800) |
1631                                    (((src_val >> src->green_shift) <<  6) & 0x000700) |
1632                                    (((src_val >> src->blue_shift)  <<  3) & 0x0000f8) |
1633                                    (((src_val >> src->blue_shift)  >>  2) & 0x000007);
1634                 }
1635                 if(pad_size) memset(dst_pixel, 0, pad_size);
1636                 dst_start += dst->stride / 4;
1637                 src_start += src->stride / 2;
1638             }
1639         }
1640         else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
1641         {
1642             for(y = src_rect->top; y < src_rect->bottom; y++)
1643             {
1644                 dst_pixel = dst_start;
1645                 src_pixel = src_start;
1646                 for(x = src_rect->left; x < src_rect->right; x++)
1647                 {
1648                     src_val = *src_pixel++;
1649                     *dst_pixel++ = (((src_val >> src->red_shift)   << 19) & 0xf80000) |
1650                                    (((src_val >> src->red_shift)   << 14) & 0x070000) |
1651                                    (((src_val >> src->green_shift) << 10) & 0x00fc00) |
1652                                    (((src_val >> src->green_shift) <<  4) & 0x000300) |
1653                                    (((src_val >> src->blue_shift)  <<  3) & 0x0000f8) |
1654                                    (((src_val >> src->blue_shift)  >>  2) & 0x000007);
1655                 }
1656                 if(pad_size) memset(dst_pixel, 0, pad_size);
1657                 dst_start += dst->stride / 4;
1658                 src_start += src->stride / 2;
1659             }
1660         }
1661         else
1662         {
1663             for(y = src_rect->top; y < src_rect->bottom; y++)
1664             {
1665                 dst_pixel = dst_start;
1666                 src_pixel = src_start;
1667                 for(x = src_rect->left; x < src_rect->right; x++)
1668                 {
1669                     src_val = *src_pixel++;
1670                     *dst_pixel++ = (get_field( src_val, src->red_shift, src->red_len ) << 16 |
1671                                     get_field( src_val, src->green_shift, src->green_len ) << 8 |
1672                                     get_field( src_val, src->blue_shift, src->blue_len ));
1673                 }
1674                 if(pad_size) memset(dst_pixel, 0, pad_size);
1675                 dst_start += dst->stride / 4;
1676                 src_start += src->stride / 2;
1677             }
1678         }
1679         break;
1680     }
1681
1682     case 8:
1683     {
1684         const RGBQUAD *color_table = get_dib_color_table( src );
1685         BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
1686         for(y = src_rect->top; y < src_rect->bottom; y++)
1687         {
1688             dst_pixel = dst_start;
1689             src_pixel = src_start;
1690             for(x = src_rect->left; x < src_rect->right; x++)
1691             {
1692                 RGBQUAD rgb = color_table[*src_pixel++];
1693                 *dst_pixel++ = rgb.rgbRed << 16 | rgb.rgbGreen << 8 | rgb.rgbBlue;
1694             }
1695             if(pad_size) memset(dst_pixel, 0, pad_size);
1696             dst_start += dst->stride / 4;
1697             src_start += src->stride;
1698         }
1699         break;
1700     }
1701
1702     case 4:
1703     {
1704         const RGBQUAD *color_table = get_dib_color_table( src );
1705         BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
1706         for(y = src_rect->top; y < src_rect->bottom; y++)
1707         {
1708             int pos = (src->rect.left + src_rect->left) & 1;
1709             src_pixel = src_start;
1710             for (x = 0; x < src_rect->right - src_rect->left; x++, pos++)
1711             {
1712                 RGBQUAD rgb;
1713                 if (pos & 1)
1714                     rgb = color_table[*src_pixel++ & 0xf];
1715                 else
1716                     rgb = color_table[*src_pixel >> 4];
1717                 dst_start[x] = rgb.rgbRed << 16 | rgb.rgbGreen << 8 | rgb.rgbBlue;
1718             }
1719             if(pad_size) memset(dst_start + x, 0, pad_size);
1720             dst_start += dst->stride / 4;
1721             src_start += src->stride;
1722         }
1723         break;
1724     }
1725
1726     case 1:
1727     {
1728         const RGBQUAD *color_table = get_dib_color_table( src );
1729         BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top);
1730         for(y = src_rect->top; y < src_rect->bottom; y++)
1731         {
1732             int pos = (src->rect.left + src_rect->left) & 7;
1733             for(x = 0; x < src_rect->right - src_rect->left; x++, pos++)
1734             {
1735                 RGBQUAD rgb;
1736                 src_val = (src_start[pos / 8] & pixel_masks_1[pos % 8]) ? 1 : 0;
1737                 rgb = color_table[src_val];
1738                 dst_start[x] = rgb.rgbRed << 16 | rgb.rgbGreen << 8 | rgb.rgbBlue;
1739             }
1740             if(pad_size) memset(dst_start + x, 0, pad_size);
1741             dst_start += dst->stride / 4;
1742             src_start += src->stride;
1743         }
1744         break;
1745     }
1746     }
1747 }
1748
1749 static void convert_to_32(dib_info *dst, const dib_info *src, const RECT *src_rect, BOOL dither)
1750 {
1751     DWORD *dst_start = get_pixel_ptr_32(dst, 0, 0), *dst_pixel, src_val;
1752     int x, y, pad_size = (dst->width - (src_rect->right - src_rect->left)) * 4;
1753
1754     switch(src->bit_count)
1755     {
1756     case 32:
1757     {
1758         DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
1759
1760         if(src->funcs == &funcs_8888)
1761         {
1762             for(y = src_rect->top; y < src_rect->bottom; y++)
1763             {
1764                 dst_pixel = dst_start;
1765                 src_pixel = src_start;
1766                 for(x = src_rect->left; x < src_rect->right; x++)
1767                 {
1768                     src_val = *src_pixel++;
1769                     *dst_pixel++ = put_field(src_val >> 16, dst->red_shift,   dst->red_len)   |
1770                                    put_field(src_val >>  8, dst->green_shift, dst->green_len) |
1771                                    put_field(src_val,       dst->blue_shift,  dst->blue_len);
1772                 }
1773                 if(pad_size) memset(dst_pixel, 0, pad_size);
1774                 dst_start += dst->stride / 4;
1775                 src_start += src->stride / 4;
1776             }
1777         }
1778         else if(bit_fields_match(src, dst))
1779         {
1780             if (src->stride > 0 && src->stride == dst->stride && !pad_size)
1781                 memcpy(dst_start, src_start, (src_rect->bottom - src_rect->top) * src->stride);
1782             else
1783             {
1784                 for(y = src_rect->top; y < src_rect->bottom; y++)
1785                 {
1786                     memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 4);
1787                     if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
1788                     dst_start += dst->stride / 4;
1789                     src_start += src->stride / 4;
1790                 }
1791             }
1792         }
1793         else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8 &&
1794                 dst->red_len == 8 && dst->green_len == 8 && dst->blue_len == 8)
1795         {
1796             for(y = src_rect->top; y < src_rect->bottom; y++)
1797             {
1798                 dst_pixel = dst_start;
1799                 src_pixel = src_start;
1800                 for(x = src_rect->left; x < src_rect->right; x++)
1801                 {
1802                     src_val = *src_pixel++;
1803                     *dst_pixel++ = (((src_val >> src->red_shift)   & 0xff) << dst->red_shift)   |
1804                                    (((src_val >> src->green_shift) & 0xff) << dst->green_shift) |
1805                                    (((src_val >> src->blue_shift)  & 0xff) << dst->blue_shift);
1806                 }
1807                 if(pad_size) memset(dst_pixel, 0, pad_size);
1808                 dst_start += dst->stride / 4;
1809                 src_start += src->stride / 4;
1810             }
1811         }
1812         else
1813         {
1814             for(y = src_rect->top; y < src_rect->bottom; y++)
1815             {
1816                 dst_pixel = dst_start;
1817                 src_pixel = src_start;
1818                 for(x = src_rect->left; x < src_rect->right; x++)
1819                 {
1820                     src_val = *src_pixel++;
1821                     *dst_pixel++ = put_field(get_field(src_val, src->red_shift,   src->red_len ),   dst->red_shift,   dst->red_len)   |
1822                                    put_field(get_field(src_val, src->green_shift, src->green_len ), dst->green_shift, dst->green_len) |
1823                                    put_field(get_field(src_val, src->blue_shift,  src->blue_len ),  dst->blue_shift,  dst->blue_len);
1824                 }
1825                 if(pad_size) memset(dst_pixel, 0, pad_size);
1826                 dst_start += dst->stride / 4;
1827                 src_start += src->stride / 4;
1828             }
1829         }
1830         break;
1831     }
1832
1833     case 24:
1834     {
1835         BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
1836
1837         for(y = src_rect->top; y < src_rect->bottom; y++)
1838         {
1839             dst_pixel = dst_start;
1840             src_pixel = src_start;
1841             for(x = src_rect->left; x < src_rect->right; x++)
1842             {
1843                 RGBQUAD rgb;
1844                 rgb.rgbBlue  = *src_pixel++;
1845                 rgb.rgbGreen = *src_pixel++;
1846                 rgb.rgbRed   = *src_pixel++;
1847
1848                 *dst_pixel++ = put_field(rgb.rgbRed,   dst->red_shift,   dst->red_len)   |
1849                                put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1850                                put_field(rgb.rgbBlue,  dst->blue_shift,  dst->blue_len);
1851             }
1852             if(pad_size) memset(dst_pixel, 0, pad_size);
1853             dst_start += dst->stride / 4;
1854             src_start += src->stride;
1855         }
1856         break;
1857     }
1858
1859     case 16:
1860     {
1861         WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
1862         if(src->funcs == &funcs_555)
1863         {
1864             for(y = src_rect->top; y < src_rect->bottom; y++)
1865             {
1866                 dst_pixel = dst_start;
1867                 src_pixel = src_start;
1868                 for(x = src_rect->left; x < src_rect->right; x++)
1869                 {
1870                     src_val = *src_pixel++;
1871                     *dst_pixel++ = put_field(((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07), dst->red_shift,   dst->red_len) |
1872                                    put_field(((src_val >> 2) & 0xf8) | ((src_val >>  7) & 0x07), dst->green_shift, dst->green_len) |
1873                                    put_field(((src_val << 3) & 0xf8) | ((src_val >>  2) & 0x07), dst->blue_shift,  dst->blue_len);
1874                 }
1875                 if(pad_size) memset(dst_pixel, 0, pad_size);
1876                 dst_start += dst->stride / 4;
1877                 src_start += src->stride / 2;
1878             }
1879         }
1880         else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
1881         {
1882             for(y = src_rect->top; y < src_rect->bottom; y++)
1883             {
1884                 dst_pixel = dst_start;
1885                 src_pixel = src_start;
1886                 for(x = src_rect->left; x < src_rect->right; x++)
1887                 {
1888                     src_val = *src_pixel++;
1889                     *dst_pixel++ = put_field( (((src_val >> src->red_shift)   << 3) & 0xf8) |
1890                                               (((src_val >> src->red_shift)   >> 2) & 0x07), dst->red_shift, dst->red_len ) |
1891                                    put_field( (((src_val >> src->green_shift) << 3) & 0xf8) |
1892                                               (((src_val >> src->green_shift) >> 2) & 0x07), dst->green_shift, dst->green_len ) |
1893                                    put_field( (((src_val >> src->blue_shift)  << 3) & 0xf8) |
1894                                               (((src_val >> src->blue_shift)  >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1895                 }
1896                 if(pad_size) memset(dst_pixel, 0, pad_size);
1897                 dst_start += dst->stride / 4;
1898                 src_start += src->stride / 2;
1899             }
1900         }
1901         else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
1902         {
1903             for(y = src_rect->top; y < src_rect->bottom; y++)
1904             {
1905                 dst_pixel = dst_start;
1906                 src_pixel = src_start;
1907                 for(x = src_rect->left; x < src_rect->right; x++)
1908                 {
1909                     src_val = *src_pixel++;
1910                     *dst_pixel++ = put_field( (((src_val >> src->red_shift)   << 3) & 0xf8) |
1911                                               (((src_val >> src->red_shift)   >> 2) & 0x07), dst->red_shift, dst->red_len ) |
1912                                    put_field( (((src_val >> src->green_shift) << 2) & 0xfc) |
1913                                               (((src_val >> src->green_shift) >> 4) & 0x03), dst->green_shift, dst->green_len ) |
1914                                    put_field( (((src_val >> src->blue_shift)  << 3) & 0xf8) |
1915                                               (((src_val >> src->blue_shift)  >> 2) & 0x07), dst->blue_shift, dst->blue_len);
1916                 }
1917                 if(pad_size) memset(dst_pixel, 0, pad_size);
1918                 dst_start += dst->stride / 4;
1919                 src_start += src->stride / 2;
1920             }
1921         }
1922         else
1923         {
1924             for(y = src_rect->top; y < src_rect->bottom; y++)
1925             {
1926                 dst_pixel = dst_start;
1927                 src_pixel = src_start;
1928                 for(x = src_rect->left; x < src_rect->right; x++)
1929                 {
1930                     src_val = *src_pixel++;
1931                     *dst_pixel++ = put_field(get_field(src_val, src->red_shift,   src->red_len ),   dst->red_shift,   dst->red_len)   |
1932                                    put_field(get_field(src_val, src->green_shift, src->green_len ), dst->green_shift, dst->green_len) |
1933                                    put_field(get_field(src_val, src->blue_shift,  src->blue_len ),  dst->blue_shift,  dst->blue_len);
1934                 }
1935                 if(pad_size) memset(dst_pixel, 0, pad_size);
1936                 dst_start += dst->stride / 4;
1937                 src_start += src->stride / 2;
1938             }
1939         }
1940         break;
1941     }
1942
1943     case 8:
1944     {
1945         const RGBQUAD *color_table = get_dib_color_table( src );
1946         BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
1947         for(y = src_rect->top; y < src_rect->bottom; y++)
1948         {
1949             dst_pixel = dst_start;
1950             src_pixel = src_start;
1951             for(x = src_rect->left; x < src_rect->right; x++)
1952             {
1953                 RGBQUAD rgb = color_table[*src_pixel++];
1954                 *dst_pixel++ = put_field(rgb.rgbRed,   dst->red_shift,   dst->red_len) |
1955                                put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1956                                put_field(rgb.rgbBlue,  dst->blue_shift,  dst->blue_len);
1957             }
1958             if(pad_size) memset(dst_pixel, 0, pad_size);
1959             dst_start += dst->stride / 4;
1960             src_start += src->stride;
1961         }
1962         break;
1963     }
1964
1965     case 4:
1966     {
1967         const RGBQUAD *color_table = get_dib_color_table( src );
1968         BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
1969         for(y = src_rect->top; y < src_rect->bottom; y++)
1970         {
1971             int pos = (src->rect.left + src_rect->left) & 1;
1972             src_pixel = src_start;
1973             for (x = 0; x < src_rect->right - src_rect->left; x++, pos++)
1974             {
1975                 RGBQUAD rgb;
1976                 if (pos & 1)
1977                     rgb = color_table[*src_pixel++ & 0xf];
1978                 else
1979                     rgb = color_table[*src_pixel >> 4];
1980                 dst_start[x] = put_field(rgb.rgbRed,   dst->red_shift,   dst->red_len) |
1981                                put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
1982                                put_field(rgb.rgbBlue,  dst->blue_shift,  dst->blue_len);
1983             }
1984             if(pad_size) memset(dst_start + x, 0, pad_size);
1985             dst_start += dst->stride / 4;
1986             src_start += src->stride;
1987         }
1988         break;
1989     }
1990
1991     case 1:
1992     {
1993         const RGBQUAD *color_table = get_dib_color_table( src );
1994         BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top);
1995         for(y = src_rect->top; y < src_rect->bottom; y++)
1996         {
1997             int pos = (src->rect.left + src_rect->left) & 7;
1998             for (x = 0; x < src_rect->right - src_rect->left; x++, pos++)
1999             {
2000                 RGBQUAD rgb;
2001                 src_val = (src_start[pos / 8] & pixel_masks_1[pos % 8]) ? 1 : 0;
2002                 rgb = color_table[src_val];
2003                 dst_start[x] = put_field(rgb.rgbRed,   dst->red_shift,   dst->red_len) |
2004                                put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
2005                                put_field(rgb.rgbBlue,  dst->blue_shift,  dst->blue_len);
2006             }
2007             if(pad_size) memset(dst_start + x, 0, pad_size);
2008             dst_start += dst->stride / 4;
2009             src_start += src->stride;
2010         }
2011         break;
2012     }
2013     }
2014 }
2015
2016 static void convert_to_24(dib_info *dst, const dib_info *src, const RECT *src_rect, BOOL dither)
2017 {
2018     BYTE *dst_start = get_pixel_ptr_24(dst, 0, 0), *dst_pixel;
2019     DWORD src_val;
2020     int x, y, pad_size = ((dst->width * 3 + 3) & ~3) - (src_rect->right - src_rect->left) * 3;
2021
2022     switch(src->bit_count)
2023     {
2024     case 32:
2025     {
2026         DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
2027         if(src->funcs == &funcs_8888)
2028         {
2029             for(y = src_rect->top; y < src_rect->bottom; y++)
2030             {
2031                 dst_pixel = dst_start;
2032                 src_pixel = src_start;
2033                 for(x = src_rect->left; x < src_rect->right; x++)
2034                 {
2035                     src_val = *src_pixel++;
2036                     *dst_pixel++ =  src_val        & 0xff;
2037                     *dst_pixel++ = (src_val >>  8) & 0xff;
2038                     *dst_pixel++ = (src_val >> 16) & 0xff;
2039                 }
2040                 if(pad_size) memset(dst_pixel, 0, pad_size);
2041                 dst_start += dst->stride;
2042                 src_start += src->stride / 4;
2043             }
2044         }
2045         else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
2046         {
2047             for(y = src_rect->top; y < src_rect->bottom; y++)
2048             {
2049                 dst_pixel = dst_start;
2050                 src_pixel = src_start;
2051                 for(x = src_rect->left; x < src_rect->right; x++)
2052                 {
2053                     src_val = *src_pixel++;
2054                     *dst_pixel++ = (src_val >> src->blue_shift)  & 0xff;
2055                     *dst_pixel++ = (src_val >> src->green_shift) & 0xff;
2056                     *dst_pixel++ = (src_val >> src->red_shift)   & 0xff;
2057                 }
2058                 if(pad_size) memset(dst_pixel, 0, pad_size);
2059                 dst_start += dst->stride;
2060                 src_start += src->stride / 4;
2061             }
2062         }
2063         else
2064         {
2065             for(y = src_rect->top; y < src_rect->bottom; y++)
2066             {
2067                 dst_pixel = dst_start;
2068                 src_pixel = src_start;
2069                 for(x = src_rect->left; x < src_rect->right; x++)
2070                 {
2071                     src_val = *src_pixel++;
2072                     *dst_pixel++ = get_field( src_val, src->blue_shift, src->blue_len );
2073                     *dst_pixel++ = get_field( src_val, src->green_shift, src->green_len );
2074                     *dst_pixel++ = get_field( src_val, src->red_shift, src->red_len );
2075                 }
2076                 if(pad_size) memset(dst_pixel, 0, pad_size);
2077                 dst_start += dst->stride;
2078                 src_start += src->stride / 4;
2079             }
2080         }
2081         break;
2082     }
2083
2084     case 24:
2085     {
2086         BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top);
2087
2088         if (src->stride > 0 && src->stride == dst->stride && !pad_size)
2089             memcpy(dst_start, src_start, (src_rect->bottom - src_rect->top) * src->stride);
2090         else
2091         {
2092             for(y = src_rect->top; y < src_rect->bottom; y++)
2093             {
2094                 memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 3);
2095                 if(pad_size) memset(dst_start + (src_rect->right - src_rect->left) * 3, 0, pad_size);
2096                 dst_start += dst->stride;
2097                 src_start += src->stride;
2098             }
2099         }
2100         break;
2101     }
2102
2103     case 16:
2104     {
2105         WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2106         if(src->funcs == &funcs_555)
2107         {
2108             for(y = src_rect->top; y < src_rect->bottom; y++)
2109             {
2110                 dst_pixel = dst_start;
2111                 src_pixel = src_start;
2112                 for(x = src_rect->left; x < src_rect->right; x++)
2113                 {
2114                     src_val = *src_pixel++;
2115                     *dst_pixel++ = ((src_val << 3) & 0xf8) | ((src_val >>  2) & 0x07);
2116                     *dst_pixel++ = ((src_val >> 2) & 0xf8) | ((src_val >>  7) & 0x07);
2117                     *dst_pixel++ = ((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07);
2118                 }
2119                 if(pad_size) memset(dst_pixel, 0, pad_size);
2120                 dst_start += dst->stride;
2121                 src_start += src->stride / 2;
2122             }
2123         }
2124         else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2125         {
2126             for(y = src_rect->top; y < src_rect->bottom; y++)
2127             {
2128                 dst_pixel = dst_start;
2129                 src_pixel = src_start;
2130                 for(x = src_rect->left; x < src_rect->right; x++)
2131                 {
2132                     src_val = *src_pixel++;
2133                     *dst_pixel++ = (((src_val >> src->blue_shift)  << 3) & 0xf8) |
2134                                    (((src_val >> src->blue_shift)  >> 2) & 0x07);
2135                     *dst_pixel++ = (((src_val >> src->green_shift) << 3) & 0xf8) |
2136                                    (((src_val >> src->green_shift) >> 2) & 0x07);
2137                     *dst_pixel++ = (((src_val >> src->red_shift)   << 3) & 0xf8) |
2138                                    (((src_val >> src->red_shift)   >> 2) & 0x07);
2139                 }
2140                 if(pad_size) memset(dst_pixel, 0, pad_size);
2141                 dst_start += dst->stride;
2142                 src_start += src->stride / 2;
2143             }
2144         }
2145         else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2146         {
2147             for(y = src_rect->top; y < src_rect->bottom; y++)
2148             {
2149                 dst_pixel = dst_start;
2150                 src_pixel = src_start;
2151                 for(x = src_rect->left; x < src_rect->right; x++)
2152                 {
2153                     src_val = *src_pixel++;
2154                     *dst_pixel++ = (((src_val >> src->blue_shift)  << 3) & 0xf8) |
2155                                    (((src_val >> src->blue_shift)  >> 2) & 0x07);
2156                     *dst_pixel++ = (((src_val >> src->green_shift) << 2) & 0xfc) |
2157                                    (((src_val >> src->green_shift) >> 4) & 0x03);
2158                     *dst_pixel++ = (((src_val >> src->red_shift)   << 3) & 0xf8) |
2159                                    (((src_val >> src->red_shift)   >> 2) & 0x07);
2160                 }
2161                 if(pad_size) memset(dst_pixel, 0, pad_size);
2162                 dst_start += dst->stride;
2163                 src_start += src->stride / 2;
2164             }
2165         }
2166         else
2167         {
2168             for(y = src_rect->top; y < src_rect->bottom; y++)
2169             {
2170                 dst_pixel = dst_start;
2171                 src_pixel = src_start;
2172                 for(x = src_rect->left; x < src_rect->right; x++)
2173                 {
2174                     src_val = *src_pixel++;
2175                     *dst_pixel++ = get_field(src_val, src->blue_shift,  src->blue_len );
2176                     *dst_pixel++ = get_field(src_val, src->green_shift, src->green_len );
2177                     *dst_pixel++ = get_field(src_val, src->red_shift,   src->red_len );
2178                 }
2179                 if(pad_size) memset(dst_pixel, 0, pad_size);
2180                 dst_start += dst->stride;
2181                 src_start += src->stride / 2;
2182             }
2183         }
2184         break;
2185     }
2186
2187     case 8:
2188     {
2189         const RGBQUAD *color_table = get_dib_color_table( src );
2190         BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
2191         for(y = src_rect->top; y < src_rect->bottom; y++)
2192         {
2193             dst_pixel = dst_start;
2194             src_pixel = src_start;
2195             for(x = src_rect->left; x < src_rect->right; x++)
2196             {
2197                 RGBQUAD rgb = color_table[*src_pixel++];
2198                 *dst_pixel++ = rgb.rgbBlue;
2199                 *dst_pixel++ = rgb.rgbGreen;
2200                 *dst_pixel++ = rgb.rgbRed;
2201             }
2202             if(pad_size) memset(dst_pixel, 0, pad_size);
2203             dst_start += dst->stride;
2204             src_start += src->stride;
2205         }
2206         break;
2207     }
2208
2209     case 4:
2210     {
2211         const RGBQUAD *color_table = get_dib_color_table( src );
2212         BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
2213         for(y = src_rect->top; y < src_rect->bottom; y++)
2214         {
2215             int pos = (src->rect.left + src_rect->left) & 1;
2216             src_pixel = src_start;
2217             for (x = 0; x < src_rect->right - src_rect->left; x++, pos++)
2218             {
2219                 RGBQUAD rgb;
2220                 if (pos & 1)
2221                     rgb = color_table[*src_pixel++ & 0xf];
2222                 else
2223                     rgb = color_table[*src_pixel >> 4];
2224                 dst_start[x * 3] = rgb.rgbBlue;
2225                 dst_start[x * 3 + 1] = rgb.rgbGreen;
2226                 dst_start[x * 3 + 2] = rgb.rgbRed;
2227             }
2228             if(pad_size) memset(dst_start + x * 3, 0, pad_size);
2229             dst_start += dst->stride;
2230             src_start += src->stride;
2231         }
2232         break;
2233     }
2234
2235     case 1:
2236     {
2237         const RGBQUAD *color_table = get_dib_color_table( src );
2238         BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top);
2239         for(y = src_rect->top; y < src_rect->bottom; y++)
2240         {
2241             int pos = (src->rect.left + src_rect->left) & 7;
2242             for (x = 0; x < src_rect->right - src_rect->left; x++, pos++)
2243             {
2244                 RGBQUAD rgb;
2245                 src_val = (src_start[pos / 8] & pixel_masks_1[pos % 8]) ? 1 : 0;
2246                 rgb = color_table[src_val];
2247                 dst_start[x * 3] = rgb.rgbBlue;
2248                 dst_start[x * 3 + 1] = rgb.rgbGreen;
2249                 dst_start[x * 3 + 2] = rgb.rgbRed;
2250             }
2251             if(pad_size) memset(dst_start + x * 3, 0, pad_size);
2252             dst_start += dst->stride;
2253             src_start += src->stride;
2254         }
2255         break;
2256     }
2257     }
2258 }
2259
2260 static void convert_to_555(dib_info *dst, const dib_info *src, const RECT *src_rect, BOOL dither)
2261 {
2262     WORD *dst_start = get_pixel_ptr_16(dst, 0, 0), *dst_pixel;
2263     INT x, y, pad_size = ((dst->width + 1) & ~1) * 2 - (src_rect->right - src_rect->left) * 2;
2264     DWORD src_val;
2265
2266     switch(src->bit_count)
2267     {
2268     case 32:
2269     {
2270         DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
2271
2272         if(src->funcs == &funcs_8888)
2273         {
2274             for(y = src_rect->top; y < src_rect->bottom; y++)
2275             {
2276                 dst_pixel = dst_start;
2277                 src_pixel = src_start;
2278                 for(x = src_rect->left; x < src_rect->right; x++)
2279                 {
2280                     src_val = *src_pixel++;
2281                     *dst_pixel++ = ((src_val >> 9) & 0x7c00) |
2282                                    ((src_val >> 6) & 0x03e0) |
2283                                    ((src_val >> 3) & 0x001f);
2284                 }
2285                 if(pad_size) memset(dst_pixel, 0, pad_size);
2286                 dst_start += dst->stride / 2;
2287                 src_start += src->stride / 4;
2288             }
2289         }
2290         else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
2291         {
2292             for(y = src_rect->top; y < src_rect->bottom; y++)
2293             {
2294                 dst_pixel = dst_start;
2295                 src_pixel = src_start;
2296                 for(x = src_rect->left; x < src_rect->right; x++)
2297                 {
2298                     src_val = *src_pixel++;
2299                     *dst_pixel++ = (((src_val >> src->red_shift)   << 7) & 0x7c00) |
2300                                    (((src_val >> src->green_shift) << 2) & 0x03e0) |
2301                                    (((src_val >> src->blue_shift)  >> 3) & 0x001f);
2302                 }
2303                 if(pad_size) memset(dst_pixel, 0, pad_size);
2304                 dst_start += dst->stride / 2;
2305                 src_start += src->stride / 4;
2306             }
2307         }
2308         else
2309         {
2310             for(y = src_rect->top; y < src_rect->bottom; y++)
2311             {
2312                 dst_pixel = dst_start;
2313                 src_pixel = src_start;
2314                 for(x = src_rect->left; x < src_rect->right; x++)
2315                 {
2316                     src_val = *src_pixel++;
2317                     *dst_pixel++ = (((get_field(src_val, src->red_shift,   src->red_len )   << 7) & 0x7c00) |
2318                                     ((get_field(src_val, src->green_shift, src->green_len ) << 2) & 0x03e0) |
2319                                     ( get_field(src_val, src->blue_shift,  src->blue_len )  >> 3));
2320                 }
2321                 if(pad_size) memset(dst_pixel, 0, pad_size);
2322                 dst_start += dst->stride / 2;
2323                 src_start += src->stride / 4;
2324             }
2325         }
2326         break;
2327     }
2328
2329     case 24:
2330     {
2331         BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
2332
2333         for(y = src_rect->top; y < src_rect->bottom; y++)
2334         {
2335             dst_pixel = dst_start;
2336             src_pixel = src_start;
2337             for(x = src_rect->left; x < src_rect->right; x++)
2338             {
2339                 RGBQUAD rgb;
2340                 rgb.rgbBlue  = *src_pixel++;
2341                 rgb.rgbGreen = *src_pixel++;
2342                 rgb.rgbRed   = *src_pixel++;
2343
2344                 *dst_pixel++ = ((rgb.rgbRed   << 7) & 0x7c00) |
2345                                ((rgb.rgbGreen << 2) & 0x03e0) |
2346                                ((rgb.rgbBlue  >> 3) & 0x001f);
2347             }
2348             if(pad_size) memset(dst_pixel, 0, pad_size);
2349             dst_start += dst->stride / 2;
2350             src_start += src->stride;
2351         }
2352         break;
2353     }
2354
2355     case 16:
2356     {
2357         WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2358         if(src->funcs == &funcs_555)
2359         {
2360             if (src->stride > 0 && src->stride == dst->stride && !pad_size)
2361                 memcpy(dst_start, src_start, (src_rect->bottom - src_rect->top) * src->stride);
2362             else
2363             {
2364                 for(y = src_rect->top; y < src_rect->bottom; y++)
2365                 {
2366                     memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 2);
2367                     if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
2368                     dst_start += dst->stride / 2;
2369                     src_start += src->stride / 2;
2370                 }
2371             }
2372         }
2373         else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2374         {
2375             for(y = src_rect->top; y < src_rect->bottom; y++)
2376             {
2377                 dst_pixel = dst_start;
2378                 src_pixel = src_start;
2379                 for(x = src_rect->left; x < src_rect->right; x++)
2380                 {
2381                     src_val = *src_pixel++;
2382                     *dst_pixel++ = (((src_val >> src->red_shift)   << 10) & 0x7c00) |
2383                                    (((src_val >> src->green_shift) <<  5) & 0x03e0) |
2384                                    ( (src_val >> src->blue_shift)         & 0x001f);
2385                 }
2386                 if(pad_size) memset(dst_pixel, 0, pad_size);
2387                 dst_start += dst->stride / 2;
2388                 src_start += src->stride / 2;
2389             }
2390         }
2391         else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2392         {
2393             for(y = src_rect->top; y < src_rect->bottom; y++)
2394             {
2395                 dst_pixel = dst_start;
2396                 src_pixel = src_start;
2397                 for(x = src_rect->left; x < src_rect->right; x++)
2398                 {
2399                     src_val = *src_pixel++;
2400                     *dst_pixel++ = (((src_val >> src->red_shift)   << 10) & 0x7c00) |
2401                                    (((src_val >> src->green_shift) <<  4) & 0x03e0) |
2402                                    ( (src_val >> src->blue_shift)         & 0x001f);
2403                 }
2404                 if(pad_size) memset(dst_pixel, 0, pad_size);
2405                 dst_start += dst->stride / 2;
2406                 src_start += src->stride / 2;
2407             }
2408         }
2409         else
2410         {
2411             for(y = src_rect->top; y < src_rect->bottom; y++)
2412             {
2413                 dst_pixel = dst_start;
2414                 src_pixel = src_start;
2415                 for(x = src_rect->left; x < src_rect->right; x++)
2416                 {
2417                     src_val = *src_pixel++;
2418                     *dst_pixel++ = (((get_field(src_val, src->red_shift, src->red_len)     << 7) & 0x7c00) |
2419                                     ((get_field(src_val, src->green_shift, src->green_len) << 2) & 0x03e0) |
2420                                     ( get_field(src_val, src->blue_shift, src->blue_len)   >> 3));
2421                 }
2422                 if(pad_size) memset(dst_pixel, 0, pad_size);
2423                 dst_start += dst->stride / 2;
2424                 src_start += src->stride / 2;
2425             }
2426         }
2427         break;
2428     }
2429
2430     case 8:
2431     {
2432         const RGBQUAD *color_table = get_dib_color_table( src );
2433         BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
2434         for(y = src_rect->top; y < src_rect->bottom; y++)
2435         {
2436             dst_pixel = dst_start;
2437             src_pixel = src_start;
2438             for(x = src_rect->left; x < src_rect->right; x++)
2439             {
2440                 RGBQUAD rgb = color_table[*src_pixel++];
2441                 *dst_pixel++ = ((rgb.rgbRed   << 7) & 0x7c00) |
2442                                ((rgb.rgbGreen << 2) & 0x03e0) |
2443                                ((rgb.rgbBlue  >> 3) & 0x001f);
2444             }
2445             if(pad_size) memset(dst_pixel, 0, pad_size);
2446             dst_start += dst->stride / 2;
2447             src_start += src->stride;
2448         }
2449         break;
2450     }
2451
2452     case 4:
2453     {
2454         const RGBQUAD *color_table = get_dib_color_table( src );
2455         BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
2456         for(y = src_rect->top; y < src_rect->bottom; y++)
2457         {
2458             int pos = (src->rect.left + src_rect->left) & 1;
2459             src_pixel = src_start;
2460             for (x = 0; x < src_rect->right - src_rect->left; x++, pos++)
2461             {
2462                 RGBQUAD rgb;
2463                 if (pos & 1)
2464                     rgb = color_table[*src_pixel++ & 0xf];
2465                 else
2466                     rgb = color_table[*src_pixel >> 4];
2467                 dst_start[x] = ((rgb.rgbRed   << 7) & 0x7c00) |
2468                                ((rgb.rgbGreen << 2) & 0x03e0) |
2469                                ((rgb.rgbBlue  >> 3) & 0x001f);
2470             }
2471             if(pad_size) memset(dst_start + x, 0, pad_size);
2472             dst_start += dst->stride / 2;
2473             src_start += src->stride;
2474         }
2475         break;
2476     }
2477
2478     case 1:
2479     {
2480         const RGBQUAD *color_table = get_dib_color_table( src );
2481         BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top);
2482         for(y = src_rect->top; y < src_rect->bottom; y++)
2483         {
2484             int pos = (src->rect.left + src_rect->left) & 7;
2485             for (x = 0; x < src_rect->right - src_rect->left; x++, pos++)
2486             {
2487                 RGBQUAD rgb;
2488                 src_val = (src_start[pos / 8] & pixel_masks_1[pos % 8]) ? 1 : 0;
2489                 rgb = color_table[src_val];
2490                 dst_start[x] = ((rgb.rgbRed   << 7) & 0x7c00) |
2491                                ((rgb.rgbGreen << 2) & 0x03e0) |
2492                                ((rgb.rgbBlue  >> 3) & 0x001f);
2493             }
2494             if(pad_size) memset(dst_start + x, 0, pad_size);
2495             dst_start += dst->stride / 2;
2496             src_start += src->stride;
2497         }
2498         break;
2499     }
2500     }
2501 }
2502
2503 static void convert_to_16(dib_info *dst, const dib_info *src, const RECT *src_rect, BOOL dither)
2504 {
2505     WORD *dst_start = get_pixel_ptr_16(dst, 0, 0), *dst_pixel;
2506     INT x, y, pad_size = ((dst->width + 1) & ~1) * 2 - (src_rect->right - src_rect->left) * 2;
2507     DWORD src_val;
2508
2509     switch(src->bit_count)
2510     {
2511     case 32:
2512     {
2513         DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
2514
2515         if(src->funcs == &funcs_8888)
2516         {
2517             for(y = src_rect->top; y < src_rect->bottom; y++)
2518             {
2519                 dst_pixel = dst_start;
2520                 src_pixel = src_start;
2521                 for(x = src_rect->left; x < src_rect->right; x++)
2522                 {
2523                     src_val = *src_pixel++;
2524                     *dst_pixel++ = put_field(src_val >> 16, dst->red_shift,   dst->red_len)   |
2525                                    put_field(src_val >>  8, dst->green_shift, dst->green_len) |
2526                                    put_field(src_val,       dst->blue_shift,  dst->blue_len);
2527                 }
2528                 if(pad_size) memset(dst_pixel, 0, pad_size);
2529                 dst_start += dst->stride / 2;
2530                 src_start += src->stride / 4;
2531             }
2532         }
2533         else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
2534         {
2535             for(y = src_rect->top; y < src_rect->bottom; y++)
2536             {
2537                 dst_pixel = dst_start;
2538                 src_pixel = src_start;
2539                 for(x = src_rect->left; x < src_rect->right; x++)
2540                 {
2541                     src_val = *src_pixel++;
2542                     *dst_pixel++ = put_field(src_val >> src->red_shift,   dst->red_shift,   dst->red_len)   |
2543                                    put_field(src_val >> src->green_shift, dst->green_shift, dst->green_len) |
2544                                    put_field(src_val >> src->blue_shift,  dst->blue_shift,  dst->blue_len);
2545                 }
2546                 if(pad_size) memset(dst_pixel, 0, pad_size);
2547                 dst_start += dst->stride / 2;
2548                 src_start += src->stride / 4;
2549             }
2550         }
2551         else
2552         {
2553             for(y = src_rect->top; y < src_rect->bottom; y++)
2554             {
2555                 dst_pixel = dst_start;
2556                 src_pixel = src_start;
2557                 for(x = src_rect->left; x < src_rect->right; x++)
2558                 {
2559                     src_val = *src_pixel++;
2560                     *dst_pixel++ = put_field(get_field(src_val, src->red_shift,   src->red_len ),   dst->red_shift,   dst->red_len)   |
2561                                    put_field(get_field(src_val, src->green_shift, src->green_len ), dst->green_shift, dst->green_len) |
2562                                    put_field(get_field(src_val, src->blue_shift,  src->blue_len ),  dst->blue_shift,  dst->blue_len);
2563                 }
2564                 if(pad_size) memset(dst_pixel, 0, pad_size);
2565                 dst_start += dst->stride / 2;
2566                 src_start += src->stride / 4;
2567             }
2568         }
2569         break;
2570     }
2571
2572     case 24:
2573     {
2574         BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
2575
2576         for(y = src_rect->top; y < src_rect->bottom; y++)
2577         {
2578             dst_pixel = dst_start;
2579             src_pixel = src_start;
2580             for(x = src_rect->left; x < src_rect->right; x++)
2581             {
2582                 RGBQUAD rgb;
2583                 rgb.rgbBlue  = *src_pixel++;
2584                 rgb.rgbGreen = *src_pixel++;
2585                 rgb.rgbRed   = *src_pixel++;
2586
2587                 *dst_pixel++ = put_field(rgb.rgbRed,   dst->red_shift,   dst->red_len) |
2588                                put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
2589                                put_field(rgb.rgbBlue,  dst->blue_shift,  dst->blue_len);
2590             }
2591             if(pad_size) memset(dst_pixel, 0, pad_size);
2592             dst_start += dst->stride / 2;
2593             src_start += src->stride;
2594         }
2595         break;
2596     }
2597
2598     case 16:
2599     {
2600         WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2601         if(src->funcs == &funcs_555)
2602         {
2603             for(y = src_rect->top; y < src_rect->bottom; y++)
2604             {
2605                 dst_pixel = dst_start;
2606                 src_pixel = src_start;
2607                 for(x = src_rect->left; x < src_rect->right; x++)
2608                 {
2609                     src_val = *src_pixel++;
2610                     *dst_pixel++ = put_field(((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07), dst->red_shift,   dst->red_len) |
2611                                    put_field(((src_val >> 2) & 0xf8) | ((src_val >>  7) & 0x07), dst->green_shift, dst->green_len) |
2612                                    put_field(((src_val << 3) & 0xf8) | ((src_val >>  2) & 0x07), dst->blue_shift,  dst->blue_len);
2613                 }
2614                 if(pad_size) memset(dst_pixel, 0, pad_size);
2615                 dst_start += dst->stride / 2;
2616                 src_start += src->stride / 2;
2617             }
2618         }
2619         else if(bit_fields_match(src, dst))
2620         {
2621             if (src->stride > 0 && src->stride == dst->stride && !pad_size)
2622                 memcpy(dst_start, src_start, (src_rect->bottom - src_rect->top) * src->stride);
2623             else
2624             {
2625                 for(y = src_rect->top; y < src_rect->bottom; y++)
2626                 {
2627                     memcpy(dst_start, src_start, (src_rect->right - src_rect->left) * 2);
2628                     if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
2629                     dst_start += dst->stride / 2;
2630                     src_start += src->stride / 2;
2631                 }
2632             }
2633         }
2634         else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2635         {
2636             for(y = src_rect->top; y < src_rect->bottom; y++)
2637             {
2638                 dst_pixel = dst_start;
2639                 src_pixel = src_start;
2640                 for(x = src_rect->left; x < src_rect->right; x++)
2641                 {
2642                     src_val = *src_pixel++;
2643                     *dst_pixel++ = put_field( (((src_val >> src->red_shift)   << 3) & 0xf8) |
2644                                               (((src_val >> src->red_shift)   >> 2) & 0x07), dst->red_shift, dst->red_len ) |
2645                                    put_field( (((src_val >> src->green_shift) << 3) & 0xf8) |
2646                                               (((src_val >> src->green_shift) >> 2) & 0x07), dst->green_shift, dst->green_len ) |
2647                                    put_field( (((src_val >> src->blue_shift)  << 3) & 0xf8) |
2648                                               (((src_val >> src->blue_shift)  >> 2) & 0x07), dst->blue_shift, dst->blue_len);
2649                 }
2650                 if(pad_size) memset(dst_pixel, 0, pad_size);
2651                 dst_start += dst->stride / 2;
2652                 src_start += src->stride / 2;
2653             }
2654         }
2655         else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2656         {
2657             for(y = src_rect->top; y < src_rect->bottom; y++)
2658             {
2659                 dst_pixel = dst_start;
2660                 src_pixel = src_start;
2661                 for(x = src_rect->left; x < src_rect->right; x++)
2662                 {
2663                     src_val = *src_pixel++;
2664                     *dst_pixel++ = put_field( (((src_val >> src->red_shift)   << 3) & 0xf8) |
2665                                               (((src_val >> src->red_shift)   >> 2) & 0x07), dst->red_shift, dst->red_len ) |
2666                                    put_field( (((src_val >> src->green_shift) << 2) & 0xfc) |
2667                                               (((src_val >> src->green_shift) >> 4) & 0x03), dst->green_shift, dst->green_len ) |
2668                                    put_field( (((src_val >> src->blue_shift)  << 3) & 0xf8) |
2669                                               (((src_val >> src->blue_shift)  >> 2) & 0x07), dst->blue_shift, dst->blue_len);
2670                 }
2671                 if(pad_size) memset(dst_pixel, 0, pad_size);
2672                 dst_start += dst->stride / 2;
2673                 src_start += src->stride / 2;
2674             }
2675         }
2676         else
2677         {
2678             for(y = src_rect->top; y < src_rect->bottom; y++)
2679             {
2680                 dst_pixel = dst_start;
2681                 src_pixel = src_start;
2682                 for(x = src_rect->left; x < src_rect->right; x++)
2683                 {
2684                     src_val = *src_pixel++;
2685                     *dst_pixel++ = put_field(get_field(src_val, src->red_shift,   src->red_len ),   dst->red_shift,   dst->red_len)   |
2686                                    put_field(get_field(src_val, src->green_shift, src->green_len ), dst->green_shift, dst->green_len) |
2687                                    put_field(get_field(src_val, src->blue_shift,  src->blue_len ),  dst->blue_shift,  dst->blue_len);
2688                 }
2689                 if(pad_size) memset(dst_pixel, 0, pad_size);
2690                 dst_start += dst->stride / 2;
2691                 src_start += src->stride / 2;
2692             }
2693         }
2694         break;
2695     }
2696
2697     case 8:
2698     {
2699         const RGBQUAD *color_table = get_dib_color_table( src );
2700         BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
2701         for(y = src_rect->top; y < src_rect->bottom; y++)
2702         {
2703             dst_pixel = dst_start;
2704             src_pixel = src_start;
2705             for(x = src_rect->left; x < src_rect->right; x++)
2706             {
2707                 RGBQUAD rgb = color_table[*src_pixel++];
2708                 *dst_pixel++ = put_field(rgb.rgbRed,   dst->red_shift,   dst->red_len) |
2709                                put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
2710                                put_field(rgb.rgbBlue,  dst->blue_shift,  dst->blue_len);
2711             }
2712             if(pad_size) memset(dst_pixel, 0, pad_size);
2713             dst_start += dst->stride / 2;
2714             src_start += src->stride;
2715         }
2716         break;
2717     }
2718
2719     case 4:
2720     {
2721         const RGBQUAD *color_table = get_dib_color_table( src );
2722         BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
2723         for(y = src_rect->top; y < src_rect->bottom; y++)
2724         {
2725             int pos = (src->rect.left + src_rect->left) & 1;
2726             src_pixel = src_start;
2727             for (x = 0; x < src_rect->right - src_rect->left; x++, pos++)
2728             {
2729                 RGBQUAD rgb;
2730                 if (pos & 1)
2731                     rgb = color_table[*src_pixel++ & 0xf];
2732                 else
2733                     rgb = color_table[*src_pixel >> 4];
2734                 dst_start[x] = put_field(rgb.rgbRed,   dst->red_shift,   dst->red_len) |
2735                                put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
2736                                put_field(rgb.rgbBlue,  dst->blue_shift,  dst->blue_len);
2737             }
2738             if(pad_size) memset(dst_start + x, 0, pad_size);
2739             dst_start += dst->stride / 2;
2740             src_start += src->stride;
2741         }
2742         break;
2743     }
2744
2745     case 1:
2746     {
2747         const RGBQUAD *color_table = get_dib_color_table( src );
2748         BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top);
2749         for(y = src_rect->top; y < src_rect->bottom; y++)
2750         {
2751             int pos = (src->rect.left + src_rect->left) & 7;
2752             for (x = 0; x < src_rect->right - src_rect->left; x++, pos++)
2753             {
2754                 RGBQUAD rgb;
2755                 src_val = (src_start[pos / 8] & pixel_masks_1[pos % 8]) ? 1 : 0;
2756                 rgb = color_table[src_val];
2757                 dst_start[x] = put_field(rgb.rgbRed,   dst->red_shift,   dst->red_len) |
2758                                put_field(rgb.rgbGreen, dst->green_shift, dst->green_len) |
2759                                put_field(rgb.rgbBlue,  dst->blue_shift,  dst->blue_len);
2760             }
2761             if(pad_size) memset(dst_start + x, 0, pad_size);
2762             dst_start += dst->stride / 2;
2763             src_start += src->stride;
2764         }
2765         break;
2766     }
2767     }
2768 }
2769
2770 static inline BOOL color_tables_match(const dib_info *d1, const dib_info *d2)
2771 {
2772     if (!d1->color_table || !d2->color_table) return (!d1->color_table && !d2->color_table);
2773     return !memcmp(d1->color_table, d2->color_table, (1 << d1->bit_count) * sizeof(d1->color_table[0]));
2774 }
2775
2776 static inline DWORD rgb_lookup_colortable(const dib_info *dst, BYTE r, BYTE g, BYTE b)
2777 {
2778     /* Windows reduces precision to 5 bits, probably in order to build some sort of lookup cache */
2779     return rgb_to_pixel_colortable( dst, (r & ~7) + 4, (g & ~7) + 4, (b & ~7) + 4 );
2780 }
2781
2782 static void convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rect, BOOL dither)
2783 {
2784     BYTE *dst_start = get_pixel_ptr_8(dst, 0, 0), *dst_pixel;
2785     INT x, y, pad_size = ((dst->width + 3) & ~3) - (src_rect->right - src_rect->left);
2786     DWORD src_val;
2787
2788     switch(src->bit_count)
2789     {
2790     case 32:
2791     {
2792         DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
2793
2794         if(src->funcs == &funcs_8888)
2795         {
2796             for(y = src_rect->top; y < src_rect->bottom; y++)
2797             {
2798                 dst_pixel = dst_start;
2799                 src_pixel = src_start;
2800                 for(x = src_rect->left; x < src_rect->right; x++)
2801                 {
2802                     src_val = *src_pixel++;
2803                     *dst_pixel++ = rgb_lookup_colortable(dst, src_val >> 16, src_val >> 8, src_val );
2804                 }
2805                 if(pad_size) memset(dst_pixel, 0, pad_size);
2806                 dst_start += dst->stride;
2807                 src_start += src->stride / 4;
2808             }
2809         }
2810         else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
2811         {
2812             for(y = src_rect->top; y < src_rect->bottom; y++)
2813             {
2814                 dst_pixel = dst_start;
2815                 src_pixel = src_start;
2816                 for(x = src_rect->left; x < src_rect->right; x++)
2817                 {
2818                     src_val = *src_pixel++;
2819                     *dst_pixel++ = rgb_lookup_colortable(dst,
2820                                                          src_val >> src->red_shift,
2821                                                          src_val >> src->green_shift,
2822                                                          src_val >> src->blue_shift );
2823                 }
2824                 if(pad_size) memset(dst_pixel, 0, pad_size);
2825                 dst_start += dst->stride;
2826                 src_start += src->stride / 4;
2827             }
2828         }
2829         else
2830         {
2831             for(y = src_rect->top; y < src_rect->bottom; y++)
2832             {
2833                 dst_pixel = dst_start;
2834                 src_pixel = src_start;
2835                 for(x = src_rect->left; x < src_rect->right; x++)
2836                 {
2837                     src_val = *src_pixel++;
2838                     *dst_pixel++ = rgb_lookup_colortable(dst,
2839                                                          get_field(src_val, src->red_shift, src->red_len),
2840                                                          get_field(src_val, src->green_shift, src->green_len),
2841                                                          get_field(src_val, src->blue_shift, src->blue_len));
2842                 }
2843                 if(pad_size) memset(dst_pixel, 0, pad_size);
2844                 dst_start += dst->stride;
2845                 src_start += src->stride / 4;
2846             }
2847         }
2848         break;
2849     }
2850
2851     case 24:
2852     {
2853         BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
2854
2855         for(y = src_rect->top; y < src_rect->bottom; y++)
2856         {
2857             dst_pixel = dst_start;
2858             src_pixel = src_start;
2859             for(x = src_rect->left; x < src_rect->right; x++, src_pixel += 3)
2860             {
2861                 *dst_pixel++ = rgb_lookup_colortable(dst, src_pixel[2], src_pixel[1], src_pixel[0] );
2862             }
2863             if(pad_size) memset(dst_pixel, 0, pad_size);
2864             dst_start += dst->stride;
2865             src_start += src->stride;
2866         }
2867         break;
2868     }
2869
2870     case 16:
2871     {
2872         WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
2873         if(src->funcs == &funcs_555)
2874         {
2875             for(y = src_rect->top; y < src_rect->bottom; y++)
2876             {
2877                 dst_pixel = dst_start;
2878                 src_pixel = src_start;
2879                 for(x = src_rect->left; x < src_rect->right; x++)
2880                 {
2881                     src_val = *src_pixel++;
2882                     *dst_pixel++ = rgb_lookup_colortable(dst,
2883                                                          ((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07),
2884                                                          ((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07),
2885                                                          ((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07) );
2886                 }
2887                 if(pad_size) memset(dst_pixel, 0, pad_size);
2888                 dst_start += dst->stride;
2889                 src_start += src->stride / 2;
2890             }
2891         }
2892         else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
2893         {
2894             for(y = src_rect->top; y < src_rect->bottom; y++)
2895             {
2896                 dst_pixel = dst_start;
2897                 src_pixel = src_start;
2898                 for(x = src_rect->left; x < src_rect->right; x++)
2899                 {
2900                     src_val = *src_pixel++;
2901                     *dst_pixel++ = rgb_lookup_colortable(dst,
2902                                                          (((src_val >> src->red_shift)   << 3) & 0xf8) |
2903                                                          (((src_val >> src->red_shift)   >> 2) & 0x07),
2904                                                          (((src_val >> src->green_shift) << 3) & 0xf8) |
2905                                                          (((src_val >> src->green_shift) >> 2) & 0x07),
2906                                                          (((src_val >> src->blue_shift)  << 3) & 0xf8) |
2907                                                          (((src_val >> src->blue_shift)  >> 2) & 0x07) );
2908                 }
2909                 if(pad_size) memset(dst_pixel, 0, pad_size);
2910                 dst_start += dst->stride;
2911                 src_start += src->stride / 2;
2912             }
2913         }
2914         else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
2915         {
2916             for(y = src_rect->top; y < src_rect->bottom; y++)
2917             {
2918                 dst_pixel = dst_start;
2919                 src_pixel = src_start;
2920                 for(x = src_rect->left; x < src_rect->right; x++)
2921                 {
2922                     src_val = *src_pixel++;
2923                     *dst_pixel++ = rgb_lookup_colortable(dst,
2924                                                          (((src_val >> src->red_shift)   << 3) & 0xf8) |
2925                                                          (((src_val >> src->red_shift)   >> 2) & 0x07),
2926                                                          (((src_val >> src->green_shift) << 2) & 0xfc) |
2927                                                          (((src_val >> src->green_shift) >> 4) & 0x03),
2928                                                          (((src_val >> src->blue_shift)  << 3) & 0xf8) |
2929                                                          (((src_val >> src->blue_shift)  >> 2) & 0x07) );
2930                 }
2931                 if(pad_size) memset(dst_pixel, 0, pad_size);
2932                 dst_start += dst->stride;
2933                 src_start += src->stride / 2;
2934             }
2935         }
2936         else
2937         {
2938             for(y = src_rect->top; y < src_rect->bottom; y++)
2939             {
2940                 dst_pixel = dst_start;
2941                 src_pixel = src_start;
2942                 for(x = src_rect->left; x < src_rect->right; x++)
2943                 {
2944                     src_val = *src_pixel++;
2945                     *dst_pixel++ = rgb_lookup_colortable(dst,
2946                                                          get_field(src_val, src->red_shift, src->red_len),
2947                                                          get_field(src_val, src->green_shift, src->green_len),
2948                                                          get_field(src_val, src->blue_shift, src->blue_len));
2949                 }
2950                 if(pad_size) memset(dst_pixel, 0, pad_size);
2951                 dst_start += dst->stride;
2952                 src_start += src->stride / 2;
2953             }
2954         }
2955         break;
2956     }
2957
2958     case 8:
2959     {
2960         BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
2961
2962         if(color_tables_match(dst, src))
2963         {
2964             if (src->stride > 0 && src->stride == dst->stride && !pad_size)
2965                 memcpy(dst_start, src_start, (src_rect->bottom - src_rect->top) * src->stride);
2966             else
2967             {
2968                 for(y = src_rect->top; y < src_rect->bottom; y++)
2969                 {
2970                     memcpy(dst_start, src_start, src_rect->right - src_rect->left);
2971                     if(pad_size) memset(dst_start + (src_rect->right - src_rect->left), 0, pad_size);
2972                     dst_start += dst->stride;
2973                     src_start += src->stride;
2974                 }
2975             }
2976         }
2977         else
2978         {
2979             const RGBQUAD *color_table = get_dib_color_table( src );
2980             for(y = src_rect->top; y < src_rect->bottom; y++)
2981             {
2982                 dst_pixel = dst_start;
2983                 src_pixel = src_start;
2984                 for(x = src_rect->left; x < src_rect->right; x++)
2985                 {
2986                     RGBQUAD rgb = color_table[*src_pixel++];
2987                     *dst_pixel++ = rgb_to_pixel_colortable(dst, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
2988                 }
2989                 if(pad_size) memset(dst_pixel, 0, pad_size);
2990                 dst_start += dst->stride;
2991                 src_start += src->stride;
2992             }
2993         }
2994         break;
2995     }
2996
2997     case 4:
2998     {
2999         const RGBQUAD *color_table = get_dib_color_table( src );
3000         BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
3001         for(y = src_rect->top; y < src_rect->bottom; y++)
3002         {
3003             int pos = (src->rect.left + src_rect->left) & 1;
3004             src_pixel = src_start;
3005             for (x = 0; x < src_rect->right - src_rect->left; x++, pos++)
3006             {
3007                 RGBQUAD rgb;
3008                 if (pos & 1)
3009                     rgb = color_table[*src_pixel++ & 0xf];
3010                 else
3011                     rgb = color_table[*src_pixel >> 4];
3012                 dst_start[x] = rgb_to_pixel_colortable(dst, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
3013             }
3014             if(pad_size) memset(dst_start + x, 0, pad_size);
3015             dst_start += dst->stride;
3016             src_start += src->stride;
3017         }
3018         break;
3019     }
3020
3021     case 1:
3022     {
3023         const RGBQUAD *color_table = get_dib_color_table( src );
3024         BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top);
3025         for(y = src_rect->top; y < src_rect->bottom; y++)
3026         {
3027             int pos = (src->rect.left + src_rect->left) & 7;
3028             for (x = 0; x < src_rect->right - src_rect->left; x++, pos++)
3029             {
3030                 RGBQUAD rgb;
3031                 src_val = (src_start[pos / 8] & pixel_masks_1[pos % 8]) ? 1 : 0;
3032                 rgb = color_table[src_val];
3033                 dst_start[x] = rgb_to_pixel_colortable(dst, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
3034             }
3035             if(pad_size) memset(dst_start + x, 0, pad_size);
3036             dst_start += dst->stride;
3037             src_start += src->stride;
3038         }
3039         break;
3040     }
3041     }
3042 }
3043
3044 static void convert_to_4(dib_info *dst, const dib_info *src, const RECT *src_rect, BOOL dither)
3045 {
3046     BYTE *dst_start = get_pixel_ptr_4(dst, 0, 0), *dst_pixel, dst_val;
3047     INT x, y, pad_size = ((dst->width + 7) & ~7) / 2 - (src_rect->right - src_rect->left + 1) / 2;
3048     DWORD src_val;
3049
3050     switch(src->bit_count)
3051     {
3052     case 32:
3053     {
3054         DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
3055
3056         if(src->funcs == &funcs_8888)
3057         {
3058             for(y = src_rect->top; y < src_rect->bottom; y++)
3059             {
3060                 dst_pixel = dst_start;
3061                 src_pixel = src_start;
3062                 for(x = src_rect->left; x < src_rect->right; x++)
3063                 {
3064                     src_val = *src_pixel++;
3065                     dst_val = rgb_to_pixel_colortable(dst, src_val >> 16, src_val >> 8, src_val);
3066                     if((x - src_rect->left) & 1)
3067                     {
3068                         *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3069                         dst_pixel++;
3070                     }
3071                     else
3072                         *dst_pixel = (dst_val << 4) & 0xf0;
3073                 }
3074                 if(pad_size)
3075                 {
3076                     if((x - src_rect->left) & 1) dst_pixel++;
3077                     memset(dst_pixel, 0, pad_size);
3078                 }
3079                 dst_start += dst->stride;
3080                 src_start += src->stride / 4;
3081             }
3082         }
3083         else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
3084         {
3085             for(y = src_rect->top; y < src_rect->bottom; y++)
3086             {
3087                 dst_pixel = dst_start;
3088                 src_pixel = src_start;
3089                 for(x = src_rect->left; x < src_rect->right; x++)
3090                 {
3091                     src_val = *src_pixel++;
3092                     dst_val = rgb_to_pixel_colortable(dst,
3093                                                       src_val >> src->red_shift,
3094                                                       src_val >> src->green_shift,
3095                                                       src_val >> src->blue_shift);
3096                     if((x - src_rect->left) & 1)
3097                     {
3098                         *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3099                         dst_pixel++;
3100                     }
3101                     else
3102                         *dst_pixel = (dst_val << 4) & 0xf0;
3103                 }
3104                 if(pad_size)
3105                 {
3106                     if((x - src_rect->left) & 1) dst_pixel++;
3107                     memset(dst_pixel, 0, pad_size);
3108                 }
3109                 dst_start += dst->stride;
3110                 src_start += src->stride / 4;
3111             }
3112         }
3113         else
3114         {
3115             for(y = src_rect->top; y < src_rect->bottom; y++)
3116             {
3117                 dst_pixel = dst_start;
3118                 src_pixel = src_start;
3119                 for(x = src_rect->left; x < src_rect->right; x++)
3120                 {
3121                     src_val = *src_pixel++;
3122                     dst_val = rgb_to_pixel_colortable(dst,
3123                                                       get_field(src_val, src->red_shift, src->red_len),
3124                                                       get_field(src_val, src->green_shift, src->green_len),
3125                                                       get_field(src_val, src->blue_shift, src->blue_len));
3126                     if((x - src_rect->left) & 1)
3127                     {
3128                         *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3129                         dst_pixel++;
3130                     }
3131                     else
3132                         *dst_pixel = (dst_val << 4) & 0xf0;
3133                 }
3134                 if(pad_size)
3135                 {
3136                     if((x - src_rect->left) & 1) dst_pixel++;
3137                     memset(dst_pixel, 0, pad_size);
3138                 }
3139                 dst_start += dst->stride;
3140                 src_start += src->stride / 4;
3141             }
3142         }
3143         break;
3144     }
3145
3146     case 24:
3147     {
3148         BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
3149
3150         for(y = src_rect->top; y < src_rect->bottom; y++)
3151         {
3152             dst_pixel = dst_start;
3153             src_pixel = src_start;
3154             for(x = src_rect->left; x < src_rect->right; x++, src_pixel += 3)
3155             {
3156                 dst_val = rgb_to_pixel_colortable(dst, src_pixel[2], src_pixel[1], src_pixel[0]);
3157
3158                 if((x - src_rect->left) & 1)
3159                 {
3160                     *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3161                     dst_pixel++;
3162                 }
3163                 else
3164                     *dst_pixel = (dst_val << 4) & 0xf0;
3165             }
3166             if(pad_size)
3167             {
3168                 if((x - src_rect->left) & 1) dst_pixel++;
3169                 memset(dst_pixel, 0, pad_size);
3170             }
3171             dst_start += dst->stride;
3172             src_start += src->stride;
3173         }
3174         break;
3175     }
3176
3177     case 16:
3178     {
3179         WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
3180         if(src->funcs == &funcs_555)
3181         {
3182             for(y = src_rect->top; y < src_rect->bottom; y++)
3183             {
3184                 dst_pixel = dst_start;
3185                 src_pixel = src_start;
3186                 for(x = src_rect->left; x < src_rect->right; x++)
3187                 {
3188                     src_val = *src_pixel++;
3189                     dst_val = rgb_to_pixel_colortable(dst,
3190                                                       ((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07),
3191                                                       ((src_val >> 2) & 0xf8) | ((src_val >>  7) & 0x07),
3192                                                       ((src_val << 3) & 0xf8) | ((src_val >>  2) & 0x07) );
3193                     if((x - src_rect->left) & 1)
3194                     {
3195                         *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3196                         dst_pixel++;
3197                     }
3198                     else
3199                         *dst_pixel = (dst_val << 4) & 0xf0;
3200                 }
3201                 if(pad_size)
3202                 {
3203                     if((x - src_rect->left) & 1) dst_pixel++;
3204                     memset(dst_pixel, 0, pad_size);
3205                 }
3206                 dst_start += dst->stride;
3207                 src_start += src->stride / 2;
3208             }
3209         }
3210         else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
3211         {
3212             for(y = src_rect->top; y < src_rect->bottom; y++)
3213             {
3214                 dst_pixel = dst_start;
3215                 src_pixel = src_start;
3216                 for(x = src_rect->left; x < src_rect->right; x++)
3217                 {
3218                     src_val = *src_pixel++;
3219                     dst_val = rgb_to_pixel_colortable(dst,
3220                                                       (((src_val >> src->red_shift)   << 3) & 0xf8) |
3221                                                       (((src_val >> src->red_shift)   >> 2) & 0x07),
3222                                                       (((src_val >> src->green_shift) << 3) & 0xf8) |
3223                                                       (((src_val >> src->green_shift) >> 2) & 0x07),
3224                                                       (((src_val >> src->blue_shift)  << 3) & 0xf8) |
3225                                                       (((src_val >> src->blue_shift)  >> 2) & 0x07) );
3226                     if((x - src_rect->left) & 1)
3227                     {
3228                         *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3229                         dst_pixel++;
3230                     }
3231                     else
3232                         *dst_pixel = (dst_val << 4) & 0xf0;
3233                 }
3234                 if(pad_size)
3235                 {
3236                     if((x - src_rect->left) & 1) dst_pixel++;
3237                     memset(dst_pixel, 0, pad_size);
3238                 }
3239                 dst_start += dst->stride;
3240                 src_start += src->stride / 2;
3241             }
3242         }
3243         else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
3244         {
3245             for(y = src_rect->top; y < src_rect->bottom; y++)
3246             {
3247                 dst_pixel = dst_start;
3248                 src_pixel = src_start;
3249                 for(x = src_rect->left; x < src_rect->right; x++)
3250                 {
3251                     src_val = *src_pixel++;
3252                     dst_val = rgb_to_pixel_colortable(dst,
3253                                                       (((src_val >> src->red_shift)   << 3) & 0xf8) |
3254                                                       (((src_val >> src->red_shift)   >> 2) & 0x07),
3255                                                       (((src_val >> src->green_shift) << 2) & 0xfc) |
3256                                                       (((src_val >> src->green_shift) >> 4) & 0x03),
3257                                                       (((src_val >> src->blue_shift)  << 3) & 0xf8) |
3258                                                       (((src_val >> src->blue_shift)  >> 2) & 0x07) );
3259                     if((x - src_rect->left) & 1)
3260                     {
3261                         *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3262                         dst_pixel++;
3263                     }
3264                     else
3265                         *dst_pixel = (dst_val << 4) & 0xf0;
3266                 }
3267                 if(pad_size)
3268                 {
3269                     if((x - src_rect->left) & 1) dst_pixel++;
3270                     memset(dst_pixel, 0, pad_size);
3271                 }
3272                 dst_start += dst->stride;
3273                 src_start += src->stride / 2;
3274             }
3275         }
3276         else
3277         {
3278             for(y = src_rect->top; y < src_rect->bottom; y++)
3279             {
3280                 dst_pixel = dst_start;
3281                 src_pixel = src_start;
3282                 for(x = src_rect->left; x < src_rect->right; x++)
3283                 {
3284                     src_val = *src_pixel++;
3285                     dst_val = rgb_to_pixel_colortable(dst,
3286                                                       get_field(src_val, src->red_shift, src->red_len),
3287                                                       get_field(src_val, src->green_shift, src->green_len),
3288                                                       get_field(src_val, src->blue_shift, src->blue_len));
3289                     if((x - src_rect->left) & 1)
3290                     {
3291                         *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3292                         dst_pixel++;
3293                     }
3294                     else
3295                         *dst_pixel = (dst_val << 4) & 0xf0;
3296                 }
3297                 if(pad_size)
3298                 {
3299                     if((x - src_rect->left) & 1) dst_pixel++;
3300                     memset(dst_pixel, 0, pad_size);
3301                 }
3302                 dst_start += dst->stride;
3303                 src_start += src->stride / 2;
3304             }
3305         }
3306         break;
3307     }
3308
3309     case 8:
3310     {
3311         const RGBQUAD *color_table = get_dib_color_table( src );
3312         BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
3313
3314         for(y = src_rect->top; y < src_rect->bottom; y++)
3315         {
3316             dst_pixel = dst_start;
3317             src_pixel = src_start;
3318             for(x = src_rect->left; x < src_rect->right; x++)
3319             {
3320                 RGBQUAD rgb = color_table[*src_pixel++];
3321                 dst_val = rgb_to_pixel_colortable(dst, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
3322                 if((x - src_rect->left) & 1)
3323                 {
3324                     *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3325                     dst_pixel++;
3326                 }
3327                 else
3328                     *dst_pixel = (dst_val << 4) & 0xf0;
3329             }
3330             if(pad_size)
3331             {
3332                 if((x - src_rect->left) & 1) dst_pixel++;
3333                 memset(dst_pixel, 0, pad_size);
3334             }
3335             dst_start += dst->stride;
3336             src_start += src->stride;
3337         }
3338         break;
3339     }
3340
3341     case 4:
3342     {
3343         BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
3344
3345         if(color_tables_match(dst, src) && ((src->rect.left + src_rect->left) & 1) == 0)
3346         {
3347             if (src->stride > 0 && src->stride == dst->stride && !pad_size)
3348                 memcpy(dst_start, src_start, (src_rect->bottom - src_rect->top) * src->stride);
3349             else
3350             {
3351                 for(y = src_rect->top; y < src_rect->bottom; y++)
3352                 {
3353                     memcpy(dst_start, src_start, (src_rect->right - src_rect->left + 1) / 2);
3354                     if(pad_size) memset(dst_start + (src_rect->right - src_rect->left + 1) / 2, 0, pad_size);
3355                     dst_start += dst->stride;
3356                     src_start += src->stride;
3357                 }
3358             }
3359         }
3360         else
3361         {
3362             const RGBQUAD *color_table = get_dib_color_table( src );
3363             for(y = src_rect->top; y < src_rect->bottom; y++)
3364             {
3365                 int pos = (src->rect.left + src_rect->left) & 1;
3366                 dst_pixel = dst_start;
3367                 src_pixel = src_start;
3368                 for(x = src_rect->left; x < src_rect->right; x++, pos++)
3369                 {
3370                     RGBQUAD rgb;
3371                     if(pos & 1)
3372                         rgb = color_table[*src_pixel++ & 0xf];
3373                     else
3374                         rgb = color_table[*src_pixel >> 4];
3375                     dst_val = rgb_to_pixel_colortable(dst, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
3376                     if((x - src_rect->left) & 1)
3377                     {
3378                         *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3379                         dst_pixel++;
3380                     }
3381                     else
3382                         *dst_pixel = (dst_val << 4) & 0xf0;
3383                 }
3384                 if(pad_size)
3385                 {
3386                     if((x - src_rect->left) & 1) dst_pixel++;
3387                     memset(dst_pixel, 0, pad_size);
3388                 }
3389                 dst_start += dst->stride;
3390                 src_start += src->stride;
3391             }
3392         }
3393         break;
3394     }
3395
3396     case 1:
3397     {
3398         const RGBQUAD *color_table = get_dib_color_table( src );
3399         BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top);
3400         for(y = src_rect->top; y < src_rect->bottom; y++)
3401         {
3402             int pos = (src->rect.left + src_rect->left) & 7;
3403             dst_pixel = dst_start;
3404             for(x = src_rect->left; x < src_rect->right; x++, pos++)
3405             {
3406                 RGBQUAD rgb;
3407                 src_val = (src_start[pos / 8] & pixel_masks_1[pos % 8]) ? 1 : 0;
3408                 rgb = color_table[src_val];
3409                 dst_val = rgb_to_pixel_colortable(dst, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
3410                 if((x - src_rect->left) & 1)
3411                 {
3412                     *dst_pixel = (dst_val & 0x0f) | (*dst_pixel & 0xf0);
3413                     dst_pixel++;
3414                 }
3415                 else
3416                     *dst_pixel = (dst_val << 4) & 0xf0;
3417             }
3418             if(pad_size)
3419             {
3420                 if((x - src_rect->left) & 1) dst_pixel++;
3421                 memset(dst_pixel, 0, pad_size);
3422             }
3423             dst_start += dst->stride;
3424             src_start += src->stride;
3425         }
3426         break;
3427     }
3428     }
3429 }
3430
3431 static void convert_to_1(dib_info *dst, const dib_info *src, const RECT *src_rect, BOOL dither)
3432 {
3433     BYTE *dst_start = get_pixel_ptr_1(dst, 0, 0), *dst_pixel, dst_val;
3434     INT x, y, pad_size = ((dst->width + 31) & ~31) / 8 - (src_rect->right - src_rect->left + 7) / 8;
3435     DWORD src_val;
3436     int bit_pos;
3437
3438     switch(src->bit_count)
3439     {
3440     case 32:
3441     {
3442         DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
3443
3444         if(src->funcs == &funcs_8888)
3445         {
3446             for(y = src_rect->top; y < src_rect->bottom; y++)
3447             {
3448                 dst_pixel = dst_start;
3449                 src_pixel = src_start;
3450                 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3451                 {
3452                     src_val = *src_pixel++;
3453                     dst_val = rgb_to_pixel_mono(dst, dither, x, y, src_val >> 16, src_val >> 8, src_val);
3454
3455                     if(bit_pos == 0) *dst_pixel = 0;
3456                     *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3457
3458                     if(++bit_pos == 8)
3459                     {
3460                         dst_pixel++;
3461                         bit_pos = 0;
3462                     }
3463                 }
3464                 if(pad_size)
3465                 {
3466                     if(bit_pos != 0) dst_pixel++;
3467                     memset(dst_pixel, 0, pad_size);
3468                 }
3469                 dst_start += dst->stride;
3470                 src_start += src->stride / 4;
3471             }
3472         }
3473         else if(src->red_len == 8 && src->green_len == 8 && src->blue_len == 8)
3474         {
3475             for(y = src_rect->top; y < src_rect->bottom; y++)
3476             {
3477                 dst_pixel = dst_start;
3478                 src_pixel = src_start;
3479                 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3480                 {
3481                     src_val = *src_pixel++;
3482                     dst_val = rgb_to_pixel_mono(dst, dither, x, y,
3483                                                 src_val >> src->red_shift,
3484                                                 src_val >> src->green_shift,
3485                                                 src_val >> src->blue_shift);
3486
3487                    if(bit_pos == 0) *dst_pixel = 0;
3488                     *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3489
3490                     if(++bit_pos == 8)
3491                     {
3492                         dst_pixel++;
3493                         bit_pos = 0;
3494                     }
3495                 }
3496                 if(pad_size)
3497                 {
3498                     if(bit_pos != 0) dst_pixel++;
3499                     memset(dst_pixel, 0, pad_size);
3500                 }
3501                 dst_start += dst->stride;
3502                 src_start += src->stride / 4;
3503             }
3504         }
3505         else
3506         {
3507             for(y = src_rect->top; y < src_rect->bottom; y++)
3508             {
3509                 dst_pixel = dst_start;
3510                 src_pixel = src_start;
3511                 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3512                 {
3513                     src_val = *src_pixel++;
3514                     dst_val = rgb_to_pixel_mono(dst, dither, x, y,
3515                                                 get_field(src_val, src->red_shift, src->red_len),
3516                                                 get_field(src_val, src->green_shift, src->green_len),
3517                                                 get_field(src_val, src->blue_shift, src->blue_len));
3518
3519                    if(bit_pos == 0) *dst_pixel = 0;
3520                     *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3521
3522                     if(++bit_pos == 8)
3523                     {
3524                         dst_pixel++;
3525                         bit_pos = 0;
3526                     }
3527                 }
3528                 if(pad_size)
3529                 {
3530                     if(bit_pos != 0) dst_pixel++;
3531                     memset(dst_pixel, 0, pad_size);
3532                 }
3533                 dst_start += dst->stride;
3534                 src_start += src->stride / 4;
3535             }
3536         }
3537         break;
3538     }
3539
3540     case 24:
3541     {
3542         BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
3543
3544         for(y = src_rect->top; y < src_rect->bottom; y++)
3545         {
3546             dst_pixel = dst_start;
3547             src_pixel = src_start;
3548             for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++, src_pixel += 3)
3549             {
3550                 dst_val = rgb_to_pixel_mono(dst, dither, x, y, src_pixel[2], src_pixel[1], src_pixel[0]);
3551
3552                 if(bit_pos == 0) *dst_pixel = 0;
3553                 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3554
3555                 if(++bit_pos == 8)
3556                 {
3557                     dst_pixel++;
3558                     bit_pos = 0;
3559                 }
3560             }
3561             if(pad_size)
3562             {
3563                 if(bit_pos != 0) dst_pixel++;
3564                 memset(dst_pixel, 0, pad_size);
3565             }
3566             dst_start += dst->stride;
3567             src_start += src->stride;
3568         }
3569         break;
3570     }
3571
3572     case 16:
3573     {
3574         WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
3575         if(src->funcs == &funcs_555)
3576         {
3577             for(y = src_rect->top; y < src_rect->bottom; y++)
3578             {
3579                 dst_pixel = dst_start;
3580                 src_pixel = src_start;
3581                 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3582                 {
3583                     src_val = *src_pixel++;
3584                     dst_val = rgb_to_pixel_mono(dst, dither, x, y,
3585                                                 ((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07),
3586                                                 ((src_val >> 2) & 0xf8) | ((src_val >>  7) & 0x07),
3587                                                 ((src_val << 3) & 0xf8) | ((src_val >>  2) & 0x07));
3588
3589                     if(bit_pos == 0) *dst_pixel = 0;
3590                     *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3591
3592                     if(++bit_pos == 8)
3593                     {
3594                         dst_pixel++;
3595                         bit_pos = 0;
3596                     }
3597                 }
3598                 if(pad_size)
3599                 {
3600                     if(bit_pos != 0) dst_pixel++;
3601                     memset(dst_pixel, 0, pad_size);
3602                 }
3603                 dst_start += dst->stride;
3604                 src_start += src->stride / 2;
3605             }
3606         }
3607         else if(src->red_len == 5 && src->green_len == 5 && src->blue_len == 5)
3608         {
3609             for(y = src_rect->top; y < src_rect->bottom; y++)
3610             {
3611                 dst_pixel = dst_start;
3612                 src_pixel = src_start;
3613                 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3614                 {
3615                     src_val = *src_pixel++;
3616                     dst_val = rgb_to_pixel_mono(dst, dither, x, y,
3617                                                 (((src_val >> src->red_shift)   << 3) & 0xf8) |
3618                                                 (((src_val >> src->red_shift)   >> 2) & 0x07),
3619                                                 (((src_val >> src->green_shift) << 3) & 0xf8) |
3620                                                 (((src_val >> src->green_shift) >> 2) & 0x07),
3621                                                 (((src_val >> src->blue_shift)  << 3) & 0xf8) |
3622                                                 (((src_val >> src->blue_shift)  >> 2) & 0x07));
3623                     if(bit_pos == 0) *dst_pixel = 0;
3624                     *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3625
3626                     if(++bit_pos == 8)
3627                     {
3628                         dst_pixel++;
3629                         bit_pos = 0;
3630                     }
3631                 }
3632                 if(pad_size)
3633                 {
3634                     if(bit_pos != 0) dst_pixel++;
3635                     memset(dst_pixel, 0, pad_size);
3636                 }
3637                 dst_start += dst->stride;
3638                 src_start += src->stride / 2;
3639             }
3640         }
3641         else if(src->red_len == 5 && src->green_len == 6 && src->blue_len == 5)
3642         {
3643             for(y = src_rect->top; y < src_rect->bottom; y++)
3644             {
3645                 dst_pixel = dst_start;
3646                 src_pixel = src_start;
3647                 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3648                 {
3649                     src_val = *src_pixel++;
3650                     dst_val = rgb_to_pixel_mono(dst, dither, x, y,
3651                                                 (((src_val >> src->red_shift)   << 3) & 0xf8) |
3652                                                 (((src_val >> src->red_shift)   >> 2) & 0x07),
3653                                                 (((src_val >> src->green_shift) << 2) & 0xfc) |
3654                                                 (((src_val >> src->green_shift) >> 4) & 0x03),
3655                                                 (((src_val >> src->blue_shift)  << 3) & 0xf8) |
3656                                                 (((src_val >> src->blue_shift)  >> 2) & 0x07));
3657                     if(bit_pos == 0) *dst_pixel = 0;
3658                     *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3659
3660                     if(++bit_pos == 8)
3661                     {
3662                         dst_pixel++;
3663                         bit_pos = 0;
3664                     }
3665                 }
3666                 if(pad_size)
3667                 {
3668                     if(bit_pos != 0) dst_pixel++;
3669                     memset(dst_pixel, 0, pad_size);
3670                 }
3671                 dst_start += dst->stride;
3672                 src_start += src->stride / 2;
3673             }
3674         }
3675         else
3676         {
3677             for(y = src_rect->top; y < src_rect->bottom; y++)
3678             {
3679                 dst_pixel = dst_start;
3680                 src_pixel = src_start;
3681                 for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3682                 {
3683                     src_val = *src_pixel++;
3684                     dst_val = rgb_to_pixel_mono(dst, dither, x, y,
3685                                                 get_field(src_val, src->red_shift, src->red_len),
3686                                                 get_field(src_val, src->green_shift, src->green_len),
3687                                                 get_field(src_val, src->blue_shift, src->blue_len));
3688                     if(bit_pos == 0) *dst_pixel = 0;
3689                     *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3690
3691                     if(++bit_pos == 8)
3692                     {
3693                         dst_pixel++;
3694                         bit_pos = 0;
3695                     }
3696                 }
3697                 if(pad_size)
3698                 {
3699                     if(bit_pos != 0) dst_pixel++;
3700                     memset(dst_pixel, 0, pad_size);
3701                 }
3702                 dst_start += dst->stride;
3703                 src_start += src->stride / 2;
3704             }
3705         }
3706         break;
3707     }
3708
3709     case 8:
3710     {
3711         const RGBQUAD *color_table = get_dib_color_table( src );
3712         BYTE *src_start = get_pixel_ptr_8(src, src_rect->left, src_rect->top), *src_pixel;
3713
3714         for(y = src_rect->top; y < src_rect->bottom; y++)
3715         {
3716             dst_pixel = dst_start;
3717             src_pixel = src_start;
3718             for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++)
3719             {
3720                 RGBQUAD rgb = color_table[*src_pixel++];
3721                 dst_val = rgb_to_pixel_mono(dst, dither, x, y, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
3722
3723                 if(bit_pos == 0) *dst_pixel = 0;
3724                 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3725
3726                 if(++bit_pos == 8)
3727                 {
3728                     dst_pixel++;
3729                     bit_pos = 0;
3730                 }
3731             }
3732             if(pad_size)
3733             {
3734                 if(bit_pos != 0) dst_pixel++;
3735                 memset(dst_pixel, 0, pad_size);
3736             }
3737             dst_start += dst->stride;
3738             src_start += src->stride;
3739         }
3740         break;
3741     }
3742
3743     case 4:
3744     {
3745         const RGBQUAD *color_table = get_dib_color_table( src );
3746         BYTE *src_start = get_pixel_ptr_4(src, src_rect->left, src_rect->top), *src_pixel;
3747
3748         for(y = src_rect->top; y < src_rect->bottom; y++)
3749         {
3750             int pos = (src->rect.left + src_rect->left) & 1;
3751             dst_pixel = dst_start;
3752             src_pixel = src_start;
3753             for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++, pos++)
3754             {
3755                 RGBQUAD rgb;
3756                 if (pos & 1)
3757                     rgb = color_table[*src_pixel++ & 0xf];
3758                 else
3759                     rgb = color_table[*src_pixel >> 4];
3760                 dst_val = rgb_to_pixel_mono(dst, dither, x, y, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
3761
3762                 if(bit_pos == 0) *dst_pixel = 0;
3763                 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3764
3765                 if(++bit_pos == 8)
3766                 {
3767                     dst_pixel++;
3768                     bit_pos = 0;
3769                 }
3770             }
3771             if(pad_size)
3772             {
3773                 if(bit_pos != 0) dst_pixel++;
3774                 memset(dst_pixel, 0, pad_size);
3775             }
3776             dst_start += dst->stride;
3777             src_start += src->stride;
3778         }
3779         break;
3780     }
3781
3782     /* Note that while MSDN states that a 1 bpp dib brush -> mono dc
3783        uses text/bkgnd colours instead of the dib's colour table, this
3784        doesn't appear to be the case for a dc backed by a
3785        dibsection. */
3786
3787     case 1:
3788     {
3789         const RGBQUAD *color_table = get_dib_color_table( src );
3790         BYTE *src_start = get_pixel_ptr_1(src, src_rect->left, src_rect->top);
3791         for(y = src_rect->top; y < src_rect->bottom; y++)
3792         {
3793             int pos = (src->rect.left + src_rect->left) & 7;
3794             dst_pixel = dst_start;
3795             for(x = src_rect->left, bit_pos = 0; x < src_rect->right; x++, pos++)
3796             {
3797                 RGBQUAD rgb;
3798                 src_val = (src_start[pos / 8] & pixel_masks_1[pos % 8]) ? 1 : 0;
3799                 rgb = color_table[src_val];
3800                 dst_val = rgb_to_pixel_mono(dst, dither, x, y, rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
3801
3802                 if(bit_pos == 0) *dst_pixel = 0;
3803                 *dst_pixel = (*dst_pixel & ~pixel_masks_1[bit_pos]) | (dst_val & pixel_masks_1[bit_pos]);
3804
3805                 if(++bit_pos == 8)
3806                 {
3807                     dst_pixel++;
3808                     bit_pos = 0;
3809                 }
3810             }
3811             if(pad_size)
3812             {
3813                 if(bit_pos != 0) dst_pixel++;
3814                 memset(dst_pixel, 0, pad_size);
3815             }
3816             dst_start += dst->stride;
3817             src_start += src->stride;
3818         }
3819         break;
3820     }
3821     }
3822 }
3823
3824 static void convert_to_null(dib_info *dst, const dib_info *src, const RECT *src_rect, BOOL dither)
3825 {
3826 }
3827
3828 static inline BYTE blend_color(BYTE dst, BYTE src, DWORD alpha)
3829 {
3830     return (src * alpha + dst * (255 - alpha) + 127) / 255;
3831 }
3832
3833 static inline DWORD blend_argb_constant_alpha( DWORD dst, DWORD src, DWORD alpha )
3834 {
3835     return (blend_color( dst, src, alpha ) |
3836             blend_color( dst >> 8, src >> 8, alpha ) << 8 |
3837             blend_color( dst >> 16, src >> 16, alpha ) << 16 |
3838             blend_color( dst >> 24, src >> 24, alpha ) << 24);
3839 }
3840
3841 static inline DWORD blend_argb_no_src_alpha( DWORD dst, DWORD src, DWORD alpha )
3842 {
3843     return (blend_color( dst, src, alpha ) |
3844             blend_color( dst >> 8, src >> 8, alpha ) << 8 |
3845             blend_color( dst >> 16, src >> 16, alpha ) << 16 |
3846             blend_color( dst >> 24, 255, alpha ) << 24);
3847 }
3848
3849 static inline DWORD blend_argb( DWORD dst, DWORD src )
3850 {
3851     BYTE b = (BYTE)src;
3852     BYTE g = (BYTE)(src >> 8);
3853     BYTE r = (BYTE)(src >> 16);
3854     DWORD alpha  = (BYTE)(src >> 24);
3855     return ((b     + ((BYTE)dst         * (255 - alpha) + 127) / 255) |
3856             (g     + ((BYTE)(dst >> 8)  * (255 - alpha) + 127) / 255) << 8 |
3857             (r     + ((BYTE)(dst >> 16) * (255 - alpha) + 127) / 255) << 16 |
3858             (alpha + ((BYTE)(dst >> 24) * (255 - alpha) + 127) / 255) << 24);
3859 }
3860
3861 static inline DWORD blend_argb_alpha( DWORD dst, DWORD src, DWORD alpha )
3862 {
3863     BYTE b = ((BYTE)src         * alpha + 127) / 255;
3864     BYTE g = ((BYTE)(src >> 8)  * alpha + 127) / 255;
3865     BYTE r = ((BYTE)(src >> 16) * alpha + 127) / 255;
3866     alpha  = ((BYTE)(src >> 24) * alpha + 127) / 255;
3867     return ((b     + ((BYTE)dst         * (255 - alpha) + 127) / 255) |
3868             (g     + ((BYTE)(dst >> 8)  * (255 - alpha) + 127) / 255) << 8 |
3869             (r     + ((BYTE)(dst >> 16) * (255 - alpha) + 127) / 255) << 16 |
3870             (alpha + ((BYTE)(dst >> 24) * (255 - alpha) + 127) / 255) << 24);
3871 }
3872
3873 static inline DWORD blend_rgb( BYTE dst_r, BYTE dst_g, BYTE dst_b, DWORD src, BLENDFUNCTION blend )
3874 {
3875     if (blend.AlphaFormat & AC_SRC_ALPHA)
3876     {
3877         DWORD alpha = blend.SourceConstantAlpha;
3878         BYTE src_b = ((BYTE)src         * alpha + 127) / 255;
3879         BYTE src_g = ((BYTE)(src >> 8)  * alpha + 127) / 255;
3880         BYTE src_r = ((BYTE)(src >> 16) * alpha + 127) / 255;
3881         alpha      = ((BYTE)(src >> 24) * alpha + 127) / 255;
3882         return ((src_b + (dst_b * (255 - alpha) + 127) / 255) |
3883                 (src_g + (dst_g * (255 - alpha) + 127) / 255) << 8 |
3884                 (src_r + (dst_r * (255 - alpha) + 127) / 255) << 16);
3885     }
3886     return (blend_color( dst_b, src, blend.SourceConstantAlpha ) |
3887             blend_color( dst_g, src >> 8, blend.SourceConstantAlpha ) << 8 |
3888             blend_color( dst_r, src >> 16, blend.SourceConstantAlpha ) << 16);
3889 }
3890
3891 static void blend_rect_8888(const dib_info *dst, const RECT *rc,
3892                             const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
3893 {
3894     DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
3895     DWORD *dst_ptr = get_pixel_ptr_32( dst, rc->left, rc->top );
3896     int x, y;
3897
3898     if (blend.AlphaFormat & AC_SRC_ALPHA)
3899     {
3900         if (blend.SourceConstantAlpha == 255)
3901             for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
3902                 for (x = 0; x < rc->right - rc->left; x++)
3903                     dst_ptr[x] = blend_argb( dst_ptr[x], src_ptr[x] );
3904         else
3905             for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
3906                 for (x = 0; x < rc->right - rc->left; x++)
3907                     dst_ptr[x] = blend_argb_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
3908     }
3909     else if (src->compression == BI_RGB)
3910         for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
3911             for (x = 0; x < rc->right - rc->left; x++)
3912                 dst_ptr[x] = blend_argb_constant_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
3913     else
3914         for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
3915             for (x = 0; x < rc->right - rc->left; x++)
3916                 dst_ptr[x] = blend_argb_no_src_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
3917 }
3918
3919 static void blend_rect_32(const dib_info *dst, const RECT *rc,
3920                           const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
3921 {
3922     DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
3923     DWORD *dst_ptr = get_pixel_ptr_32( dst, rc->left, rc->top );
3924     int x, y;
3925
3926     if (dst->red_len == 8 && dst->green_len == 8 && dst->blue_len == 8)
3927     {
3928         for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
3929         {
3930             for (x = 0; x < rc->right - rc->left; x++)
3931             {
3932                 DWORD val = blend_rgb( dst_ptr[x] >> dst->red_shift,
3933                                        dst_ptr[x] >> dst->green_shift,
3934                                        dst_ptr[x] >> dst->blue_shift,
3935                                        src_ptr[x], blend );
3936                 dst_ptr[x] = ((( val        & 0xff) << dst->blue_shift) |
3937                               (((val >> 8)  & 0xff) << dst->green_shift) |
3938                               (((val >> 16) & 0xff) << dst->red_shift));
3939             }
3940         }
3941     }
3942     else
3943     {
3944         for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
3945         {
3946             for (x = 0; x < rc->right - rc->left; x++)
3947             {
3948                 DWORD val = blend_rgb( get_field( dst_ptr[x], dst->red_shift, dst->red_len ),
3949                                        get_field( dst_ptr[x], dst->green_shift, dst->green_len ),
3950                                        get_field( dst_ptr[x], dst->blue_shift, dst->blue_len ),
3951                                        src_ptr[x], blend );
3952                 dst_ptr[x] = (put_field( val >> 16, dst->red_shift,   dst->red_len )   |
3953                               put_field( val >> 8,  dst->green_shift, dst->green_len ) |
3954                               put_field( val,       dst->blue_shift,  dst->blue_len ));
3955             }
3956         }
3957     }
3958 }
3959
3960 static void blend_rect_24(const dib_info *dst, const RECT *rc,
3961                           const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
3962 {
3963     DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
3964     BYTE *dst_ptr = get_pixel_ptr_24( dst, rc->left, rc->top );
3965     int x, y;
3966
3967     for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
3968     {
3969         for (x = 0; x < rc->right - rc->left; x++)
3970         {
3971             DWORD val = blend_rgb( dst_ptr[x * 3 + 2], dst_ptr[x * 3 + 1], dst_ptr[x * 3],
3972                                    src_ptr[x], blend );
3973             dst_ptr[x * 3]     = val;
3974             dst_ptr[x * 3 + 1] = val >> 8;
3975             dst_ptr[x * 3 + 2] = val >> 16;
3976         }
3977     }
3978 }
3979
3980 static void blend_rect_555(const dib_info *dst, const RECT *rc,
3981                            const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
3982 {
3983     DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
3984     WORD *dst_ptr = get_pixel_ptr_16( dst, rc->left, rc->top );
3985     int x, y;
3986
3987     for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 2, src_ptr += src->stride / 4)
3988     {
3989         for (x = 0; x < rc->right - rc->left; x++)
3990         {
3991             DWORD val = blend_rgb( ((dst_ptr[x] >> 7) & 0xf8) | ((dst_ptr[x] >> 12) & 0x07),
3992                                    ((dst_ptr[x] >> 2) & 0xf8) | ((dst_ptr[x] >>  7) & 0x07),
3993                                    ((dst_ptr[x] << 3) & 0xf8) | ((dst_ptr[x] >>  2) & 0x07),
3994                                    src_ptr[x], blend );
3995             dst_ptr[x] = ((val >> 9) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 3) & 0x001f);
3996         }
3997     }
3998 }
3999
4000 static void blend_rect_16(const dib_info *dst, const RECT *rc,
4001                           const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
4002 {
4003     DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
4004     WORD *dst_ptr = get_pixel_ptr_16( dst, rc->left, rc->top );
4005     int x, y;
4006
4007     for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 2, src_ptr += src->stride / 4)
4008     {
4009         for (x = 0; x < rc->right - rc->left; x++)
4010         {
4011             DWORD val = blend_rgb( get_field( dst_ptr[x], dst->red_shift, dst->red_len ),
4012                                    get_field( dst_ptr[x], dst->green_shift, dst->green_len ),
4013                                    get_field( dst_ptr[x], dst->blue_shift, dst->blue_len ),
4014                                    src_ptr[x], blend );
4015             dst_ptr[x] = (put_field((val >> 16), dst->red_shift,   dst->red_len)   |
4016                           put_field((val >>  8), dst->green_shift, dst->green_len) |
4017                           put_field( val,        dst->blue_shift,  dst->blue_len));
4018         }
4019     }
4020 }
4021
4022 static void blend_rect_8(const dib_info *dst, const RECT *rc,
4023                          const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
4024 {
4025     const RGBQUAD *color_table = get_dib_color_table( dst );
4026     DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
4027     BYTE *dst_ptr = get_pixel_ptr_8( dst, rc->left, rc->top );
4028     int x, y;
4029
4030     for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
4031     {
4032         for (x = 0; x < rc->right - rc->left; x++)
4033         {
4034             RGBQUAD rgb = color_table[dst_ptr[x]];
4035             DWORD val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[x], blend );
4036             dst_ptr[x] = rgb_lookup_colortable( dst, val >> 16, val >> 8, val );
4037         }
4038     }
4039 }
4040
4041 static void blend_rect_4(const dib_info *dst, const RECT *rc,
4042                          const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
4043 {
4044     const RGBQUAD *color_table = get_dib_color_table( dst );
4045     DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
4046     BYTE *dst_ptr = get_pixel_ptr_4( dst, rc->left, rc->top );
4047     int i, x, y;
4048
4049     for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
4050     {
4051         for (i = 0, x = (dst->rect.left + rc->left) & 1; i < rc->right - rc->left; i++, x++)
4052         {
4053             DWORD val = ((x & 1) ? dst_ptr[x / 2] : (dst_ptr[x / 2] >> 4)) & 0x0f;
4054             RGBQUAD rgb = color_table[val];
4055             val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[i], blend );
4056             val = rgb_lookup_colortable( dst, val >> 16, val >> 8, val );
4057             if (x & 1)
4058                 dst_ptr[x / 2] = val | (dst_ptr[x / 2] & 0xf0);
4059             else
4060                 dst_ptr[x / 2] = (val << 4) | (dst_ptr[x / 2] & 0x0f);
4061         }
4062     }
4063 }
4064
4065 static void blend_rect_1(const dib_info *dst, const RECT *rc,
4066                          const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
4067 {
4068     const RGBQUAD *color_table = get_dib_color_table( dst );
4069     DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
4070     BYTE *dst_ptr = get_pixel_ptr_1( dst, rc->left, rc->top );
4071     int i, x, y;
4072
4073     for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
4074     {
4075         for (i = 0, x = (dst->rect.left + rc->left) & 7; i < rc->right - rc->left; i++, x++)
4076         {
4077             DWORD val = (dst_ptr[x / 8] & pixel_masks_1[x % 8]) ? 1 : 0;
4078             RGBQUAD rgb = color_table[val];
4079             val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[i], blend );
4080             val = rgb_to_pixel_colortable(dst, val >> 16, val >> 8, val) ? 0xff : 0;
4081             dst_ptr[x / 8] = (dst_ptr[x / 8] & ~pixel_masks_1[x % 8]) | (val & pixel_masks_1[x % 8]);
4082         }
4083     }
4084 }
4085
4086 static void blend_rect_null(const dib_info *dst, const RECT *rc,
4087                             const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
4088 {
4089 }
4090
4091 static inline DWORD gradient_rgb_8888( const TRIVERTEX *v, unsigned int pos, unsigned int len )
4092 {
4093     BYTE r, g, b, a;
4094     r = (v[0].Red   * (len - pos) + v[1].Red   * pos) / len / 256;
4095     g = (v[0].Green * (len - pos) + v[1].Green * pos) / len / 256;
4096     b = (v[0].Blue  * (len - pos) + v[1].Blue  * pos) / len / 256;
4097     a = (v[0].Alpha * (len - pos) + v[1].Alpha * pos) / len / 256;
4098     return a << 24 | r << 16 | g << 8 | b;
4099 }
4100
4101 static inline DWORD gradient_rgb_24( const TRIVERTEX *v, unsigned int pos, unsigned int len )
4102 {
4103     BYTE r, g, b;
4104     r = (v[0].Red   * (len - pos) + v[1].Red   * pos) / len / 256;
4105     g = (v[0].Green * (len - pos) + v[1].Green * pos) / len / 256;
4106     b = (v[0].Blue  * (len - pos) + v[1].Blue  * pos) / len / 256;
4107     return r << 16 | g << 8 | b;
4108 }
4109
4110 static inline WORD gradient_rgb_555( const TRIVERTEX *v, unsigned int pos, unsigned int len,
4111                                      unsigned int x, unsigned int y )
4112 {
4113     int r = (v[0].Red   * (len - pos) + v[1].Red   * pos) / len / 128 + bayer_4x4[y % 4][x % 4];
4114     int g = (v[0].Green * (len - pos) + v[1].Green * pos) / len / 128 + bayer_4x4[y % 4][x % 4];
4115     int b = (v[0].Blue  * (len - pos) + v[1].Blue  * pos) / len / 128 + bayer_4x4[y % 4][x % 4];
4116     r = min( 31, max( 0, r / 16 ));
4117     g = min( 31, max( 0, g / 16 ));
4118     b = min( 31, max( 0, b / 16 ));
4119     return (r << 10) | (g << 5) | b;
4120 }
4121
4122 static inline BYTE gradient_rgb_8( const dib_info *dib, const TRIVERTEX *v,
4123                                    unsigned int pos, unsigned int len, unsigned int x, unsigned int y )
4124 {
4125     BYTE r = ((v[0].Red   * (len - pos) + v[1].Red   * pos) / len / 128 + bayer_16x16[y % 16][x % 16]) / 256;
4126     BYTE g = ((v[0].Green * (len - pos) + v[1].Green * pos) / len / 128 + bayer_16x16[y % 16][x % 16]) / 256;
4127     BYTE b = ((v[0].Blue  * (len - pos) + v[1].Blue  * pos) / len / 128 + bayer_16x16[y % 16][x % 16]) / 256;
4128     return rgb_to_pixel_colortable( dib, r * 127, g * 127, b * 127 );
4129 }
4130
4131 /* compute the left/right triangle limit for row y */
4132 static inline void triangle_coords( const TRIVERTEX *v, const RECT *rc, int y, int *left, int *right )
4133 {
4134     int x1, x2;
4135
4136     if (y < v[1].y) x1 = edge_coord( y, v[0].x, v[0].y, v[1].x, v[1].y );
4137     else x1 = edge_coord( y, v[1].x, v[1].y, v[2].x, v[2].y );
4138
4139     x2 = edge_coord( y, v[0].x, v[0].y, v[2].x, v[2].y );
4140
4141     *left  = max( rc->left, min( x1, x2 ) );
4142     *right = min( rc->right, max( x1, x2 ) );
4143 }
4144
4145 /* compute the matrix determinant for triangular barycentric coordinates (constant across the triangle) */
4146 static inline int triangle_det( const TRIVERTEX *v )
4147 {
4148     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);
4149 }
4150
4151 /* compute the barycentric weights for a given point inside the triangle */
4152 static inline void triangle_weights( const TRIVERTEX *v, int x, int y, INT64 *l1, INT64 *l2 )
4153 {
4154     *l1 = (v[1].y - v[2].y) * (x - v[2].x) - (v[1].x - v[2].x) * (y - v[2].y);
4155     *l2 = (v[2].y - v[0].y) * (x - v[2].x) - (v[2].x - v[0].x) * (y - v[2].y);
4156 }
4157
4158 static inline DWORD gradient_triangle_8888( const TRIVERTEX *v, int x, int y, int det )
4159 {
4160     INT64 l1, l2;
4161     BYTE r, g, b, a;
4162
4163     triangle_weights( v, x, y, &l1, &l2 );
4164     r = (v[0].Red   * l1 + v[1].Red   * l2 + v[2].Red   * (det - l1 - l2)) / det / 256;
4165     g = (v[0].Green * l1 + v[1].Green * l2 + v[2].Green * (det - l1 - l2)) / det / 256;
4166     b = (v[0].Blue  * l1 + v[1].Blue  * l2 + v[2].Blue  * (det - l1 - l2)) / det / 256;
4167     a = (v[0].Alpha * l1 + v[1].Alpha * l2 + v[2].Alpha * (det - l1 - l2)) / det / 256;
4168     return a << 24 | r << 16 | g << 8 | b;
4169 }
4170
4171 static inline DWORD gradient_triangle_24( const TRIVERTEX *v, int x, int y, int det )
4172 {
4173     INT64 l1, l2;
4174     BYTE r, g, b;
4175
4176     triangle_weights( v, x, y, &l1, &l2 );
4177     r = (v[0].Red   * l1 + v[1].Red   * l2 + v[2].Red   * (det - l1 - l2)) / det / 256;
4178     g = (v[0].Green * l1 + v[1].Green * l2 + v[2].Green * (det - l1 - l2)) / det / 256;
4179     b = (v[0].Blue  * l1 + v[1].Blue  * l2 + v[2].Blue  * (det - l1 - l2)) / det / 256;
4180     return r << 16 | g << 8 | b;
4181 }
4182
4183 static inline DWORD gradient_triangle_555( const TRIVERTEX *v, int x, int y, int det )
4184 {
4185     INT64 l1, l2;
4186     int r, g, b;
4187
4188     triangle_weights( v, x, y, &l1, &l2 );
4189     r = (v[0].Red   * l1 + v[1].Red   * l2 + v[2].Red   * (det - l1 - l2)) / det / 128 + bayer_4x4[y % 4][x % 4];
4190     g = (v[0].Green * l1 + v[1].Green * l2 + v[2].Green * (det - l1 - l2)) / det / 128 + bayer_4x4[y % 4][x % 4];
4191     b = (v[0].Blue  * l1 + v[1].Blue  * l2 + v[2].Blue  * (det - l1 - l2)) / det / 128 + bayer_4x4[y % 4][x % 4];
4192     r = min( 31, max( 0, r / 16 ));
4193     g = min( 31, max( 0, g / 16 ));
4194     b = min( 31, max( 0, b / 16 ));
4195     return (r << 10) | (g << 5) | b;
4196 }
4197
4198 static inline DWORD gradient_triangle_8( const dib_info *dib, const TRIVERTEX *v, int x, int y, int det )
4199 {
4200     INT64 l1, l2;
4201     BYTE r, g, b;
4202
4203     triangle_weights( v, x, y, &l1, &l2 );
4204     r = ((v[0].Red   * l1 + v[1].Red   * l2 + v[2].Red   * (det - l1 - l2)) / det / 128 + bayer_16x16[y % 16][x % 16]) / 256;
4205     g = ((v[0].Green * l1 + v[1].Green * l2 + v[2].Green * (det - l1 - l2)) / det / 128 + bayer_16x16[y % 16][x % 16]) / 256;
4206     b = ((v[0].Blue  * l1 + v[1].Blue  * l2 + v[2].Blue  * (det - l1 - l2)) / det / 128 + bayer_16x16[y % 16][x % 16]) / 256;
4207     return rgb_to_pixel_colortable( dib, r * 127, g * 127, b * 127 );
4208 }
4209
4210 static BOOL gradient_rect_8888( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4211 {
4212     DWORD *ptr = get_pixel_ptr_32( dib, rc->left, rc->top );
4213     int x, y, left, right, det;
4214
4215     switch (mode)
4216     {
4217     case GRADIENT_FILL_RECT_H:
4218         for (x = 0; x < rc->right - rc->left; x++)
4219             ptr[x] = gradient_rgb_8888( v, rc->left + x - v[0].x, v[1].x - v[0].x );
4220
4221         for (y = rc->top + 1; y < rc->bottom; y++, ptr += dib->stride / 4)
4222             memcpy( ptr + dib->stride / 4, ptr, (rc->right - rc->left) * 4 );
4223         break;
4224
4225     case GRADIENT_FILL_RECT_V:
4226         for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride / 4)
4227         {
4228             DWORD val = gradient_rgb_8888( v, y - v[0].y, v[1].y - v[0].y );
4229             for (x = 0; x < rc->right - rc->left; x++) ptr[x] = val;
4230         }
4231         break;
4232
4233     case GRADIENT_FILL_TRIANGLE:
4234         if (!(det = triangle_det( v ))) return FALSE;
4235         for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride / 4)
4236         {
4237             triangle_coords( v, rc, y, &left, &right );
4238             for (x = left; x < right; x++) ptr[x - rc->left] = gradient_triangle_8888( v, x, y, det );
4239         }
4240         break;
4241     }
4242     return TRUE;
4243 }
4244
4245 static BOOL gradient_rect_32( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4246 {
4247     DWORD *ptr = get_pixel_ptr_32( dib, rc->left, rc->top );
4248     int x, y, left, right, det;
4249
4250     switch (mode)
4251     {
4252     case GRADIENT_FILL_RECT_H:
4253         if (dib->red_len == 8 && dib->green_len == 8 && dib->blue_len == 8)
4254         {
4255             for (x = 0; x < rc->right - rc->left; x++)
4256             {
4257                 DWORD val = gradient_rgb_24( v, rc->left + x - v[0].x, v[1].x - v[0].x );
4258                 ptr[x] = ((( val        & 0xff) << dib->blue_shift) |
4259                           (((val >> 8)  & 0xff) << dib->green_shift) |
4260                           (((val >> 16) & 0xff) << dib->red_shift));
4261             }
4262         }
4263         else
4264         {
4265             for (x = 0; x < rc->right - rc->left; x++)
4266             {
4267                 DWORD val = gradient_rgb_24( v, rc->left + x - v[0].x, v[1].x - v[0].x );
4268                 ptr[x] = (put_field( val >> 16, dib->red_shift,   dib->red_len )   |
4269                           put_field( val >> 8,  dib->green_shift, dib->green_len ) |
4270                           put_field( val,       dib->blue_shift,  dib->blue_len ));
4271             }
4272         }
4273
4274         for (y = rc->top + 1; y < rc->bottom; y++, ptr += dib->stride / 4)
4275             memcpy( ptr + dib->stride / 4, ptr, (rc->right - rc->left) * 4 );
4276         break;
4277
4278     case GRADIENT_FILL_RECT_V:
4279         for (y = rc->top; y < rc->bottom; y++)
4280         {
4281             DWORD val = gradient_rgb_24( v, y - v[0].y, v[1].y - v[0].y );
4282             if (dib->red_len == 8 && dib->green_len == 8 && dib->blue_len == 8)
4283                 val = ((( val        & 0xff) << dib->blue_shift) |
4284                        (((val >> 8)  & 0xff) << dib->green_shift) |
4285                        (((val >> 16) & 0xff) << dib->red_shift));
4286             else
4287                 val = (put_field( val >> 16, dib->red_shift,   dib->red_len )   |
4288                        put_field( val >> 8,  dib->green_shift, dib->green_len ) |
4289                        put_field( val,       dib->blue_shift,  dib->blue_len ));
4290
4291             for (x = 0; x < rc->right - rc->left; x++) ptr[x] = val;
4292             ptr += dib->stride / 4;
4293         }
4294         break;
4295
4296     case GRADIENT_FILL_TRIANGLE:
4297         if (!(det = triangle_det( v ))) return FALSE;
4298         for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride / 4)
4299         {
4300             triangle_coords( v, rc, y, &left, &right );
4301
4302             if (dib->red_len == 8 && dib->green_len == 8 && dib->blue_len == 8)
4303                 for (x = left; x < right; x++)
4304                 {
4305                     DWORD val = gradient_triangle_24( v, x, y, det );
4306                     ptr[x - rc->left] = ((( val        & 0xff) << dib->blue_shift) |
4307                                          (((val >> 8)  & 0xff) << dib->green_shift) |
4308                                          (((val >> 16) & 0xff) << dib->red_shift));
4309                 }
4310             else
4311                 for (x = left; x < right; x++)
4312                 {
4313                     DWORD val = gradient_triangle_24( v, x, y, det );
4314                     ptr[x - rc->left] = (put_field( val >> 16, dib->red_shift,   dib->red_len )   |
4315                                          put_field( val >> 8,  dib->green_shift, dib->green_len ) |
4316                                          put_field( val,       dib->blue_shift,  dib->blue_len ));
4317                 }
4318         }
4319         break;
4320     }
4321     return TRUE;
4322 }
4323
4324 static BOOL gradient_rect_24( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4325 {
4326     BYTE *ptr = get_pixel_ptr_24( dib, rc->left, rc->top );
4327     int x, y, left, right, det;
4328
4329     switch (mode)
4330     {
4331     case GRADIENT_FILL_RECT_H:
4332         for (x = 0; x < rc->right - rc->left; x++)
4333         {
4334             DWORD val = gradient_rgb_24( v, rc->left + x - v[0].x, v[1].x - v[0].x );
4335             ptr[x * 3]     = val;
4336             ptr[x * 3 + 1] = val >> 8;
4337             ptr[x * 3 + 2] = val >> 16;
4338         }
4339
4340         for (y = rc->top + 1; y < rc->bottom; y++, ptr += dib->stride)
4341             memcpy( ptr + dib->stride, ptr, (rc->right - rc->left) * 3 );
4342         break;
4343
4344     case GRADIENT_FILL_RECT_V:
4345         for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride)
4346         {
4347             DWORD val = gradient_rgb_24( v, y - v[0].y, v[1].y - v[0].y );
4348             for (x = 0; x < rc->right - rc->left; x++)
4349             {
4350                 ptr[x * 3]     = val;
4351                 ptr[x * 3 + 1] = val >> 8;
4352                 ptr[x * 3 + 2] = val >> 16;
4353             }
4354         }
4355         break;
4356
4357     case GRADIENT_FILL_TRIANGLE:
4358         if (!(det = triangle_det( v ))) return FALSE;
4359         for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride)
4360         {
4361             triangle_coords( v, rc, y, &left, &right );
4362             for (x = left; x < right; x++)
4363             {
4364                 DWORD val = gradient_triangle_24( v, x, y, det );
4365                 ptr[(x - rc->left) * 3]     = val;
4366                 ptr[(x - rc->left) * 3 + 1] = val >> 8;
4367                 ptr[(x - rc->left) * 3 + 2] = val >> 16;
4368             }
4369         }
4370         break;
4371     }
4372     return TRUE;
4373 }
4374
4375 static BOOL gradient_rect_555( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4376 {
4377     WORD *ptr = get_pixel_ptr_16( dib, rc->left, rc->top );
4378     int x, y, left, right, det;
4379
4380     switch (mode)
4381     {
4382     case GRADIENT_FILL_RECT_H:
4383         for (y = rc->top; y < min( rc->top + 4, rc->bottom ); y++, ptr += dib->stride / 2)
4384             for (x = rc->left; x < rc->right; x++)
4385                 ptr[x - rc->left] = gradient_rgb_555( v, x - v[0].x, v[1].x - v[0].x, x, y );
4386         for ( ; y < rc->bottom; y++, ptr += dib->stride / 2)
4387             memcpy( ptr, ptr - dib->stride * 2, (rc->right - rc->left) * 2 );
4388         break;
4389
4390     case GRADIENT_FILL_RECT_V:
4391         for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride / 2)
4392         {
4393             WORD values[4];
4394             for (x = 0; x < 4; x++) values[x] = gradient_rgb_555( v, y - v[0].y, v[1].y - v[0].y, x, y );
4395             for (x = rc->left; x < rc->right; x++) ptr[x - rc->left] = values[x % 4];
4396         }
4397         break;
4398
4399     case GRADIENT_FILL_TRIANGLE:
4400         if (!(det = triangle_det( v ))) return FALSE;
4401         for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride / 2)
4402         {
4403             triangle_coords( v, rc, y, &left, &right );
4404             for (x = left; x < right; x++) ptr[x - rc->left] = gradient_triangle_555( v, x, y, det );
4405         }
4406         break;
4407     }
4408     return TRUE;
4409 }
4410
4411 static BOOL gradient_rect_16( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4412 {
4413     WORD *ptr = get_pixel_ptr_16( dib, rc->left, rc->top );
4414     int x, y, left, right, det;
4415
4416     switch (mode)
4417     {
4418     case GRADIENT_FILL_RECT_H:
4419         for (y = rc->top; y < min( rc->top + 4, rc->bottom ); y++, ptr += dib->stride / 2)
4420             for (x = rc->left; x < rc->right; x++)
4421             {
4422                 WORD val = gradient_rgb_555( v, x - v[0].x, v[1].x - v[0].x, x, y );
4423                 ptr[x - rc->left] = (put_field(((val >> 7) & 0xf8) | ((val >> 12) & 0x07), dib->red_shift,   dib->red_len)   |
4424                                      put_field(((val >> 2) & 0xf8) | ((val >> 7)  & 0x07), dib->green_shift, dib->green_len) |
4425                                      put_field(((val << 3) & 0xf8) | ((val >> 2)  & 0x07), dib->blue_shift,  dib->blue_len));
4426             }
4427         for ( ; y < rc->bottom; y++, ptr += dib->stride / 2)
4428             memcpy( ptr, ptr - dib->stride * 2, (rc->right - rc->left) * 2 );
4429         break;
4430
4431     case GRADIENT_FILL_RECT_V:
4432         for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride / 2)
4433         {
4434             WORD values[4];
4435             for (x = 0; x < 4; x++)
4436             {
4437                 WORD val = gradient_rgb_555( v, y - v[0].y, v[1].y - v[0].y, x, y );
4438                 values[x] = (put_field(((val >> 7) & 0xf8) | ((val >> 12) & 0x07), dib->red_shift,   dib->red_len)   |
4439                              put_field(((val >> 2) & 0xf8) | ((val >> 7)  & 0x07), dib->green_shift, dib->green_len) |
4440                              put_field(((val << 3) & 0xf8) | ((val >> 2)  & 0x07), dib->blue_shift,  dib->blue_len));
4441             }
4442             for (x = rc->left; x < rc->right; x++) ptr[x - rc->left] = values[x % 4];
4443         }
4444         break;
4445
4446     case GRADIENT_FILL_TRIANGLE:
4447         if (!(det = triangle_det( v ))) return FALSE;
4448         for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride / 2)
4449         {
4450             triangle_coords( v, rc, y, &left, &right );
4451             for (x = left; x < right; x++)
4452             {
4453                 WORD val = gradient_triangle_555( v, x, y, det );
4454                 ptr[x - rc->left] = (put_field(((val >> 7) & 0xf8) | ((val >> 12) & 0x07), dib->red_shift,   dib->red_len)   |
4455                                      put_field(((val >> 2) & 0xf8) | ((val >> 7)  & 0x07), dib->green_shift, dib->green_len) |
4456                                      put_field(((val << 3) & 0xf8) | ((val >> 2)  & 0x07), dib->blue_shift,  dib->blue_len));
4457             }
4458         }
4459         break;
4460     }
4461     return TRUE;
4462 }
4463
4464 static BOOL gradient_rect_8( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4465 {
4466     BYTE *ptr = get_pixel_ptr_8( dib, rc->left, rc->top );
4467     int x, y, left, right, det;
4468
4469     switch (mode)
4470     {
4471     case GRADIENT_FILL_RECT_H:
4472         for (y = rc->top; y < min( rc->top + 16, rc->bottom ); y++, ptr += dib->stride)
4473             for (x = rc->left; x < rc->right; x++)
4474                 ptr[x - rc->left] = gradient_rgb_8( dib, v, x - v[0].x, v[1].x - v[0].x, x, y );
4475         for ( ; y < rc->bottom; y++, ptr += dib->stride)
4476             memcpy( ptr, ptr - dib->stride * 16, rc->right - rc->left );
4477         break;
4478
4479     case GRADIENT_FILL_RECT_V:
4480         for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride)
4481         {
4482             BYTE values[16];
4483             for (x = 0; x < 16; x++)
4484                 values[x] = gradient_rgb_8( dib, v, y - v[0].y, v[1].y - v[0].y, x, y );
4485             for (x = rc->left; x < rc->right; x++) ptr[x - rc->left] = values[x % 16];
4486         }
4487         break;
4488
4489     case GRADIENT_FILL_TRIANGLE:
4490         if (!(det = triangle_det( v ))) return FALSE;
4491         for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride)
4492         {
4493             triangle_coords( v, rc, y, &left, &right );
4494             for (x = left; x < right; x++) ptr[x - rc->left] = gradient_triangle_8( dib, v, x, y, det );
4495         }
4496         break;
4497     }
4498     return TRUE;
4499 }
4500
4501 static BOOL gradient_rect_4( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4502 {
4503     BYTE *ptr = get_pixel_ptr_4( dib, rc->left, rc->top );
4504     int x, y, left, right, det, pos;
4505
4506     switch (mode)
4507     {
4508     case GRADIENT_FILL_RECT_H:
4509         for (y = rc->top; y < min( rc->top + 16, rc->bottom ); y++, ptr += dib->stride)
4510         {
4511             for (x = rc->left, pos = (dib->rect.left + rc->left) & 1; x < rc->right; x++, pos++)
4512             {
4513                 BYTE val = gradient_rgb_8( dib, v, x - v[0].x, v[1].x - v[0].x, x, y );
4514                 if (pos & 1)
4515                     ptr[pos / 2] = val | (ptr[pos / 2] & 0xf0);
4516                 else
4517                     ptr[pos / 2] = (val << 4) | (ptr[pos / 2] & 0x0f);
4518             }
4519         }
4520         for ( ; y < rc->bottom; y++, ptr += dib->stride)
4521         {
4522             x = rc->left;
4523             pos = (dib->rect.left + rc->left) & 1;
4524             if (pos)
4525             {
4526                 ptr[0] = (ptr[-16 * dib->stride] & 0x0f) | (ptr[0] & 0xf0);
4527                 pos++;
4528                 x++;
4529             }
4530             for (; x < rc->right - 1; x += 2, pos += 2) ptr[pos / 2] = ptr[pos / 2 - 16 * dib->stride];
4531             if (x < rc->right)
4532                 ptr[pos / 2] = (ptr[pos / 2] & 0x0f) | (ptr[pos / 2 - 16 * dib->stride] & 0xf0);
4533         }
4534         break;
4535
4536     case GRADIENT_FILL_RECT_V:
4537         for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride)
4538         {
4539             BYTE values[16];
4540             for (x = 0; x < 16; x++)
4541                 values[x] = gradient_rgb_8( dib, v, y - v[0].y, v[1].y - v[0].y, x, y );
4542             for (x = rc->left, pos = (dib->rect.left + rc->left) & 1; x < rc->right; x++, pos++)
4543                 if (pos & 1)
4544                     ptr[pos / 2] = values[x % 16] | (ptr[pos / 2] & 0xf0);
4545                 else
4546                     ptr[pos / 2] = (values[x % 16] << 4) | (ptr[pos / 2] & 0x0f);
4547         }
4548         break;
4549
4550     case GRADIENT_FILL_TRIANGLE:
4551         if (!(det = triangle_det( v ))) return FALSE;
4552         for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride)
4553         {
4554             triangle_coords( v, rc, y, &left, &right );
4555             for (x = left, pos = left - rc->left + ((dib->rect.left + rc->left) & 1); x < right; x++, pos++)
4556             {
4557                 BYTE val = gradient_triangle_8( dib, v, x, y, det );
4558                 if (pos & 1)
4559                     ptr[pos / 2] = val | (ptr[pos / 2] & 0xf0);
4560                 else
4561                     ptr[pos / 2] = (val << 4) | (ptr[pos / 2] & 0x0f);
4562             }
4563         }
4564         break;
4565     }
4566     return TRUE;
4567 }
4568
4569 static BOOL gradient_rect_1( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4570 {
4571     BYTE *ptr = get_pixel_ptr_1( dib, rc->left, rc->top );
4572     int x, y, left, right, det, pos;
4573
4574     switch (mode)
4575     {
4576     case GRADIENT_FILL_RECT_H:
4577         for (y = rc->top; y < min( rc->top + 16, rc->bottom ); y++, ptr += dib->stride)
4578         {
4579             for (x = rc->left, pos = (dib->rect.left + rc->left) & 7; x < rc->right; x++, pos++)
4580             {
4581                 BYTE val = gradient_rgb_8( dib, v, x - v[0].x, v[1].x - v[0].x, x, y ) ? 0xff : 0;
4582                 ptr[pos / 8] = (ptr[pos / 8] & ~pixel_masks_1[pos % 8]) | (val & pixel_masks_1[pos % 8]);
4583             }
4584         }
4585         for ( ; y < rc->bottom; y++, ptr += dib->stride)
4586             for (x = rc->left, pos = (dib->rect.left + rc->left) & 7; x < rc->right; x++, pos++)
4587                 ptr[pos / 8] = (ptr[pos / 8] & ~pixel_masks_1[pos % 8]) |
4588                                (ptr[pos / 8 - 16 * dib->stride] & pixel_masks_1[pos % 8]);
4589         break;
4590
4591     case GRADIENT_FILL_RECT_V:
4592         for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride)
4593         {
4594             BYTE values[16];
4595             for (x = 0; x < 16; x++)
4596                 values[x] = gradient_rgb_8( dib, v, y - v[0].y, v[1].y - v[0].y, x, y ) ? 0xff : 0;
4597             for (x = rc->left, pos = (dib->rect.left + rc->left) & 7; x < rc->right; x++, pos++)
4598                 ptr[pos / 8] = (ptr[pos / 8] & ~pixel_masks_1[pos % 8]) |
4599                                (values[x % 16] & pixel_masks_1[pos % 8]);
4600         }
4601         break;
4602
4603     case GRADIENT_FILL_TRIANGLE:
4604         if (!(det = triangle_det( v ))) return FALSE;
4605         for (y = rc->top; y < rc->bottom; y++, ptr += dib->stride)
4606         {
4607             triangle_coords( v, rc, y, &left, &right );
4608             for (x = left, pos = left - rc->left + ((dib->rect.left + rc->left) & 7); x < right; x++, pos++)
4609             {
4610                 BYTE val = gradient_triangle_8( dib, v, x, y, det ) ? 0xff : 0;
4611                 ptr[pos / 8] = (ptr[pos / 8] & ~pixel_masks_1[pos % 8]) | (val & pixel_masks_1[pos % 8]);
4612             }
4613         }
4614         break;
4615     }
4616     return TRUE;
4617 }
4618
4619 static BOOL gradient_rect_null( const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode )
4620 {
4621     return TRUE;
4622 }
4623
4624 static inline BYTE aa_color( BYTE dst, BYTE text, BYTE min_comp, BYTE max_comp )
4625 {
4626     if (dst == text) return dst;
4627
4628     if (dst > text)
4629     {
4630         DWORD diff = dst - text;
4631         DWORD range = max_comp - text;
4632         dst = text + (diff * range ) / (0xff - text);
4633         return dst;
4634     }
4635     else
4636     {
4637         DWORD diff = text - dst;
4638         DWORD range = text - min_comp;
4639         dst = text - (diff * range) / text;
4640         return dst;
4641     }
4642 }
4643
4644 static inline DWORD aa_rgb( BYTE r_dst, BYTE g_dst, BYTE b_dst, DWORD text, const struct intensity_range *range )
4645 {
4646     return (aa_color( b_dst, text,       range->b_min, range->b_max )      |
4647             aa_color( g_dst, text >> 8,  range->g_min, range->g_max ) << 8 |
4648             aa_color( r_dst, text >> 16, range->r_min, range->r_max ) << 16);
4649 }
4650
4651 static void draw_glyph_8888( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4652                              const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4653 {
4654     DWORD *dst_ptr = get_pixel_ptr_32( dib, rect->left, rect->top );
4655     const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
4656     int x, y;
4657
4658     for (y = rect->top; y < rect->bottom; y++)
4659     {
4660         for (x = 0; x < rect->right - rect->left; x++)
4661         {
4662             if (glyph_ptr[x] <= 1) continue;
4663             if (glyph_ptr[x] >= 16) { dst_ptr[x] = text_pixel; continue; }
4664             dst_ptr[x] = aa_rgb( dst_ptr[x] >> 16, dst_ptr[x] >> 8, dst_ptr[x], text_pixel, ranges + glyph_ptr[x] );
4665         }
4666         dst_ptr += dib->stride / 4;
4667         glyph_ptr += glyph->stride;
4668     }
4669 }
4670
4671 static void draw_glyph_32( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4672                            const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4673 {
4674     DWORD *dst_ptr = get_pixel_ptr_32( dib, rect->left, rect->top );
4675     const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
4676     int x, y;
4677     DWORD text, val;
4678
4679     text = get_field( text_pixel, dib->red_shift,   dib->red_len ) << 16 |
4680            get_field( text_pixel, dib->green_shift, dib->green_len ) << 8 |
4681            get_field( text_pixel, dib->blue_shift,  dib->blue_len );
4682
4683     for (y = rect->top; y < rect->bottom; y++)
4684     {
4685         for (x = 0; x < rect->right - rect->left; x++)
4686         {
4687             if (glyph_ptr[x] <= 1) continue;
4688             if (glyph_ptr[x] >= 16) { dst_ptr[x] = text_pixel; continue; }
4689             val = aa_rgb( get_field(dst_ptr[x], dib->red_shift,   dib->red_len),
4690                           get_field(dst_ptr[x], dib->green_shift, dib->green_len),
4691                           get_field(dst_ptr[x], dib->blue_shift,  dib->blue_len),
4692                           text, ranges + glyph_ptr[x] );
4693             dst_ptr[x] = (put_field( val >> 16, dib->red_shift,   dib->red_len )   |
4694                           put_field( val >> 8,  dib->green_shift, dib->green_len ) |
4695                           put_field( val,       dib->blue_shift,  dib->blue_len ));
4696         }
4697         dst_ptr += dib->stride / 4;
4698         glyph_ptr += glyph->stride;
4699     }
4700 }
4701
4702 static void draw_glyph_24( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4703                            const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4704 {
4705     BYTE *dst_ptr = get_pixel_ptr_24( dib, rect->left, rect->top );
4706     const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
4707     int x, y;
4708     DWORD val;
4709
4710     for (y = rect->top; y < rect->bottom; y++)
4711     {
4712         for (x = 0; x < rect->right - rect->left; x++)
4713         {
4714             if (glyph_ptr[x] <= 1) continue;
4715             if (glyph_ptr[x] >= 16)
4716                 val = text_pixel;
4717             else
4718                 val = aa_rgb( dst_ptr[x * 3 + 2], dst_ptr[x * 3 + 1], dst_ptr[x * 3],
4719                               text_pixel, ranges + glyph_ptr[x] );
4720             dst_ptr[x * 3]     = val;
4721             dst_ptr[x * 3 + 1] = val >> 8;
4722             dst_ptr[x * 3 + 2] = val >> 16;
4723         }
4724         dst_ptr += dib->stride;
4725         glyph_ptr += glyph->stride;
4726     }
4727 }
4728
4729 static void draw_glyph_555( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4730                             const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4731 {
4732     WORD *dst_ptr = get_pixel_ptr_16( dib, rect->left, rect->top );
4733     const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
4734     int x, y;
4735     DWORD text, val;
4736
4737     text = ((text_pixel << 9) & 0xf80000) | ((text_pixel << 4) & 0x070000) |
4738            ((text_pixel << 6) & 0x00f800) | ((text_pixel << 1) & 0x000700) |
4739            ((text_pixel << 3) & 0x0000f8) | ((text_pixel >> 2) & 0x000007);
4740
4741     for (y = rect->top; y < rect->bottom; y++)
4742     {
4743         for (x = 0; x < rect->right - rect->left; x++)
4744         {
4745             if (glyph_ptr[x] <= 1) continue;
4746             if (glyph_ptr[x] >= 16) { dst_ptr[x] = text_pixel; continue; }
4747             val = aa_rgb( ((dst_ptr[x] >> 7) & 0xf8) | ((dst_ptr[x] >> 12) & 0x07),
4748                           ((dst_ptr[x] >> 2) & 0xf8) | ((dst_ptr[x] >>  7) & 0x07),
4749                           ((dst_ptr[x] << 3) & 0xf8) | ((dst_ptr[x] >>  2) & 0x07),
4750                           text, ranges + glyph_ptr[x] );
4751             dst_ptr[x] = ((val >> 9) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 3) & 0x001f);
4752         }
4753         dst_ptr += dib->stride / 2;
4754         glyph_ptr += glyph->stride;
4755     }
4756 }
4757
4758 static void draw_glyph_16( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4759                            const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4760 {
4761     WORD *dst_ptr = get_pixel_ptr_16( dib, rect->left, rect->top );
4762     const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
4763     int x, y;
4764     DWORD text, val;
4765
4766     text = get_field( text_pixel, dib->red_shift,   dib->red_len ) << 16 |
4767            get_field( text_pixel, dib->green_shift, dib->green_len ) << 8 |
4768            get_field( text_pixel, dib->blue_shift,  dib->blue_len );
4769
4770     for (y = rect->top; y < rect->bottom; y++)
4771     {
4772         for (x = 0; x < rect->right - rect->left; x++)
4773         {
4774             if (glyph_ptr[x] <= 1) continue;
4775             if (glyph_ptr[x] >= 16) { dst_ptr[x] = text_pixel; continue; }
4776             val = aa_rgb( get_field(dst_ptr[x], dib->red_shift,   dib->red_len),
4777                           get_field(dst_ptr[x], dib->green_shift, dib->green_len),
4778                           get_field(dst_ptr[x], dib->blue_shift,  dib->blue_len),
4779                           text, ranges + glyph_ptr[x] );
4780             dst_ptr[x] = (put_field( val >> 16, dib->red_shift,   dib->red_len )   |
4781                           put_field( val >> 8,  dib->green_shift, dib->green_len ) |
4782                           put_field( val,       dib->blue_shift,  dib->blue_len ));
4783         }
4784         dst_ptr += dib->stride / 2;
4785         glyph_ptr += glyph->stride;
4786     }
4787 }
4788
4789 static void draw_glyph_8( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4790                           const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4791 {
4792     BYTE *dst_ptr = get_pixel_ptr_8( dib, rect->left, rect->top );
4793     const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
4794     int x, y;
4795
4796     for (y = rect->top; y < rect->bottom; y++)
4797     {
4798         for (x = 0; x < rect->right - rect->left; x++)
4799         {
4800             /* no antialiasing, glyph should only contain 0 or 16. */
4801             if (glyph_ptr[x] >= 16)
4802                 dst_ptr[x] = text_pixel;
4803         }
4804         dst_ptr += dib->stride;
4805         glyph_ptr += glyph->stride;
4806     }
4807 }
4808
4809 static void draw_glyph_4( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4810                           const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4811 {
4812     BYTE *dst_ptr = get_pixel_ptr_4( dib, rect->left, rect->top );
4813     const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
4814     int x, y, pos;
4815
4816     for (y = rect->top; y < rect->bottom; y++)
4817     {
4818         for (x = 0, pos = (dib->rect.left + rect->left) & 1; x < rect->right - rect->left; x++, pos++)
4819         {
4820             /* no antialiasing, glyph should only contain 0 or 16. */
4821             if (glyph_ptr[x] >= 16)
4822             {
4823                 if (pos & 1)
4824                     dst_ptr[pos / 2] = text_pixel | (dst_ptr[pos / 2] & 0xf0);
4825                 else
4826                     dst_ptr[pos / 2] = (text_pixel << 4) | (dst_ptr[pos / 2] & 0x0f);
4827             }
4828         }
4829         dst_ptr += dib->stride;
4830         glyph_ptr += glyph->stride;
4831     }
4832 }
4833
4834 static void draw_glyph_1( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4835                           const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4836 {
4837     BYTE *dst_ptr = get_pixel_ptr_1( dib, rect->left, rect->top );
4838     const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
4839     int x, y, pos;
4840     BYTE text = (text_pixel & 1) ? 0xff : 0;
4841
4842     for (y = rect->top; y < rect->bottom; y++)
4843     {
4844         for (x = 0, pos = (dib->rect.left + rect->left) & 7; x < rect->right - rect->left; x++, pos++)
4845         {
4846             /* no antialiasing, glyph should only contain 0 or 16. */
4847             if (glyph_ptr[x] >= 16)
4848                 dst_ptr[pos / 8] = (dst_ptr[pos / 8] & ~pixel_masks_1[pos % 8]) |
4849                                    (text & pixel_masks_1[pos % 8]);
4850         }
4851         dst_ptr += dib->stride;
4852         glyph_ptr += glyph->stride;
4853     }
4854 }
4855
4856 static void draw_glyph_null( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4857                              const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
4858 {
4859     return;
4860 }
4861
4862 static DWORD blend_subpixel( BYTE r, BYTE g, BYTE b, DWORD text, DWORD alpha )
4863 {
4864     return blend_color( r, text >> 16, (BYTE)(alpha >> 16) ) << 16 |
4865            blend_color( g, text >> 8,  (BYTE)(alpha >> 8) )  << 8  |
4866            blend_color( b, text,       (BYTE) alpha );
4867 }
4868
4869 static void draw_subpixel_glyph_8888( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4870                                       const POINT *origin, DWORD text_pixel )
4871 {
4872     DWORD *dst_ptr = get_pixel_ptr_32( dib, rect->left, rect->top );
4873     const DWORD *glyph_ptr = get_pixel_ptr_32( glyph, origin->x, origin->y );
4874     int x, y;
4875
4876     for (y = rect->top; y < rect->bottom; y++)
4877     {
4878         for (x = 0; x < rect->right - rect->left; x++)
4879         {
4880             if (glyph_ptr[x] == 0) continue;
4881             dst_ptr[x] = blend_subpixel( dst_ptr[x] >> 16, dst_ptr[x] >> 8, dst_ptr[x], text_pixel, glyph_ptr[x] );
4882         }
4883         dst_ptr += dib->stride / 4;
4884         glyph_ptr += glyph->stride / 4;
4885     }
4886 }
4887
4888 static void draw_subpixel_glyph_32( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4889                                     const POINT *origin, DWORD text_pixel )
4890 {
4891     DWORD *dst_ptr = get_pixel_ptr_32( dib, rect->left, rect->top );
4892     const DWORD *glyph_ptr = get_pixel_ptr_32( glyph, origin->x, origin->y );
4893     int x, y;
4894     DWORD text, val;
4895
4896     text = get_field( text_pixel, dib->red_shift,   dib->red_len ) << 16 |
4897            get_field( text_pixel, dib->green_shift, dib->green_len ) << 8 |
4898            get_field( text_pixel, dib->blue_shift,  dib->blue_len );
4899
4900     for (y = rect->top; y < rect->bottom; y++)
4901     {
4902         for (x = 0; x < rect->right - rect->left; x++)
4903         {
4904             if (glyph_ptr[x] == 0) continue;
4905             val = blend_subpixel( get_field(dst_ptr[x], dib->red_shift,   dib->red_len),
4906                                   get_field(dst_ptr[x], dib->green_shift, dib->green_len),
4907                                   get_field(dst_ptr[x], dib->blue_shift,  dib->blue_len),
4908                                   text, glyph_ptr[x] );
4909             dst_ptr[x] = (put_field( val >> 16, dib->red_shift,   dib->red_len )   |
4910                           put_field( val >> 8,  dib->green_shift, dib->green_len ) |
4911                           put_field( val,       dib->blue_shift,  dib->blue_len ));
4912         }
4913         dst_ptr += dib->stride / 4;
4914         glyph_ptr += glyph->stride / 4;
4915     }
4916 }
4917
4918 static void draw_subpixel_glyph_24( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4919                                     const POINT *origin, DWORD text_pixel )
4920 {
4921     BYTE *dst_ptr = get_pixel_ptr_24( dib, rect->left, rect->top );
4922     const DWORD *glyph_ptr = get_pixel_ptr_32( glyph, origin->x, origin->y );
4923     int x, y;
4924     DWORD val;
4925
4926     for (y = rect->top; y < rect->bottom; y++)
4927     {
4928         for (x = 0; x < rect->right - rect->left; x++)
4929         {
4930             if (glyph_ptr[x] == 0) continue;
4931             val = blend_subpixel( dst_ptr[x * 3 + 2], dst_ptr[x * 3 + 1], dst_ptr[x * 3],
4932                                   text_pixel, glyph_ptr[x] );
4933             dst_ptr[x * 3]     = val;
4934             dst_ptr[x * 3 + 1] = val >> 8;
4935             dst_ptr[x * 3 + 2] = val >> 16;
4936         }
4937         dst_ptr += dib->stride;
4938         glyph_ptr += glyph->stride / 4;
4939     }
4940 }
4941
4942 static void draw_subpixel_glyph_555( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4943                                      const POINT *origin, DWORD text_pixel )
4944 {
4945     WORD *dst_ptr = get_pixel_ptr_16( dib, rect->left, rect->top );
4946     const DWORD *glyph_ptr = get_pixel_ptr_32( glyph, origin->x, origin->y );
4947     int x, y;
4948     DWORD text, val;
4949
4950     text = ((text_pixel << 9) & 0xf80000) | ((text_pixel << 4) & 0x070000) |
4951            ((text_pixel << 6) & 0x00f800) | ((text_pixel << 1) & 0x000700) |
4952            ((text_pixel << 3) & 0x0000f8) | ((text_pixel >> 2) & 0x000007);
4953
4954     for (y = rect->top; y < rect->bottom; y++)
4955     {
4956         for (x = 0; x < rect->right - rect->left; x++)
4957         {
4958             if (glyph_ptr[x] == 0) continue;
4959             val = blend_subpixel( ((dst_ptr[x] >> 7) & 0xf8) | ((dst_ptr[x] >> 12) & 0x07),
4960                                   ((dst_ptr[x] >> 2) & 0xf8) | ((dst_ptr[x] >>  7) & 0x07),
4961                                   ((dst_ptr[x] << 3) & 0xf8) | ((dst_ptr[x] >>  2) & 0x07),
4962                                   text, glyph_ptr[x] );
4963             dst_ptr[x] = ((val >> 9) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 3) & 0x001f);
4964         }
4965         dst_ptr += dib->stride / 2;
4966         glyph_ptr += glyph->stride / 4;
4967     }
4968 }
4969
4970 static void draw_subpixel_glyph_16( const dib_info *dib, const RECT *rect, const dib_info *glyph,
4971                                     const POINT *origin, DWORD text_pixel )
4972 {
4973     WORD *dst_ptr = get_pixel_ptr_16( dib, rect->left, rect->top );
4974     const DWORD *glyph_ptr = get_pixel_ptr_32( glyph, origin->x, origin->y );
4975     int x, y;
4976     DWORD text, val;
4977
4978     text = get_field( text_pixel, dib->red_shift,   dib->red_len ) << 16 |
4979            get_field( text_pixel, dib->green_shift, dib->green_len ) << 8 |
4980            get_field( text_pixel, dib->blue_shift,  dib->blue_len );
4981
4982     for (y = rect->top; y < rect->bottom; y++)
4983     {
4984         for (x = 0; x < rect->right - rect->left; x++)
4985         {
4986             if (glyph_ptr[x] == 0) continue;
4987             val = blend_subpixel( get_field(dst_ptr[x], dib->red_shift,   dib->red_len),
4988                                   get_field(dst_ptr[x], dib->green_shift, dib->green_len),
4989                                   get_field(dst_ptr[x], dib->blue_shift,  dib->blue_len),
4990                                   text, glyph_ptr[x] );
4991             dst_ptr[x] = (put_field( val >> 16, dib->red_shift,   dib->red_len )   |
4992                           put_field( val >> 8,  dib->green_shift, dib->green_len ) |
4993                           put_field( val,       dib->blue_shift,  dib->blue_len ));
4994         }
4995         dst_ptr += dib->stride / 2;
4996         glyph_ptr += glyph->stride / 4;
4997     }
4998 }
4999
5000 static void draw_subpixel_glyph_null( const dib_info *dib, const RECT *rect, const dib_info *glyph,
5001                                       const POINT *origin, DWORD text_pixel )
5002 {
5003     return;
5004 }
5005
5006 static void create_rop_masks_32(const dib_info *dib, const BYTE *hatch_ptr,
5007                                 const rop_mask *fg, const rop_mask *bg, rop_mask_bits *bits)
5008 {
5009     DWORD *and_bits = bits->and, *xor_bits = bits->xor;
5010     int x, y;
5011
5012     /* masks are always 8x8 */
5013     assert( dib->width == 8 );
5014     assert( dib->height == 8 );
5015
5016     for(y = 0; y < 8; y++, hatch_ptr++)
5017     {
5018         for(x = 0; x < 8; x++)
5019         {
5020             if(*hatch_ptr & pixel_masks_1[x])
5021             {
5022                 and_bits[x] = fg->and;
5023                 xor_bits[x] = fg->xor;
5024             }
5025             else
5026             {
5027                 and_bits[x] = bg->and;
5028                 xor_bits[x] = bg->xor;
5029             }
5030         }
5031         and_bits += dib->stride / 4;
5032         xor_bits += dib->stride / 4;
5033     }
5034 }
5035
5036 static void create_rop_masks_24(const dib_info *dib, const BYTE *hatch_ptr,
5037                                 const rop_mask *fg, const rop_mask *bg, rop_mask_bits *bits)
5038 {
5039     DWORD mask_start = 0, mask_offset;
5040     BYTE *and_bits = bits->and, *xor_bits = bits->xor;
5041     int x, y;
5042
5043     /* masks are always 8x8 */
5044     assert( dib->width == 8 );
5045     assert( dib->height == 8 );
5046
5047     for(y = 0; y < 8; y++, hatch_ptr++)
5048     {
5049         mask_offset = mask_start;
5050         for(x = 0; x < 8; x++)
5051         {
5052             if(*hatch_ptr & pixel_masks_1[x])
5053             {
5054                 and_bits[mask_offset]   =  fg->and        & 0xff;
5055                 xor_bits[mask_offset++] =  fg->xor        & 0xff;
5056                 and_bits[mask_offset]   = (fg->and >>  8) & 0xff;
5057                 xor_bits[mask_offset++] = (fg->xor >>  8) & 0xff;
5058                 and_bits[mask_offset]   = (fg->and >> 16) & 0xff;
5059                 xor_bits[mask_offset++] = (fg->xor >> 16) & 0xff;
5060             }
5061             else
5062             {
5063                 and_bits[mask_offset]   =  bg->and        & 0xff;
5064                 xor_bits[mask_offset++] =  bg->xor        & 0xff;
5065                 and_bits[mask_offset]   = (bg->and >>  8) & 0xff;
5066                 xor_bits[mask_offset++] = (bg->xor >>  8) & 0xff;
5067                 and_bits[mask_offset]   = (bg->and >> 16) & 0xff;
5068                 xor_bits[mask_offset++] = (bg->xor >> 16) & 0xff;
5069             }
5070         }
5071         mask_start += dib->stride;
5072     }
5073 }
5074
5075 static void create_rop_masks_16(const dib_info *dib, const BYTE *hatch_ptr,
5076                                 const rop_mask *fg, const rop_mask *bg, rop_mask_bits *bits)
5077 {
5078     WORD *and_bits = bits->and, *xor_bits = bits->xor;
5079     int x, y;
5080
5081     /* masks are always 8x8 */
5082     assert( dib->width == 8 );
5083     assert( dib->height == 8 );
5084
5085     for(y = 0; y < 8; y++, hatch_ptr++)
5086     {
5087         for(x = 0; x < 8; x++)
5088         {
5089             if(*hatch_ptr & pixel_masks_1[x])
5090             {
5091                 and_bits[x] = fg->and;
5092                 xor_bits[x] = fg->xor;
5093             }
5094             else
5095             {
5096                 and_bits[x] = bg->and;
5097                 xor_bits[x] = bg->xor;
5098             }
5099         }
5100         and_bits += dib->stride / 2;
5101         xor_bits += dib->stride / 2;
5102     }
5103 }
5104
5105 static void create_rop_masks_8(const dib_info *dib, const BYTE *hatch_ptr,
5106                                const rop_mask *fg, const rop_mask *bg, rop_mask_bits *bits)
5107 {
5108     BYTE *and_bits = bits->and, *xor_bits = bits->xor;
5109     int x, y;
5110
5111     /* masks are always 8x8 */
5112     assert( dib->width == 8 );
5113     assert( dib->height == 8 );
5114
5115     for(y = 0; y < 8; y++, hatch_ptr++)
5116     {
5117         for(x = 0; x < 8; x++)
5118         {
5119             if(*hatch_ptr & pixel_masks_1[x])
5120             {
5121                 and_bits[x] = fg->and;
5122                 xor_bits[x] = fg->xor;
5123             }
5124             else
5125             {
5126                 and_bits[x] = bg->and;
5127                 xor_bits[x] = bg->xor;
5128             }
5129         }
5130         and_bits += dib->stride;
5131         xor_bits += dib->stride;
5132     }
5133 }
5134
5135 static void create_rop_masks_4(const dib_info *dib, const BYTE *hatch_ptr,
5136                                const rop_mask *fg, const rop_mask *bg, rop_mask_bits *bits)
5137 {
5138     DWORD mask_offset;
5139     BYTE *and_bits = bits->and, *xor_bits = bits->xor;
5140     const rop_mask *rop_mask;
5141     int x, y;
5142
5143     /* masks are always 8x8 */
5144     assert( dib->width == 8 );
5145     assert( dib->height == 8 );
5146
5147     for(y = 0; y < 8; y++, hatch_ptr++)
5148     {
5149         for(x = mask_offset = 0; x < 8; x++)
5150         {
5151             if(*hatch_ptr & pixel_masks_1[x])
5152                 rop_mask = fg;
5153             else
5154                 rop_mask = bg;
5155
5156             if(x & 1)
5157             {
5158                 and_bits[mask_offset] |= (rop_mask->and & 0x0f);
5159                 xor_bits[mask_offset] |= (rop_mask->xor & 0x0f);
5160                 mask_offset++;
5161             }
5162             else
5163             {
5164                 and_bits[mask_offset] = (rop_mask->and << 4) & 0xf0;
5165                 xor_bits[mask_offset] = (rop_mask->xor << 4) & 0xf0;
5166             }
5167         }
5168         and_bits += dib->stride;
5169         xor_bits += dib->stride;
5170     }
5171 }
5172
5173 static void create_rop_masks_1(const dib_info *dib, const BYTE *hatch_ptr,
5174                                const rop_mask *fg, const rop_mask *bg, rop_mask_bits *bits)
5175 {
5176     BYTE *and_bits = bits->and, *xor_bits = bits->xor;
5177     rop_mask rop_mask;
5178     int x, y;
5179
5180     /* masks are always 8x8 */
5181     assert( dib->width == 8 );
5182     assert( dib->height == 8 );
5183
5184     for(y = 0; y < 8; y++, hatch_ptr++)
5185     {
5186         *and_bits = *xor_bits = 0;
5187         for(x = 0; x < 8; x++)
5188         {
5189             if(*hatch_ptr & pixel_masks_1[x])
5190             {
5191                 rop_mask.and = (fg->and & 1) ? 0xff : 0;
5192                 rop_mask.xor = (fg->xor & 1) ? 0xff : 0;
5193             }
5194             else
5195             {
5196                 rop_mask.and = (bg->and & 1) ? 0xff : 0;
5197                 rop_mask.xor = (bg->xor & 1) ? 0xff : 0;
5198             }
5199             *and_bits |= (rop_mask.and & pixel_masks_1[x]);
5200             *xor_bits |= (rop_mask.xor & pixel_masks_1[x]);
5201         }
5202         and_bits += dib->stride;
5203         xor_bits += dib->stride;
5204     }
5205 }
5206
5207 static void create_rop_masks_null(const dib_info *dib, const BYTE *hatch_ptr,
5208                                   const rop_mask *fg, const rop_mask *bg, rop_mask_bits *bits)
5209 {
5210 }
5211
5212 static void create_dither_masks_8(const dib_info *dib, int rop2, COLORREF color, rop_mask_bits *bits)
5213 {
5214     /* mapping between RGB triples and the default color table */
5215     static const BYTE mapping[27] =
5216     {
5217         0,   /* 000000 -> 000000 */
5218         4,   /* 00007f -> 000080 */
5219         252, /* 0000ff -> 0000ff */
5220         2,   /* 007f00 -> 008000 */
5221         6,   /* 007f7f -> 008080 */
5222         224, /* 007fff -> 0080c0 */
5223         250, /* 00ff00 -> 00ff00 */
5224         184, /* 00ff7f -> 00e080 */
5225         254, /* 00ffff -> 00ffff */
5226         1,   /* 7f0000 -> 800000 */
5227         5,   /* 7f007f -> 800080 */
5228         196, /* 7f00ff -> 8000c0 */
5229         3,   /* 7f7f00 -> 808000 */
5230         248, /* 7f7f7f -> 808080 */
5231         228, /* 7f7fff -> 8080c0 */
5232         60,  /* 7fff00 -> 80e000 */
5233         188, /* 7fff7f -> 80e080 */
5234         244, /* 7fffff -> 80c0c0 */
5235         249, /* ff0000 -> ff0000 */
5236         135, /* ff007f -> e00080 */
5237         253, /* ff00ff -> ff00ff */
5238         39,  /* ff7f00 -> e08000 */
5239         167, /* ff7f7f -> e08080 */
5240         231, /* ff7fff -> e080c0 */
5241         251, /* ffff00 -> ffff00 */
5242         191, /* ffff7f -> e0e080 */
5243         255  /* ffffff -> ffffff */
5244     };
5245
5246     BYTE *and_bits = bits->and, *xor_bits = bits->xor;
5247     struct rop_codes codes;
5248     int x, y;
5249
5250     /* masks are always 8x8 */
5251     assert( dib->width == 8 );
5252     assert( dib->height == 8 );
5253
5254     get_rop_codes( rop2, &codes );
5255
5256     for (y = 0; y < 8; y++)
5257     {
5258         for (x = 0; x < 8; x++)
5259         {
5260             DWORD r = ((GetRValue(color) + 1) / 2 + bayer_8x8[y][x]) / 64;
5261             DWORD g = ((GetGValue(color) + 1) / 2 + bayer_8x8[y][x]) / 64;
5262             DWORD b = ((GetBValue(color) + 1) / 2 + bayer_8x8[y][x]) / 64;
5263             DWORD pixel = mapping[r * 9 + g * 3 + b];
5264             and_bits[x] = (pixel & codes.a1) ^ codes.a2;
5265             xor_bits[x] = (pixel & codes.x1) ^ codes.x2;
5266         }
5267         and_bits += dib->stride;
5268         xor_bits += dib->stride;
5269     }
5270 }
5271
5272 static void create_dither_masks_4(const dib_info *dib, int rop2, COLORREF color, rop_mask_bits *bits)
5273 {
5274     /* mapping between RGB triples and the default color table */
5275     static const BYTE mapping[27] =
5276     {
5277         0,  /* 000000 -> 000000 */
5278         4,  /* 00007f -> 000080 */
5279         12, /* 0000ff -> 0000ff */
5280         2,  /* 007f00 -> 008000 */
5281         6,  /* 007f7f -> 008080 */
5282         6,  /* 007fff -> 008080 */
5283         10, /* 00ff00 -> 00ff00 */
5284         6,  /* 00ff7f -> 008080 */
5285         14, /* 00ffff -> 00ffff */
5286         1,  /* 7f0000 -> 800000 */
5287         5,  /* 7f007f -> 800080 */
5288         5,  /* 7f00ff -> 800080 */
5289         3,  /* 7f7f00 -> 808000 */
5290         7,  /* 7f7f7f -> 808080 */
5291         8,  /* 7f7fff -> c0c0c0 */
5292         3,  /* 7fff00 -> 808000 */
5293         8,  /* 7fff7f -> c0c0c0 */
5294         8,  /* 7fffff -> c0c0c0 */
5295         9,  /* ff0000 -> ff0000 */
5296         5,  /* ff007f -> 800080 */
5297         13, /* ff00ff -> ff00ff */
5298         3,  /* ff7f00 -> 808000 */
5299         8,  /* ff7f7f -> c0c0c0 */
5300         8,  /* ff7fff -> c0c0c0 */
5301         11, /* ffff00 -> ffff00 */
5302         8,  /* ffff7f -> c0c0c0 */
5303         15  /* ffffff -> ffffff */
5304     };
5305
5306     BYTE *and_bits = bits->and, *xor_bits = bits->xor;
5307     struct rop_codes codes;
5308     int x, y;
5309
5310     /* masks are always 8x8 */
5311     assert( dib->width == 8 );
5312     assert( dib->height == 8 );
5313
5314     get_rop_codes( rop2, &codes );
5315
5316     for (y = 0; y < 8; y++)
5317     {
5318         for (x = 0; x < 8; x++)
5319         {
5320             DWORD r = ((GetRValue(color) + 1) / 2 + bayer_8x8[y][x]) / 64;
5321             DWORD g = ((GetGValue(color) + 1) / 2 + bayer_8x8[y][x]) / 64;
5322             DWORD b = ((GetBValue(color) + 1) / 2 + bayer_8x8[y][x]) / 64;
5323             DWORD pixel = mapping[r * 9 + g * 3 + b];
5324             if (x & 1)
5325             {
5326                 and_bits[x / 2] |= (pixel & codes.a1) ^ codes.a2;
5327                 xor_bits[x / 2] |= (pixel & codes.x1) ^ codes.x2;
5328             }
5329             else
5330             {
5331                 and_bits[x / 2] = ((pixel & codes.a1) ^ codes.a2) << 4;
5332                 xor_bits[x / 2] = ((pixel & codes.x1) ^ codes.x2) << 4;
5333             }
5334         }
5335         and_bits += dib->stride;
5336         xor_bits += dib->stride;
5337     }
5338 }
5339
5340 static void create_dither_masks_1(const dib_info *dib, int rop2, COLORREF color, rop_mask_bits *bits)
5341 {
5342     BYTE *and_bits = bits->and, *xor_bits = bits->xor;
5343     struct rop_codes codes;
5344     rop_mask rop_mask;
5345     int x, y, grey = (30 * GetRValue(color) + 59 * GetGValue(color) + 11 * GetBValue(color) + 200) / 400;
5346
5347     /* masks are always 8x8 */
5348     assert( dib->width == 8 );
5349     assert( dib->height == 8 );
5350
5351     get_rop_codes( rop2, &codes );
5352
5353     for (y = 0; y < 8; y++)
5354     {
5355         *and_bits = *xor_bits = 0;
5356         for (x = 0; x < 8; x++)
5357         {
5358             if (grey + bayer_8x8[y][x] > 63)
5359             {
5360                 rop_mask.and = (0xff & codes.a1) ^ codes.a2;
5361                 rop_mask.xor = (0xff & codes.x1) ^ codes.x2;
5362             }
5363             else
5364             {
5365                 rop_mask.and = (0x00 & codes.a1) ^ codes.a2;
5366                 rop_mask.xor = (0x00 & codes.x1) ^ codes.x2;
5367             }
5368             *and_bits |= (rop_mask.and & pixel_masks_1[x]);
5369             *xor_bits |= (rop_mask.xor & pixel_masks_1[x]);
5370         }
5371         and_bits += dib->stride;
5372         xor_bits += dib->stride;
5373     }
5374 }
5375
5376 static void create_dither_masks_null(const dib_info *dib, int rop2, COLORREF color, rop_mask_bits *bits)
5377 {
5378 }
5379
5380 static inline void rop_codes_from_stretch_mode( int mode, struct rop_codes *codes )
5381 {
5382     switch (mode)
5383     {
5384     default:
5385     case STRETCH_DELETESCANS:
5386         get_rop_codes( R2_COPYPEN, codes );
5387         break;
5388     case STRETCH_ORSCANS:
5389         get_rop_codes( R2_MERGEPEN, codes );
5390         break;
5391     case STRETCH_ANDSCANS:
5392         get_rop_codes( R2_MASKPEN, codes );
5393         break;
5394     }
5395     return;
5396 }
5397
5398 static void stretch_row_32(const dib_info *dst_dib, const POINT *dst_start,
5399                            const dib_info *src_dib, const POINT *src_start,
5400                            const struct stretch_params *params, int mode,
5401                            BOOL keep_dst)
5402 {
5403     DWORD *dst_ptr = get_pixel_ptr_32( dst_dib, dst_start->x, dst_start->y );
5404     DWORD *src_ptr = get_pixel_ptr_32( src_dib, src_start->x, src_start->y );
5405     int err = params->err_start;
5406     int width;
5407     struct rop_codes codes;
5408
5409     rop_codes_from_stretch_mode( mode, &codes );
5410     for (width = params->length; width; width--)
5411     {
5412         do_rop_codes_32( dst_ptr, *src_ptr, &codes );
5413         dst_ptr += params->dst_inc;
5414         if (err > 0)
5415         {
5416             src_ptr += params->src_inc;
5417             err += params->err_add_1;
5418         }
5419         else err += params->err_add_2;
5420     }
5421 }
5422
5423 static void stretch_row_24(const dib_info *dst_dib, const POINT *dst_start,
5424                            const dib_info *src_dib, const POINT *src_start,
5425                            const struct stretch_params *params, int mode,
5426                            BOOL keep_dst)
5427 {
5428     BYTE *dst_ptr = get_pixel_ptr_24( dst_dib, dst_start->x, dst_start->y );
5429     BYTE *src_ptr = get_pixel_ptr_24( src_dib, src_start->x, src_start->y );
5430     int err = params->err_start;
5431     int width;
5432     struct rop_codes codes;
5433
5434     rop_codes_from_stretch_mode( mode, &codes );
5435     for (width = params->length; width; width--)
5436     {
5437         do_rop_codes_8( dst_ptr,     *src_ptr,       &codes );
5438         do_rop_codes_8( dst_ptr + 1, *(src_ptr + 1), &codes );
5439         do_rop_codes_8( dst_ptr + 2, *(src_ptr + 2), &codes );
5440         dst_ptr += 3 * params->dst_inc;
5441         if (err > 0)
5442         {
5443             src_ptr += 3 * params->src_inc;
5444             err += params->err_add_1;
5445         }
5446         else err += params->err_add_2;
5447     }
5448 }
5449
5450 static void stretch_row_16(const dib_info *dst_dib, const POINT *dst_start,
5451                            const dib_info *src_dib, const POINT *src_start,
5452                            const struct stretch_params *params, int mode,
5453                            BOOL keep_dst)
5454 {
5455     WORD *dst_ptr = get_pixel_ptr_16( dst_dib, dst_start->x, dst_start->y );
5456     WORD *src_ptr = get_pixel_ptr_16( src_dib, src_start->x, src_start->y );
5457     int err = params->err_start;
5458     int width;
5459     struct rop_codes codes;
5460
5461     rop_codes_from_stretch_mode( mode, &codes );
5462     for (width = params->length; width; width--)
5463     {
5464         do_rop_codes_16( dst_ptr, *src_ptr, &codes );
5465         dst_ptr += params->dst_inc;
5466         if (err > 0)
5467         {
5468             src_ptr += params->src_inc;
5469             err += params->err_add_1;
5470         }
5471         else err += params->err_add_2;
5472     }
5473 }
5474
5475 static void stretch_row_8(const dib_info *dst_dib, const POINT *dst_start,
5476                           const dib_info *src_dib, const POINT *src_start,
5477                           const struct stretch_params *params, int mode,
5478                           BOOL keep_dst)
5479 {
5480     BYTE *dst_ptr = get_pixel_ptr_8( dst_dib, dst_start->x, dst_start->y );
5481     BYTE *src_ptr = get_pixel_ptr_8( src_dib, src_start->x, src_start->y );
5482     int err = params->err_start;
5483     int width;
5484     struct rop_codes codes;
5485
5486     rop_codes_from_stretch_mode( mode, &codes );
5487     for (width = params->length; width; width--)
5488     {
5489         do_rop_codes_8( dst_ptr, *src_ptr, &codes );
5490         dst_ptr += params->dst_inc;
5491         if (err > 0)
5492         {
5493             src_ptr += params->src_inc;
5494             err += params->err_add_1;
5495         }
5496         else err += params->err_add_2;
5497     }
5498 }
5499
5500 static void stretch_row_4(const dib_info *dst_dib, const POINT *dst_start,
5501                           const dib_info *src_dib, const POINT *src_start,
5502                           const struct stretch_params *params, int mode,
5503                           BOOL keep_dst)
5504 {
5505     BYTE *dst_ptr = get_pixel_ptr_4( dst_dib, dst_start->x, dst_start->y );
5506     BYTE *src_ptr = get_pixel_ptr_4( src_dib, src_start->x, src_start->y );
5507     int err = params->err_start;
5508     int width, dst_x = dst_dib->rect.left + dst_start->x, src_x = src_dib->rect.left + src_start->x;
5509     struct rop_codes codes;
5510     BYTE src_val;
5511
5512     rop_codes_from_stretch_mode( mode, &codes );
5513     for (width = params->length; width; width--)
5514     {
5515         if (src_x & 1) src_val = (*src_ptr & 0x0f) | (*src_ptr << 4);
5516         else src_val = (*src_ptr & 0xf0) | (*src_ptr >> 4);
5517
5518         do_rop_codes_mask_8( dst_ptr, src_val, &codes, (dst_x & 1) ? 0x0f : 0xf0 );
5519
5520         if ((dst_x & ~1) != ((dst_x + params->dst_inc) & ~1))
5521             dst_ptr += params->dst_inc;
5522         dst_x += params->dst_inc;
5523
5524         if (err > 0)
5525         {
5526             if ((src_x & ~1) != ((src_x + params->src_inc) & ~1))
5527                 src_ptr += params->src_inc;
5528             src_x += params->src_inc;
5529             err += params->err_add_1;
5530         }
5531         else err += params->err_add_2;
5532     }
5533 }
5534
5535 static void stretch_row_1(const dib_info *dst_dib, const POINT *dst_start,
5536                           const dib_info *src_dib, const POINT *src_start,
5537                           const struct stretch_params *params, int mode,
5538                           BOOL keep_dst)
5539 {
5540     BYTE *dst_ptr = get_pixel_ptr_1( dst_dib, dst_start->x, dst_start->y );
5541     BYTE *src_ptr = get_pixel_ptr_1( src_dib, src_start->x, src_start->y );
5542     int err = params->err_start;
5543     int width, dst_x = dst_dib->rect.left + dst_start->x, src_x = src_dib->rect.left + src_start->x;
5544     struct rop_codes codes;
5545     BYTE src_val;
5546
5547     rop_codes_from_stretch_mode( mode, &codes );
5548     for (width = params->length; width; width--)
5549     {
5550         src_val = *src_ptr & pixel_masks_1[src_x % 8] ? 0xff : 0;
5551         do_rop_codes_mask_8( dst_ptr, src_val, &codes, pixel_masks_1[dst_x % 8] );
5552
5553         if ((dst_x & ~7) != ((dst_x + params->dst_inc) & ~7))
5554             dst_ptr += params->dst_inc;
5555         dst_x += params->dst_inc;
5556
5557         if (err > 0)
5558         {
5559             if ((src_x & ~7) != ((src_x + params->src_inc) & ~7))
5560                 src_ptr += params->src_inc;
5561             src_x += params->src_inc;
5562             err += params->err_add_1;
5563         }
5564         else err += params->err_add_2;
5565     }
5566 }
5567
5568 static void stretch_row_null(const dib_info *dst_dib, const POINT *dst_start,
5569                              const dib_info *src_dib, const POINT *src_start,
5570                              const struct stretch_params *params, int mode,
5571                              BOOL keep_dst)
5572 {
5573     FIXME("bit count %d\n", dst_dib->bit_count);
5574     return;
5575 }
5576
5577 static void shrink_row_32(const dib_info *dst_dib, const POINT *dst_start,
5578                           const dib_info *src_dib, const POINT *src_start,
5579                           const struct stretch_params *params, int mode,
5580                           BOOL keep_dst)
5581 {
5582     DWORD *dst_ptr = get_pixel_ptr_32( dst_dib, dst_start->x, dst_start->y );
5583     DWORD *src_ptr = get_pixel_ptr_32( src_dib, src_start->x, src_start->y );
5584     int err = params->err_start;
5585     int width;
5586     struct rop_codes codes;
5587     DWORD init_val = (mode == STRETCH_ANDSCANS) ? ~0u : 0u;
5588     BOOL new_pix = TRUE;
5589
5590     rop_codes_from_stretch_mode( mode, &codes );
5591     for (width = params->length; width; width--)
5592     {
5593         if (new_pix && !keep_dst) *dst_ptr = init_val;
5594         do_rop_codes_32( dst_ptr, *src_ptr, &codes );
5595         new_pix = FALSE;
5596         src_ptr += params->src_inc;
5597         if (err > 0)
5598         {
5599             dst_ptr += params->dst_inc;
5600             new_pix = TRUE;
5601             err += params->err_add_1;
5602         }
5603         else err += params->err_add_2;
5604     }
5605 }
5606
5607 static void shrink_row_24(const dib_info *dst_dib, const POINT *dst_start,
5608                           const dib_info *src_dib, const POINT *src_start,
5609                           const struct stretch_params *params, int mode,
5610                           BOOL keep_dst)
5611 {
5612     BYTE *dst_ptr = get_pixel_ptr_24( dst_dib, dst_start->x, dst_start->y );
5613     BYTE *src_ptr = get_pixel_ptr_24( src_dib, src_start->x, src_start->y );
5614     int err = params->err_start;
5615     int width;
5616     struct rop_codes codes;
5617     BYTE init_val = (mode == STRETCH_ANDSCANS) ? ~0u : 0u;
5618     BOOL new_pix = TRUE;
5619
5620     rop_codes_from_stretch_mode( mode, &codes );
5621     for (width = params->length; width; width--)
5622     {
5623         if (new_pix && !keep_dst) memset( dst_ptr, init_val, 3 );
5624         do_rop_codes_8( dst_ptr,      *src_ptr,      &codes );
5625         do_rop_codes_8( dst_ptr + 1, *(src_ptr + 1), &codes );
5626         do_rop_codes_8( dst_ptr + 2, *(src_ptr + 2), &codes );
5627         new_pix = FALSE;
5628         src_ptr += 3 * params->src_inc;
5629         if (err > 0)
5630         {
5631             dst_ptr += 3 * params->dst_inc;
5632             new_pix = TRUE;
5633             err += params->err_add_1;
5634         }
5635         else err += params->err_add_2;
5636     }
5637 }
5638
5639 static void shrink_row_16(const dib_info *dst_dib, const POINT *dst_start,
5640                           const dib_info *src_dib, const POINT *src_start,
5641                           const struct stretch_params *params, int mode,
5642                           BOOL keep_dst)
5643 {
5644     WORD *dst_ptr = get_pixel_ptr_16( dst_dib, dst_start->x, dst_start->y );
5645     WORD *src_ptr = get_pixel_ptr_16( src_dib, src_start->x, src_start->y );
5646     int err = params->err_start;
5647     int width;
5648     struct rop_codes codes;
5649     WORD init_val = (mode == STRETCH_ANDSCANS) ? ~0u : 0u;
5650     BOOL new_pix = TRUE;
5651
5652     rop_codes_from_stretch_mode( mode, &codes );
5653     for (width = params->length; width; width--)
5654     {
5655         if (new_pix && !keep_dst) *dst_ptr = init_val;
5656         do_rop_codes_16( dst_ptr, *src_ptr, &codes );
5657         new_pix = FALSE;
5658         src_ptr += params->src_inc;
5659         if (err > 0)
5660         {
5661             dst_ptr += params->dst_inc;
5662             new_pix = TRUE;
5663             err += params->err_add_1;
5664         }
5665         else err += params->err_add_2;
5666     }
5667 }
5668
5669 static void shrink_row_8(const dib_info *dst_dib, const POINT *dst_start,
5670                          const dib_info *src_dib, const POINT *src_start,
5671                          const struct stretch_params *params, int mode,
5672                          BOOL keep_dst)
5673 {
5674     BYTE *dst_ptr = get_pixel_ptr_8( dst_dib, dst_start->x, dst_start->y );
5675     BYTE *src_ptr = get_pixel_ptr_8( src_dib, src_start->x, src_start->y );
5676     int err = params->err_start;
5677     int width;
5678     struct rop_codes codes;
5679     BYTE init_val = (mode == STRETCH_ANDSCANS) ? ~0u : 0u;
5680     BOOL new_pix = TRUE;
5681
5682     rop_codes_from_stretch_mode( mode, &codes );
5683     for (width = params->length; width; width--)
5684     {
5685         if (new_pix && !keep_dst) *dst_ptr = init_val;
5686         do_rop_codes_8( dst_ptr, *src_ptr, &codes );
5687         new_pix = FALSE;
5688         src_ptr += params->src_inc;
5689         if (err > 0)
5690         {
5691             dst_ptr += params->dst_inc;
5692             new_pix = TRUE;
5693             err += params->err_add_1;
5694         }
5695         else err += params->err_add_2;
5696     }
5697 }
5698
5699 static void shrink_row_4(const dib_info *dst_dib, const POINT *dst_start,
5700                          const dib_info *src_dib, const POINT *src_start,
5701                          const struct stretch_params *params, int mode,
5702                          BOOL keep_dst)
5703 {
5704     BYTE *dst_ptr = get_pixel_ptr_4( dst_dib, dst_start->x, dst_start->y );
5705     BYTE *src_ptr = get_pixel_ptr_4( src_dib, src_start->x, src_start->y );
5706     int err = params->err_start;
5707     int width, dst_x = dst_dib->rect.left + dst_start->x, src_x = src_dib->rect.left + src_start->x;
5708     struct rop_codes codes;
5709     BYTE src_val, init_val = (mode == STRETCH_ANDSCANS) ? ~0u : 0u;
5710     BOOL new_pix = TRUE;
5711
5712     rop_codes_from_stretch_mode( mode, &codes );
5713     for (width = params->length; width; width--)
5714     {
5715         if (new_pix && !keep_dst) do_rop_mask_8( dst_ptr, 0, init_val, (dst_x & 1) ? 0x0f : 0xf0 );
5716
5717         if (src_x & 1) src_val = (*src_ptr & 0x0f) | (*src_ptr << 4);
5718         else src_val = (*src_ptr & 0xf0) | (*src_ptr >> 4);
5719
5720         do_rop_codes_mask_8( dst_ptr, src_val, &codes, (dst_x & 1) ? 0x0f : 0xf0 );
5721         new_pix = FALSE;
5722
5723         if ((src_x & ~1) != ((src_x + params->src_inc) & ~1))
5724             src_ptr += params->src_inc;
5725         src_x += params->src_inc;
5726
5727         if (err > 0)
5728         {
5729             if ((dst_x & ~1) != ((dst_x + params->dst_inc) & ~1))
5730                 dst_ptr += params->dst_inc;
5731             dst_x += params->dst_inc;
5732             new_pix = TRUE;
5733             err += params->err_add_1;
5734         }
5735         else err += params->err_add_2;
5736     }
5737 }
5738
5739 static void shrink_row_1(const dib_info *dst_dib, const POINT *dst_start,
5740                          const dib_info *src_dib, const POINT *src_start,
5741                          const struct stretch_params *params, int mode,
5742                          BOOL keep_dst)
5743 {
5744     BYTE *dst_ptr = get_pixel_ptr_1( dst_dib, dst_start->x, dst_start->y );
5745     BYTE *src_ptr = get_pixel_ptr_1( src_dib, src_start->x, src_start->y );
5746     int err = params->err_start;
5747     int width, dst_x = dst_dib->rect.left + dst_start->x, src_x = src_dib->rect.left + src_start->x;
5748     struct rop_codes codes;
5749     BYTE src_val, init_val = (mode == STRETCH_ANDSCANS) ? ~0u : 0u;
5750     BOOL new_pix = TRUE;
5751
5752     rop_codes_from_stretch_mode( mode, &codes );
5753     for (width = params->length; width; width--)
5754     {
5755         if (new_pix && !keep_dst) do_rop_mask_8( dst_ptr, 0, init_val, pixel_masks_1[dst_x % 8] );
5756         src_val = *src_ptr & pixel_masks_1[src_x % 8] ? 0xff : 0;
5757         do_rop_codes_mask_8( dst_ptr, src_val, &codes, pixel_masks_1[dst_x % 8] );
5758         new_pix = FALSE;
5759
5760         if ((src_x & ~7) != ((src_x + params->src_inc) & ~7))
5761             src_ptr += params->src_inc;
5762         src_x += params->src_inc;
5763
5764         if (err > 0)
5765         {
5766             if ((dst_x & ~7) != ((dst_x + params->dst_inc) & ~7))
5767                 dst_ptr += params->dst_inc;
5768             dst_x += params->dst_inc;
5769             new_pix = TRUE;
5770             err += params->err_add_1;
5771         }
5772         else err += params->err_add_2;
5773     }
5774 }
5775
5776 static void shrink_row_null(const dib_info *dst_dib, const POINT *dst_start,
5777                             const dib_info *src_dib, const POINT *src_start,
5778                             const struct stretch_params *params, int mode,
5779                             BOOL keep_dst)
5780 {
5781     FIXME("bit count %d\n", dst_dib->bit_count);
5782     return;
5783 }
5784
5785 const primitive_funcs funcs_8888 =
5786 {
5787     solid_rects_32,
5788     solid_line_32,
5789     pattern_rects_32,
5790     copy_rect_32,
5791     blend_rect_8888,
5792     gradient_rect_8888,
5793     draw_glyph_8888,
5794     draw_subpixel_glyph_8888,
5795     get_pixel_32,
5796     colorref_to_pixel_888,
5797     pixel_to_colorref_888,
5798     convert_to_8888,
5799     create_rop_masks_32,
5800     create_dither_masks_null,
5801     stretch_row_32,
5802     shrink_row_32
5803 };
5804
5805 const primitive_funcs funcs_32 =
5806 {
5807     solid_rects_32,
5808     solid_line_32,
5809     pattern_rects_32,
5810     copy_rect_32,
5811     blend_rect_32,
5812     gradient_rect_32,
5813     draw_glyph_32,
5814     draw_subpixel_glyph_32,
5815     get_pixel_32,
5816     colorref_to_pixel_masks,
5817     pixel_to_colorref_masks,
5818     convert_to_32,
5819     create_rop_masks_32,
5820     create_dither_masks_null,
5821     stretch_row_32,
5822     shrink_row_32
5823 };
5824
5825 const primitive_funcs funcs_24 =
5826 {
5827     solid_rects_24,
5828     solid_line_24,
5829     pattern_rects_24,
5830     copy_rect_24,
5831     blend_rect_24,
5832     gradient_rect_24,
5833     draw_glyph_24,
5834     draw_subpixel_glyph_24,
5835     get_pixel_24,
5836     colorref_to_pixel_888,
5837     pixel_to_colorref_888,
5838     convert_to_24,
5839     create_rop_masks_24,
5840     create_dither_masks_null,
5841     stretch_row_24,
5842     shrink_row_24
5843 };
5844
5845 const primitive_funcs funcs_555 =
5846 {
5847     solid_rects_16,
5848     solid_line_16,
5849     pattern_rects_16,
5850     copy_rect_16,
5851     blend_rect_555,
5852     gradient_rect_555,
5853     draw_glyph_555,
5854     draw_subpixel_glyph_555,
5855     get_pixel_16,
5856     colorref_to_pixel_555,
5857     pixel_to_colorref_555,
5858     convert_to_555,
5859     create_rop_masks_16,
5860     create_dither_masks_null,
5861     stretch_row_16,
5862     shrink_row_16
5863 };
5864
5865 const primitive_funcs funcs_16 =
5866 {
5867     solid_rects_16,
5868     solid_line_16,
5869     pattern_rects_16,
5870     copy_rect_16,
5871     blend_rect_16,
5872     gradient_rect_16,
5873     draw_glyph_16,
5874     draw_subpixel_glyph_16,
5875     get_pixel_16,
5876     colorref_to_pixel_masks,
5877     pixel_to_colorref_masks,
5878     convert_to_16,
5879     create_rop_masks_16,
5880     create_dither_masks_null,
5881     stretch_row_16,
5882     shrink_row_16
5883 };
5884
5885 const primitive_funcs funcs_8 =
5886 {
5887     solid_rects_8,
5888     solid_line_8,
5889     pattern_rects_8,
5890     copy_rect_8,
5891     blend_rect_8,
5892     gradient_rect_8,
5893     draw_glyph_8,
5894     draw_subpixel_glyph_null,
5895     get_pixel_8,
5896     colorref_to_pixel_colortable,
5897     pixel_to_colorref_colortable,
5898     convert_to_8,
5899     create_rop_masks_8,
5900     create_dither_masks_8,
5901     stretch_row_8,
5902     shrink_row_8
5903 };
5904
5905 const primitive_funcs funcs_4 =
5906 {
5907     solid_rects_4,
5908     solid_line_4,
5909     pattern_rects_4,
5910     copy_rect_4,
5911     blend_rect_4,
5912     gradient_rect_4,
5913     draw_glyph_4,
5914     draw_subpixel_glyph_null,
5915     get_pixel_4,
5916     colorref_to_pixel_colortable,
5917     pixel_to_colorref_colortable,
5918     convert_to_4,
5919     create_rop_masks_4,
5920     create_dither_masks_4,
5921     stretch_row_4,
5922     shrink_row_4
5923 };
5924
5925 const primitive_funcs funcs_1 =
5926 {
5927     solid_rects_1,
5928     solid_line_1,
5929     pattern_rects_1,
5930     copy_rect_1,
5931     blend_rect_1,
5932     gradient_rect_1,
5933     draw_glyph_1,
5934     draw_subpixel_glyph_null,
5935     get_pixel_1,
5936     colorref_to_pixel_colortable,
5937     pixel_to_colorref_colortable,
5938     convert_to_1,
5939     create_rop_masks_1,
5940     create_dither_masks_1,
5941     stretch_row_1,
5942     shrink_row_1
5943 };
5944
5945 const primitive_funcs funcs_null =
5946 {
5947     solid_rects_null,
5948     solid_line_null,
5949     pattern_rects_null,
5950     copy_rect_null,
5951     blend_rect_null,
5952     gradient_rect_null,
5953     draw_glyph_null,
5954     draw_subpixel_glyph_null,
5955     get_pixel_null,
5956     colorref_to_pixel_null,
5957     pixel_to_colorref_null,
5958     convert_to_null,
5959     create_rop_masks_null,
5960     create_dither_masks_null,
5961     stretch_row_null,
5962     shrink_row_null
5963 };