Release 941227
[wine] / objects / dib.c
1 /*
2  * GDI device-independent bitmaps
3  *
4  * Copyright 1993,1994  Alexandre Julliard
5  */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <X11/Xlib.h>
10 #include <X11/Xutil.h>
11 #include "dc.h"
12 #include "gdi.h"
13 #include "bitmap.h"
14 #include "icon.h"
15 #include "stddebug.h"
16 #include "color.h"
17 #include "debug.h"
18
19
20 /***********************************************************************
21  *           DIB_GetImageWidthBytes
22  *
23  * Return the width of an X image in bytes
24  */
25 int DIB_GetImageWidthBytes( int width, int depth )
26 {
27     int words;
28
29     switch(depth)
30     {
31     case 1:  words = (width + 31) / 32; break;
32     case 4:  words = (width + 7) / 8; break;
33     case 8:  words = (width + 3) / 4; break;
34     case 15:
35     case 16: words = (width + 1) / 2; break;
36     case 24: words = width; break;
37     default:
38         fprintf(stderr, "DIB: unsupported depth %d.\n", depth );
39         exit(1);
40     }
41     return 4 * words;
42 }
43
44
45 /***********************************************************************
46  *           DIB_BitmapInfoSize
47  *
48  * Return the size of the bitmap info structure.
49  */
50 int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse )
51 {
52     int size = info->bmiHeader.biClrUsed;
53     if (!size && (info->bmiHeader.biBitCount != 24))
54         size = 1 << info->bmiHeader.biBitCount;
55     if (coloruse == DIB_RGB_COLORS) 
56         size = info->bmiHeader.biSize + size * sizeof(RGBQUAD);
57     else
58         size = info->bmiHeader.biSize + size * sizeof(WORD);
59     return size;
60 }
61
62
63 /***********************************************************************
64  *           DIB_DIBmpToImage
65  *
66  * Create an XImage pointing to the bitmap data.
67  */
68 static XImage *DIB_DIBmpToImage( BITMAPINFOHEADER * bmp, void * bmpData )
69 {
70     extern void _XInitImageFuncPtrs( XImage* );
71     XImage * image;
72
73     image = XCreateImage(display, DefaultVisualOfScreen( screen ),
74                          bmp->biBitCount, ZPixmap, 0, bmpData,
75                          bmp->biWidth, bmp->biHeight, 32,
76                          DIB_GetImageWidthBytes(bmp->biWidth,bmp->biBitCount));
77     if (!image) return 0;
78     image->byte_order = MSBFirst;
79     image->bitmap_bit_order = MSBFirst;
80     image->bitmap_unit = 16;
81     _XInitImageFuncPtrs(image);
82     return image;
83 }
84
85
86 /***********************************************************************
87  *           DIB_SetImageBits_1
88  *
89  * SetDIBits for a 1-bit deep DIB.
90  */
91 static void DIB_SetImageBits_1( WORD lines, BYTE *bits, WORD width,
92                                 int *colors, XImage *bmpImage )
93 {
94     WORD i, x;
95     BYTE pad, pix;
96
97     if (!(width & 31)) pad = 0;
98     else pad = ((32 - (width & 31)) + 7) / 8;
99
100     while (lines--)
101     {
102         for (i = width/8, x = 0; (i > 0); i--)
103         {
104             pix = *bits++;
105             XPutPixel( bmpImage, x++, lines, colors[pix >> 7] );
106             XPutPixel( bmpImage, x++, lines, colors[(pix >> 6) & 1] );
107             XPutPixel( bmpImage, x++, lines, colors[(pix >> 5) & 1] );
108             XPutPixel( bmpImage, x++, lines, colors[(pix >> 4) & 1] );
109             XPutPixel( bmpImage, x++, lines, colors[(pix >> 3) & 1] );
110             XPutPixel( bmpImage, x++, lines, colors[(pix >> 2) & 1] );
111             XPutPixel( bmpImage, x++, lines, colors[(pix >> 1) & 1] );
112             XPutPixel( bmpImage, x++, lines, colors[pix & 1] );
113         }
114         pix = *bits;
115         switch(width & 7)
116         {
117         case 7: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
118         case 6: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
119         case 5: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
120         case 4: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
121         case 3: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
122         case 2: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
123         case 1: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] );
124         }
125         bits += pad;
126     }
127 }
128
129
130 /***********************************************************************
131  *           DIB_SetImageBits_4
132  *
133  * SetDIBits for a 4-bit deep DIB.
134  */
135 static void DIB_SetImageBits_4( WORD lines, BYTE *bits, WORD width,
136                                 int *colors, XImage *bmpImage )
137 {
138     WORD i, x;
139     BYTE pad;
140
141     if (!(width & 7)) pad = 0;
142     else pad = ((8 - (width & 7)) + 1) / 2;
143
144     while (lines--)
145     {
146         for (i = width/2, x = 0; i > 0; i--)
147         {
148             BYTE pix = *bits++;
149             XPutPixel( bmpImage, x++, lines, colors[pix >> 4] );
150             XPutPixel( bmpImage, x++, lines, colors[pix & 0x0f] );
151         }
152         if (width & 1) XPutPixel( bmpImage, x, lines, colors[*bits >> 4] );
153         bits += pad;
154     }
155 }
156
157 #define check_xy(x,y) \
158         if (x > width) { \
159                 x = 0; \
160                 if (lines) \
161                         lines--; \
162         }
163
164 /***********************************************************************
165  *           DIB_SetImageBits_RLE4
166  *
167  * SetDIBits for a 4-bit deep compressed DIB.
168  */
169 static void DIB_SetImageBits_RLE4( WORD lines, BYTE *bits, WORD width,
170                                    int *colors, XImage *bmpImage )
171 {
172         int x = 0, c, length;
173         BYTE *begin = bits;
174         
175         lines--;
176         while (1) {
177                 length = *bits++;
178                 if (length) {   /* encoded */
179                         c = *bits++;
180                         while (length--) {
181                                 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
182                                 check_xy(x, y);
183                                 if (length) {
184                                         length--;
185                                         XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
186                                         check_xy(x, y);
187                                 }
188                         }
189                 } else {
190                         length = *bits++;
191                         switch (length) {
192                                 case 0: /* eol */
193                                         x = 0;
194                                         lines--;
195                                         continue;
196
197                                 case 1: /* eopicture */
198                                         return;
199
200                                 case 2: /* delta */
201                                         x += *bits++;
202                                         lines -= *bits++;
203                                         continue;
204
205                                 default: /* absolute */
206                                         while (length--) {
207                                                 c = *bits++;
208                                                 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
209                                                 check_xy(x, y);
210                                                 if (length) {
211                                                         length--;
212                                                         XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
213                                                         check_xy(x, y);
214                                                 }
215                                         }
216                                         if ((bits - begin) & 1)
217                                                 bits++;
218                         }
219                 }
220         }
221 }
222
223 /***********************************************************************
224  *           DIB_SetImageBits_8
225  *
226  * SetDIBits for an 8-bit deep DIB.
227  */
228 static void DIB_SetImageBits_8( WORD lines, BYTE *bits, WORD width,
229                                 int *colors, XImage *bmpImage )
230 {
231     WORD x;
232     BYTE pad = (4 - (width & 3)) & 3;
233
234     while (lines--)
235     {
236         for (x = 0; x < width; x++)
237             XPutPixel( bmpImage, x, lines, colors[*bits++] );
238         bits += pad;
239     }
240 }
241
242 /***********************************************************************
243  *            DIB_SetImageBits_RLE8
244  *
245  * SetDIBits for an 8-bit deep compressed DIB.
246  *
247  * This function rewritten 941113 by James Youngman.  WINE blew out when I
248  * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.  
249  *
250  * This was because the algorithm assumed that all RLE8 bitmaps end with the  
251  * 'End of bitmap' escape code.  This code is very much laxer in what it
252  * allows to end the expansion.  Possibly too lax.  See the note by 
253  * case RleDelta.  BTW, MS's documentation implies that a correct RLE8
254  * bitmap should end with RleEnd, but on the other hand, software exists 
255  * that produces ones that don't and Windows 3.1 doesn't complain a bit
256  * about it.
257  *
258  * (No) apologies for my English spelling.  [Emacs users: c-indent-level=4].
259  *                      James A. Youngman <mbcstjy@afs.man.ac.uk>
260  *                                              [JAY]
261  */
262
263 enum Rle8_EscapeCodes           
264 {
265   /* 
266    * Apologies for polluting your file's namespace...
267    */
268   RleEol        = 0,            /* End of line */
269   RleEnd        = 1,            /* End of bitmap */
270   RleDelta      = 2             /* Delta */
271 };
272   
273 static void DIB_SetImageBits_RLE8(WORD lines, 
274                                   BYTE *bits, 
275                                   WORD width,
276                                   int *colors, 
277                                   XImage *bmpImage)
278 {
279     int x;                      /* X-positon on each line.  Increases. */
280     int line;                   /* Line #.  Starts at lines-1, decreases */
281     BYTE *pIn = bits;           /* Pointer to current position in bits */
282     BYTE length;                /* The length pf a run */
283     BYTE color_index;           /* index into colors[] as read from bits */
284     BYTE escape_code;           /* See enum Rle8_EscapeCodes.*/
285     WORD color;                 /* value of colour[color_index] */
286     
287     if (lines == 0)             /* Let's hope this doesn't happen. */
288       return;
289     
290     /*
291      * Note that the bitmap data is stored by Windows starting at the
292      * bottom line of the bitmap and going upwards.  Within each line,
293      * the data is stored left-to-right.  That's the reason why line
294      * goes from lines-1 to 0.                  [JAY]
295      */
296     
297     x = 0;
298     line = lines-1;
299     do
300       {
301           length = *pIn++;
302           
303           /* 
304            * If the length byte is not zero (which is the escape value),
305            * We have a run of length pixels all the same colour.  The colour 
306            * index is stored next. 
307            *
308            * If the length byte is zero, we need to read the next byte to
309            * know what to do.                   [JAY]
310            */
311           if (length != 0) 
312             {                                   
313                 /* 
314                  * [Run-Length] Encoded mode 
315                  */
316                 color_index = (*pIn++); /* Get the colour index. */
317                 color = colors[color_index];
318
319                 while(length--)
320                   XPutPixel(bmpImage, x++, line, color);
321             }
322           else 
323             {    
324                 /* 
325                  * Escape codes (may be an absolute sequence though)
326                  */
327                 escape_code = (*pIn++);
328                 switch(escape_code)
329                   {
330                     case RleEol: /* =0, end of line */
331                       {
332                           x = 0;  
333                           line--;  
334                           break;
335                       }
336                       
337                     case RleEnd: /* =1, end of bitmap */
338                       {
339                           /*
340                            * Not all RLE8 bitmaps end with this 
341                            * code.  For example, Paint Shop Pro 
342                            * produces some that don't.  That's (I think)
343                            * what caused the previous implementation to 
344                            * fail.                      [JAY]
345                            */
346                           line=0; /* Cause exit from do loop. */
347                       }
348                       
349                     case RleDelta: /* =2, a delta */
350                       {
351                           /* 
352                            * Note that deltaing to line 0 
353                            * will cause an exit from the loop, 
354                            * which may not be what is intended. 
355                            * The fact that there is a delta in the bits
356                            * almost certainly implies that there is data
357                            * to follow.  You may feel that we should 
358                            * jump to the top of the loop to avoid exiting
359                            * in this case.  
360                            *
361                            * TODO: Decide what to do here in that case. [JAY]
362                            */
363                           x     += (*pIn++); 
364                           line  -= (*pIn++);
365                           if (line == 0)
366                             {
367                               dprintf_bitmap(stddeb, 
368                                              "DIB_SetImageBits_RLE8(): "
369                                              "Delta to last line of bitmap "
370                                              "(wrongly?) causes loop exit\n");
371                             }
372                           break;
373                       }
374                       
375                     default:    /* >2, switch to absolute mode */
376                       {
377                           /* 
378                            * Absolute Mode 
379                            */
380                           length = escape_code;
381                           while(length--)
382                             {
383                                 color_index = (*pIn++);
384                                 XPutPixel(bmpImage, x++, line, 
385                                           colors[color_index]);
386                             }
387                           
388                           /*
389                            * If you think for a moment you'll realise that the
390                            * only time we could ever possibly read an odd
391                            * number of bytes is when there is a 0x00 (escape),
392                            * a value >0x02 (absolute mode) and then an odd-
393                            * length run.  Therefore this is the only place we
394                            * need to worry about it.  Everywhere else the
395                            * bytes are always read in pairs.  [JAY]
396                            */
397                           if (escape_code & 1) 
398                             (*pIn++); /* Get and throw away the pad byte. */
399                           break;
400                       }
401                   } /* switch (escape_code) : Escape sequence */
402             }  /* process either an encoded sequence or an escape sequence */
403           
404           /* We expect to come here more than once per line. */
405       } while (line > 0);  /* Do this until the bitmap is filled */
406     
407     /*
408      * Everybody comes here at the end.
409      * Check how we exited the loop and print a message if it's a bit odd.
410      *                                          [JAY]
411      */
412     if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) )
413       {
414         dprintf_bitmap(stddeb, "DIB_SetImageBits_RLE8(): End-of-bitmap "
415                        "without (strictly) proper escape code.  Last two "
416                        "bytes were: %02X %02X.\n",
417                        (int)*(pIn-2),
418                        (int)*(pIn-1));           
419       }
420 }  
421
422
423 /***********************************************************************
424  *           DIB_SetImageBits_24
425  *
426  * SetDIBits for a 24-bit deep DIB.
427  */
428 static void DIB_SetImageBits_24( WORD lines, BYTE *bits, WORD width,
429                                  DC *dc, XImage *bmpImage )
430 {
431     WORD x;
432     BYTE pad = (4 - ((width*3) & 3)) & 3;
433
434     while (lines--)
435     {
436         for (x = 0; x < width; x++, bits += 3)
437         {
438             XPutPixel( bmpImage, x, lines,
439                        COLOR_ToPhysical( dc, RGB(bits[0],bits[1],bits[2]) ));
440         }
441         bits += pad;
442     }
443 }
444
445
446 /***********************************************************************
447  *           DIB_SetImageBits
448  *
449  * Transfer the bits to an X image.
450  * Helper function for SetDIBits() and SetDIBitsToDevice().
451  */
452 static int DIB_SetImageBits( DC *dc, WORD lines, WORD depth, LPSTR bits,
453                              BITMAPINFO *info, WORD coloruse,
454                              Drawable drawable, GC gc, int xSrc, int ySrc,
455                              int xDest, int yDest, int width, int height )
456 {
457     int *colorMapping;
458     XImage *bmpImage;
459     int i, colors;
460
461       /* Build the color mapping table */
462
463     if (info->bmiHeader.biBitCount == 24) colorMapping = NULL;
464     else
465     {
466         colors = info->bmiHeader.biClrUsed;
467         if (!colors) colors = 1 << info->bmiHeader.biBitCount;
468         if (!(colorMapping = (int *)malloc( colors * sizeof(int) )))
469             return 0;
470         if (coloruse == DIB_RGB_COLORS)
471         {
472             RGBQUAD * rgbPtr = info->bmiColors;
473             for (i = 0; i < colors; i++, rgbPtr++)
474                 colorMapping[i] = COLOR_ToPhysical( dc, RGB(rgbPtr->rgbRed,
475                                                             rgbPtr->rgbGreen,
476                                                             rgbPtr->rgbBlue) );
477         }
478         else
479         {
480             WORD * index = (WORD *)info->bmiColors;
481             for (i = 0; i < colors; i++, index++)
482                 colorMapping[i] = COLOR_ToPhysical( dc, PALETTEINDEX(*index) );
483         }
484     }
485
486       /* Transfer the pixels */
487     XCREATEIMAGE(bmpImage, info->bmiHeader.biWidth, lines, depth );
488
489     switch(info->bmiHeader.biBitCount)
490     {
491     case 1:
492         DIB_SetImageBits_1( lines, bits, info->bmiHeader.biWidth,
493                             colorMapping, bmpImage );
494         break;
495     case 4:
496         if (info->bmiHeader.biCompression)
497                 DIB_SetImageBits_RLE4( lines, bits, info->bmiHeader.biWidth,
498                             colorMapping, bmpImage );
499         else    
500                 DIB_SetImageBits_4( lines, bits, info->bmiHeader.biWidth,
501                             colorMapping, bmpImage );
502         break;
503     case 8:
504         if (info->bmiHeader.biCompression)
505                 DIB_SetImageBits_RLE8( lines, bits, info->bmiHeader.biWidth,
506                             colorMapping, bmpImage );
507         else
508                 DIB_SetImageBits_8( lines, bits, info->bmiHeader.biWidth,
509                             colorMapping, bmpImage );
510         break;
511     case 24:
512         DIB_SetImageBits_24( lines, bits, info->bmiHeader.biWidth,
513                              dc, bmpImage );
514         break;
515     }
516     if (colorMapping) free(colorMapping);
517
518     XPutImage( display, drawable, gc, bmpImage, xSrc, ySrc,
519                xDest, yDest, width, height );
520     XDestroyImage( bmpImage );
521     return lines;
522 }
523
524
525 /***********************************************************************
526  *           SetDIBits    (GDI.440)
527  */
528 int SetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines,
529                LPSTR bits, BITMAPINFO * info, WORD coloruse )
530 {
531     DC * dc;
532     BITMAPOBJ * bmp;
533
534       /* Check parameters */
535
536     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
537     if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
538         return 0;
539     if (!lines || (startscan >= (WORD)info->bmiHeader.biHeight)) return 0;
540     if (startscan+lines > info->bmiHeader.biHeight)
541         lines = info->bmiHeader.biHeight - startscan;
542
543     return DIB_SetImageBits( dc, lines, bmp->bitmap.bmBitsPixel,
544                              bits, info, coloruse, bmp->pixmap, BITMAP_GC(bmp),
545                              0, 0, 0, startscan, bmp->bitmap.bmWidth, lines );
546 }
547
548
549 /***********************************************************************
550  *           SetDIBitsToDevice    (GDI.443)
551  */
552 int SetDIBitsToDevice( HDC hdc, short xDest, short yDest, WORD cx, WORD cy,
553                        WORD xSrc, WORD ySrc, WORD startscan, WORD lines,
554                        LPSTR bits, BITMAPINFO * info, WORD coloruse )
555 {
556     DC * dc;
557
558       /* Check parameters */
559
560     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
561     if (!lines || (startscan >= info->bmiHeader.biHeight)) return 0;
562     if (startscan+lines > info->bmiHeader.biHeight)
563         lines = info->bmiHeader.biHeight - startscan;
564     if (ySrc < startscan) ySrc = startscan;
565     else if (ySrc >= startscan+lines) return 0;
566     if (xSrc >= info->bmiHeader.biWidth) return 0;
567     if (ySrc+cy >= startscan+lines) cy = startscan + lines - ySrc;
568     if (xSrc+cx >= info->bmiHeader.biWidth) cx = info->bmiHeader.biWidth-xSrc;
569     if (!cx || !cy) return 0;
570
571     DC_SetupGCForText( dc );  /* To have the correct colors */
572     XSetFunction( display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] );
573     return DIB_SetImageBits( dc, lines, dc->w.bitsPerPixel,
574                              bits, info, coloruse,
575                              dc->u.x.drawable, dc->u.x.gc,
576                              xSrc, ySrc - startscan,
577                              dc->w.DCOrgX + XLPTODP( dc, xDest ),
578                              dc->w.DCOrgY + YLPTODP( dc, yDest ),
579                              cx, cy );
580 }
581
582
583 /***********************************************************************
584  *           GetDIBits    (GDI.441)
585  */
586 int GetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines,
587                LPSTR bits, BITMAPINFO * info, WORD coloruse )
588 {
589     DC * dc;
590     BITMAPOBJ * bmp;
591     PALETTEENTRY * palEntry;
592     PALETTEOBJ * palette;
593     XImage * bmpImage, * dibImage;
594     int i, x, y;
595         
596     if (!lines) return 0;
597     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
598     if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
599         return 0;
600     if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
601         return 0;
602
603       /* Transfer color info */
604     
605     palEntry = palette->logpalette.palPalEntry;
606     for (i = 0; i < info->bmiHeader.biClrUsed; i++, palEntry++)
607     {
608         if (coloruse == DIB_RGB_COLORS)
609         {
610             info->bmiColors[i].rgbRed      = palEntry->peRed;
611             info->bmiColors[i].rgbGreen    = palEntry->peGreen;
612             info->bmiColors[i].rgbBlue     = palEntry->peBlue;
613             info->bmiColors[i].rgbReserved = 0;
614         }
615         else ((WORD *)info->bmiColors)[i] = (WORD)i;
616     }
617     
618       /* Transfer the pixels (very slow...) */
619
620     if (bits)
621     {   
622         bmpImage = XGetImage( display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth,
623                               bmp->bitmap.bmHeight, AllPlanes, ZPixmap );
624         dibImage = DIB_DIBmpToImage( &info->bmiHeader, bits );
625
626         for (y = 0; y < lines; y++)
627         {
628             for (x = 0; x < info->bmiHeader.biWidth; x++)
629             {
630                 XPutPixel( dibImage, x, y,
631                   XGetPixel(bmpImage, x, bmp->bitmap.bmHeight-startscan-y-1) );
632                 
633             }
634         }
635         
636         dibImage->data = NULL;
637         XDestroyImage( dibImage );
638         XDestroyImage( bmpImage );
639     }
640     return lines;
641 }
642
643
644 /***********************************************************************
645  *           CreateDIBitmap    (GDI.442)
646  */
647 HBITMAP CreateDIBitmap( HDC hdc, BITMAPINFOHEADER * header, DWORD init,
648                         LPSTR bits, BITMAPINFO * data, WORD coloruse )
649 {
650     HBITMAP handle;
651     
652     handle = CreateCompatibleBitmap( hdc, header->biWidth, header->biHeight );
653     if (!handle) return 0;
654     if (init == CBM_INIT) SetDIBits( hdc, handle, 0, header->biHeight,
655                                     bits, data, coloruse );
656     return handle;
657 }
658
659 /***********************************************************************
660  *           DrawIcon    (USER.84)
661  */
662 BOOL DrawIcon(HDC hDC, short x, short y, HICON hIcon)
663 {
664     ICONALLOC   *lpico;
665     BITMAP      bm;
666     HBITMAP     hBitTemp;
667     HDC         hMemDC;
668
669     dprintf_icon(stddeb,"DrawIcon(%04X, %d, %d, %04X) \n", hDC, x, y, hIcon);
670     if (hIcon == (HICON)NULL) return FALSE;
671     lpico = (ICONALLOC *)GlobalLock(hIcon);
672     GetObject(lpico->hBitmap, sizeof(BITMAP), (LPSTR)&bm);
673     dprintf_icon(stddeb,"DrawIcon / x=%d y=%d\n", x, y);
674     dprintf_icon(stddeb,"DrawIcon / icon Width=%d\n", 
675                  (int)lpico->descriptor.Width);
676     dprintf_icon(stddeb,"DrawIcon / icon Height=%d\n", 
677                  (int)lpico->descriptor.Height);
678     dprintf_icon(stddeb,"DrawIcon / icon ColorCount=%d\n", 
679                  (int)lpico->descriptor.ColorCount);
680     dprintf_icon(stddeb,"DrawIcon / icon icoDIBSize=%lX\n", 
681                  (DWORD)lpico->descriptor.icoDIBSize);
682     dprintf_icon(stddeb,"DrawIcon / icon icoDIBOffset=%lX\n", 
683                  (DWORD)lpico->descriptor.icoDIBOffset);
684     dprintf_icon(stddeb,"DrawIcon / bitmap bmWidth=%d bmHeight=%d\n", 
685                  bm.bmWidth, bm.bmHeight);
686     hMemDC = CreateCompatibleDC(hDC);
687     if(debugging_icon){
688     hBitTemp = SelectObject(hMemDC, lpico->hBitmap);
689     BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
690     SelectObject(hMemDC, lpico->hBitMask);
691     BitBlt(hDC, x, y + bm.bmHeight, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
692     }else{
693     hBitTemp = SelectObject(hMemDC, lpico->hBitMask);
694     BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCAND);
695     SelectObject(hMemDC, lpico->hBitmap);
696     BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCPAINT);
697     }
698     SelectObject( hMemDC, hBitTemp );
699     DeleteDC(hMemDC);
700     return TRUE;
701 }
702