Converted to the new debug interface, using script written by Patrik
[wine] / graphics / painting.c
1 /*
2  * Misc. graphics operations
3  *
4  * Copyright 1993, 1994 Alexandre Julliard
5  * Copyright 1997 Bertho A. Stultiens
6  */
7
8 #include <string.h>
9 #include "dc.h"
10 #include "bitmap.h"
11 #include "heap.h"
12 #include "monitor.h"
13 #include "cache.h"
14 #include "region.h"
15 #include "path.h"
16 #include "debugtools.h"
17 #include "winerror.h"
18 #include "winuser.h"
19 #include "wine/winuser16.h"
20
21 DEFAULT_DEBUG_CHANNEL(gdi)
22
23
24 /***********************************************************************
25  *           LineTo16    (GDI.19)
26  */
27 BOOL16 WINAPI LineTo16( HDC16 hdc, INT16 x, INT16 y )
28 {
29     return LineTo( hdc, x, y );
30 }
31
32
33 /***********************************************************************
34  *           LineTo32    (GDI32.249)
35  */
36 BOOL WINAPI LineTo( HDC hdc, INT x, INT y )
37 {
38     DC * dc = DC_GetDCPtr( hdc );
39
40     if(dc && PATH_IsPathOpen(dc->w.path))
41         if(!PATH_LineTo(hdc, x, y))
42            return FALSE;
43     
44     return dc && dc->funcs->pLineTo &&
45            dc->funcs->pLineTo(dc,x,y);
46 }
47
48
49 /***********************************************************************
50  *           MoveTo    (GDI.20)
51  */
52 DWORD WINAPI MoveTo16( HDC16 hdc, INT16 x, INT16 y )
53 {
54     POINT16     pt;
55
56     if (!MoveToEx16(hdc,x,y,&pt))
57         return 0;
58     return MAKELONG(pt.x,pt.y);
59 }
60
61
62 /***********************************************************************
63  *           MoveToEx16    (GDI.483)
64  */
65 BOOL16 WINAPI MoveToEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
66 {
67     POINT pt32;
68
69     if (!MoveToEx( (HDC)hdc, (INT)x, (INT)y, &pt32 )) return FALSE;
70     if (pt) CONV_POINT32TO16( &pt32, pt );
71     return TRUE;
72
73 }
74
75
76 /***********************************************************************
77  *           MoveToEx32    (GDI32.254)
78  */
79 BOOL WINAPI MoveToEx( HDC hdc, INT x, INT y, LPPOINT pt )
80 {
81     DC * dc = DC_GetDCPtr( hdc );
82   
83     if(dc && PATH_IsPathOpen(dc->w.path))
84         if(!PATH_MoveTo(hdc))
85             return FALSE;
86
87     return dc && dc->funcs->pMoveToEx &&
88            dc->funcs->pMoveToEx(dc,x,y,pt);
89 }
90
91
92 /***********************************************************************
93  *           Arc16    (GDI.23)
94  */
95 BOOL16 WINAPI Arc16( HDC16 hdc, INT16 left, INT16 top, INT16 right,
96                      INT16 bottom, INT16 xstart, INT16 ystart,
97                      INT16 xend, INT16 yend )
98 {
99     return Arc( (HDC)hdc, (INT)left, (INT)top, (INT)right,
100                   (INT)bottom, (INT)xstart, (INT)ystart, (INT)xend,
101                   (INT)yend );
102 }
103
104
105 /***********************************************************************
106  *           Arc32    (GDI32.7)
107  */
108 BOOL WINAPI Arc( HDC hdc, INT left, INT top, INT right,
109                      INT bottom, INT xstart, INT ystart,
110                      INT xend, INT yend )
111 {
112     DC * dc = DC_GetDCPtr( hdc );
113   
114     if(dc && PATH_IsPathOpen(dc->w.path))
115         if(!PATH_Arc(hdc, left, top, right, bottom, xstart, ystart, xend,
116            yend))
117            return FALSE;
118     
119     return dc && dc->funcs->pArc &&
120            dc->funcs->pArc(dc,left,top,right,bottom,xstart,ystart,xend,yend);
121 }
122
123 /***********************************************************************
124  *           ArcTo    (GDI32.8)
125  */
126 BOOL WINAPI ArcTo( HDC hdc, 
127                      INT left,   INT top, 
128                      INT right,  INT bottom,
129                      INT xstart, INT ystart,
130                      INT xend,   INT yend )
131 {
132     BOOL result;
133
134     /*
135      * According to the documentation, a line is drawn from the current
136      * position to the starting point of the arc.
137      */
138     LineTo(hdc, xstart, ystart);
139
140     /*
141      * Then the arc is drawn.
142      */
143     result = Arc(hdc, 
144                   left, top,
145                   right, bottom,
146                   xstart, ystart,
147                   xend, yend);
148
149     /*
150      * If no error occured, the current position is moved to the ending
151      * point of the arc.
152      */
153     if (result)
154     {
155         MoveToEx(hdc, xend, yend, NULL);
156     }
157
158     return result;
159 }
160
161 /***********************************************************************
162  *           Pie16    (GDI.26)
163  */
164 BOOL16 WINAPI Pie16( HDC16 hdc, INT16 left, INT16 top,
165                      INT16 right, INT16 bottom, INT16 xstart, INT16 ystart,
166                      INT16 xend, INT16 yend )
167 {
168     return Pie( (HDC)hdc, (INT)left, (INT)top, (INT)right,
169                   (INT)bottom, (INT)xstart, (INT)ystart, (INT)xend,
170                   (INT)yend );
171 }
172
173
174 /***********************************************************************
175  *           Pie32   (GDI32.262)
176  */
177 BOOL WINAPI Pie( HDC hdc, INT left, INT top,
178                      INT right, INT bottom, INT xstart, INT ystart,
179                      INT xend, INT yend )
180 {
181     DC * dc = DC_GetDCPtr( hdc );
182   
183     return dc && dc->funcs->pPie &&
184            dc->funcs->pPie(dc,left,top,right,bottom,xstart,ystart,xend,yend);
185 }
186
187
188 /***********************************************************************
189  *           Chord16    (GDI.348)
190  */
191 BOOL16 WINAPI Chord16( HDC16 hdc, INT16 left, INT16 top,
192                        INT16 right, INT16 bottom, INT16 xstart, INT16 ystart,
193                        INT16 xend, INT16 yend )
194 {
195     return Chord( hdc, left, top, right, bottom, xstart, ystart, xend, yend );
196 }
197
198
199 /***********************************************************************
200  *           Chord32    (GDI32.14)
201  */
202 BOOL WINAPI Chord( HDC hdc, INT left, INT top,
203                        INT right, INT bottom, INT xstart, INT ystart,
204                        INT xend, INT yend )
205 {
206     DC * dc = DC_GetDCPtr( hdc );
207   
208     return dc && dc->funcs->pChord &&
209            dc->funcs->pChord(dc,left,top,right,bottom,xstart,ystart,xend,yend);
210 }
211
212
213 /***********************************************************************
214  *           Ellipse16    (GDI.24)
215  */
216 BOOL16 WINAPI Ellipse16( HDC16 hdc, INT16 left, INT16 top,
217                          INT16 right, INT16 bottom )
218 {
219     return Ellipse( hdc, left, top, right, bottom );
220 }
221
222
223 /***********************************************************************
224  *           Ellipse32    (GDI32.75)
225  */
226 BOOL WINAPI Ellipse( HDC hdc, INT left, INT top,
227                          INT right, INT bottom )
228 {
229     DC * dc = DC_GetDCPtr( hdc );
230   
231     return dc && dc->funcs->pEllipse &&
232            dc->funcs->pEllipse(dc,left,top,right,bottom);
233 }
234
235
236 /***********************************************************************
237  *           Rectangle16    (GDI.27)
238  */
239 BOOL16 WINAPI Rectangle16( HDC16 hdc, INT16 left, INT16 top,
240                            INT16 right, INT16 bottom )
241 {
242     return Rectangle( hdc, left, top, right, bottom );
243 }
244
245
246 /***********************************************************************
247  *           Rectangle32    (GDI32.283)
248  */
249 BOOL WINAPI Rectangle( HDC hdc, INT left, INT top,
250                            INT right, INT bottom )
251 {
252     DC * dc = DC_GetDCPtr( hdc );
253   
254     if(dc && PATH_IsPathOpen(dc->w.path))
255         if(!PATH_Rectangle(hdc, left, top, right, bottom))
256            return FALSE;
257
258     return dc && dc->funcs->pRectangle &&
259            dc->funcs->pRectangle(dc,left,top,right,bottom);
260 }
261
262
263 /***********************************************************************
264  *           RoundRect16    (GDI.28)
265  */
266 BOOL16 WINAPI RoundRect16( HDC16 hdc, INT16 left, INT16 top, INT16 right,
267                            INT16 bottom, INT16 ell_width, INT16 ell_height )
268 {
269     return RoundRect( hdc, left, top, right, bottom, ell_width, ell_height );
270 }
271
272
273 /***********************************************************************
274  *           RoundRect32    (GDI32.291)
275  */
276 BOOL WINAPI RoundRect( HDC hdc, INT left, INT top, INT right,
277                            INT bottom, INT ell_width, INT ell_height )
278 {
279   
280     if(ell_width == 0 || ell_height == 0) /* Just an optimization */
281         return Rectangle(hdc, left, top, right, bottom);
282
283     else {
284         DC * dc = DC_GetDCPtr( hdc );
285
286         return dc && dc->funcs->pRoundRect &&
287            dc->funcs->pRoundRect(dc,left,top,right,bottom,ell_width,ell_height);
288     }
289 }
290
291
292 /***********************************************************************
293  *           FillRect16    (USER.81)
294  */
295 INT16 WINAPI FillRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
296 {
297     HBRUSH16 prevBrush;
298
299     /* coordinates are logical so we cannot fast-check 'rect',
300      * it will be done later in the PatBlt().
301      */
302
303     if (!(prevBrush = SelectObject16( hdc, hbrush ))) return 0;
304     PatBlt( hdc, rect->left, rect->top,
305               rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
306     SelectObject16( hdc, prevBrush );
307     return 1;
308 }
309
310
311 /***********************************************************************
312  *           FillRect32    (USER32.197)
313  */
314 INT WINAPI FillRect( HDC hdc, const RECT *rect, HBRUSH hbrush )
315 {
316     HBRUSH prevBrush;
317
318     if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
319     PatBlt( hdc, rect->left, rect->top,
320               rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
321     SelectObject( hdc, prevBrush );
322     return 1;
323 }
324
325
326 /***********************************************************************
327  *           InvertRect16    (USER.82)
328  */
329 void WINAPI InvertRect16( HDC16 hdc, const RECT16 *rect )
330 {
331     PatBlt( hdc, rect->left, rect->top,
332               rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
333 }
334
335
336 /***********************************************************************
337  *           InvertRect32    (USER32.330)
338  */
339 BOOL WINAPI InvertRect( HDC hdc, const RECT *rect )
340 {
341     return PatBlt( hdc, rect->left, rect->top,
342                      rect->right - rect->left, rect->bottom - rect->top, 
343                      DSTINVERT );
344 }
345
346
347 /***********************************************************************
348  *           FrameRect16    (USER.83)
349  */
350 INT16 WINAPI FrameRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
351 {
352     HBRUSH16 prevBrush;
353     int left, top, right, bottom;
354
355     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
356     if (!dc) return FALSE;
357
358     left   = XLPTODP( dc, rect->left );
359     top    = YLPTODP( dc, rect->top );
360     right  = XLPTODP( dc, rect->right );
361     bottom = YLPTODP( dc, rect->bottom );
362
363     if ( (right <= left) || (bottom <= top) ) return 0;
364     if (!(prevBrush = SelectObject16( hdc, hbrush ))) return 0;
365     
366     PatBlt( hdc, rect->left, rect->top, 1,
367               rect->bottom - rect->top, PATCOPY );
368     PatBlt( hdc, rect->right - 1, rect->top, 1,
369               rect->bottom - rect->top, PATCOPY );
370     PatBlt( hdc, rect->left, rect->top,
371               rect->right - rect->left, 1, PATCOPY );
372     PatBlt( hdc, rect->left, rect->bottom - 1,
373               rect->right - rect->left, 1, PATCOPY );
374
375     SelectObject16( hdc, prevBrush );
376     return 1;
377 }
378
379
380 /***********************************************************************
381  *           FrameRect32    (USER32.203)
382  */
383 INT WINAPI FrameRect( HDC hdc, const RECT *rect, HBRUSH hbrush )
384 {
385     RECT16 rect16;
386     CONV_RECT32TO16( rect, &rect16 );
387     return FrameRect16( (HDC16)hdc, &rect16, (HBRUSH16)hbrush );
388 }
389
390
391 /***********************************************************************
392  *           SetPixel16    (GDI.31)
393  */
394 COLORREF WINAPI SetPixel16( HDC16 hdc, INT16 x, INT16 y, COLORREF color )
395 {
396     return SetPixel( hdc, x, y, color );
397 }
398
399
400 /***********************************************************************
401  *           SetPixel32    (GDI32.327)
402  */
403 COLORREF WINAPI SetPixel( HDC hdc, INT x, INT y, COLORREF color )
404 {
405     DC * dc = DC_GetDCPtr( hdc );
406   
407     if (!dc || !dc->funcs->pSetPixel) return 0;
408     return dc->funcs->pSetPixel(dc,x,y,color);
409 }
410
411 /***********************************************************************
412  *           SetPixelV32    (GDI32.329)
413  */
414 BOOL WINAPI SetPixelV( HDC hdc, INT x, INT y, COLORREF color )
415 {
416     DC * dc = DC_GetDCPtr( hdc );
417   
418     if (!dc || !dc->funcs->pSetPixel) return FALSE;
419     dc->funcs->pSetPixel(dc,x,y,color);
420     return TRUE;
421 }
422
423 /***********************************************************************
424  *           GetPixel16    (GDI.83)
425  */
426 COLORREF WINAPI GetPixel16( HDC16 hdc, INT16 x, INT16 y )
427 {
428     return GetPixel( hdc, x, y );
429 }
430
431
432 /***********************************************************************
433  *           GetPixel32    (GDI32.211)
434  */
435 COLORREF WINAPI GetPixel( HDC hdc, INT x, INT y )
436 {
437     DC * dc = DC_GetDCPtr( hdc );
438
439     if (!dc) return 0;
440 #ifdef SOLITAIRE_SPEED_HACK
441     return 0;
442 #endif
443
444     /* FIXME: should this be in the graphics driver? */
445     if (!PtVisible( hdc, x, y )) return 0;
446     if (!dc || !dc->funcs->pGetPixel) return 0;
447     return dc->funcs->pGetPixel(dc,x,y);
448 }
449
450
451 /******************************************************************************
452  * ChoosePixelFormat [GDI32.13]
453  * Matches a pixel format to given format
454  *
455  * PARAMS
456  *    hdc  [I] Device context to search for best pixel match
457  *    ppfd [I] Pixel format for which a match is sought
458  *
459  * RETURNS
460  *    Success: Pixel format index closest to given format
461  *    Failure: 0
462  */
463 INT WINAPI ChoosePixelFormat( HDC hdc, const PIXELFORMATDESCRIPTOR* ppfd )
464 {
465     FIXME("(%d,%p): stub\n",hdc,ppfd);
466     return 1;
467 }
468
469
470 /******************************************************************************
471  * SetPixelFormat [GDI32.328]
472  * Sets pixel format of device context
473  *
474  * PARAMS
475  *    hdc          [I] Device context to search for best pixel match
476  *    iPixelFormat [I] Pixel format index
477  *    ppfd         [I] Pixel format for which a match is sought
478  *
479  * RETURNS STD
480  */
481 BOOL WINAPI SetPixelFormat( HDC hdc, int iPixelFormat, 
482                               const PIXELFORMATDESCRIPTOR* ppfd)
483 {
484     FIXME("(%d,%d,%p): stub\n",hdc,iPixelFormat,ppfd);
485     return TRUE;
486 }
487
488
489 /******************************************************************************
490  * GetPixelFormat [GDI32.212]
491  * Gets index of pixel format of DC
492  *
493  * PARAMETERS
494  *    hdc [I] Device context whose pixel format index is sought
495  *
496  * RETURNS
497  *    Success: Currently selected pixel format
498  *    Failure: 0
499  */
500 int WINAPI GetPixelFormat( HDC hdc )
501 {
502     FIXME("(%d): stub\n",hdc);
503     return 1;
504 }
505
506
507 /******************************************************************************
508  * DescribePixelFormat [GDI32.71]
509  * Gets info about pixel format from DC
510  *
511  * PARAMS
512  *    hdc          [I] Device context
513  *    iPixelFormat [I] Pixel format selector
514  *    nBytes       [I] Size of buffer
515  *    ppfd         [O] Pointer to structure to receive pixel format data
516  *
517  * RETURNS
518  *    Success: Maximum pixel format index of the device context
519  *    Failure: 0
520  */
521 int WINAPI DescribePixelFormat( HDC hdc, int iPixelFormat, UINT nBytes,
522                                 LPPIXELFORMATDESCRIPTOR ppfd )
523 {
524     FIXME("(%d,%d,%d,%p): stub\n",hdc,iPixelFormat,nBytes,ppfd);
525     ppfd->nSize = nBytes;
526     ppfd->nVersion = 1;
527     return 3;
528 }
529
530
531 /******************************************************************************
532  * SwapBuffers [GDI32.354]
533  * Exchanges front and back buffers of window
534  *
535  * PARAMS
536  *    hdc [I] Device context whose buffers get swapped
537  *
538  * RETURNS STD
539  */
540 BOOL WINAPI SwapBuffers( HDC hdc )
541 {
542     FIXME("(%d): stub\n",hdc);
543     return TRUE;
544 }
545
546
547 /***********************************************************************
548  *           PaintRgn16    (GDI.43)
549  */
550 BOOL16 WINAPI PaintRgn16( HDC16 hdc, HRGN16 hrgn )
551 {
552     return PaintRgn( hdc, hrgn );
553 }
554
555
556 /***********************************************************************
557  *           PaintRgn32    (GDI32.259)
558  */
559 BOOL WINAPI PaintRgn( HDC hdc, HRGN hrgn )
560 {
561     DC * dc = DC_GetDCPtr( hdc );
562
563     return dc && dc->funcs->pPaintRgn &&
564            dc->funcs->pPaintRgn(dc,hrgn);
565 }
566
567
568 /***********************************************************************
569  *           FillRgn16    (GDI.40)
570  */
571 BOOL16 WINAPI FillRgn16( HDC16 hdc, HRGN16 hrgn, HBRUSH16 hbrush )
572 {
573     return FillRgn( hdc, hrgn, hbrush );
574 }
575
576     
577 /***********************************************************************
578  *           FillRgn32    (GDI32.101)
579  */
580 BOOL WINAPI FillRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush )
581 {
582     BOOL retval;
583     HBRUSH prevBrush;
584     DC * dc = DC_GetDCPtr( hdc );
585
586     if(dc->funcs->pFillRgn)
587         return dc->funcs->pFillRgn(dc, hrgn, hbrush);
588
589     prevBrush = SelectObject( hdc, hbrush );
590     if (!prevBrush) return FALSE;
591     retval = PaintRgn( hdc, hrgn );
592     SelectObject( hdc, prevBrush );
593     return retval;
594 }
595
596
597 /***********************************************************************
598  *           FrameRgn16     (GDI.41)
599  */
600 BOOL16 WINAPI FrameRgn16( HDC16 hdc, HRGN16 hrgn, HBRUSH16 hbrush,
601                           INT16 nWidth, INT16 nHeight )
602 {
603     return FrameRgn( hdc, hrgn, hbrush, nWidth, nHeight );
604 }
605
606
607 /***********************************************************************
608  *           FrameRgn32     (GDI32.105)
609  */
610 BOOL WINAPI FrameRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush,
611                           INT nWidth, INT nHeight )
612 {
613     HRGN tmp;
614     DC *dc = DC_GetDCPtr( hdc );
615
616     if(dc->funcs->pFrameRgn)
617         return dc->funcs->pFrameRgn( dc, hrgn, hbrush, nWidth, nHeight );
618
619     tmp = CreateRectRgn( 0, 0, 0, 0 );
620     if(!REGION_FrameRgn( tmp, hrgn, nWidth, nHeight )) return FALSE;
621     FillRgn( hdc, tmp, hbrush );
622     DeleteObject( tmp );
623     return TRUE;
624 }
625
626
627 /***********************************************************************
628  *           InvertRgn16    (GDI.42)
629  */
630 BOOL16 WINAPI InvertRgn16( HDC16 hdc, HRGN16 hrgn )
631 {
632     return InvertRgn( hdc, hrgn );
633 }
634
635
636 /***********************************************************************
637  *           InvertRgn32    (GDI32.246)
638  */
639 BOOL WINAPI InvertRgn( HDC hdc, HRGN hrgn )
640 {
641     HBRUSH prevBrush;
642     INT prevROP;
643     BOOL retval;
644     DC *dc = DC_GetDCPtr( hdc );
645
646     if(dc->funcs->pInvertRgn)
647         return dc->funcs->pInvertRgn( dc, hrgn );
648
649     prevBrush = SelectObject( hdc, GetStockObject(BLACK_BRUSH) );
650     prevROP = SetROP2( hdc, R2_NOT );
651     retval = PaintRgn( hdc, hrgn );
652     SelectObject( hdc, prevBrush );
653     SetROP2( hdc, prevROP );
654     return retval;
655 }
656
657
658 /***********************************************************************
659  *           DrawFocusRect16    (USER.466)
660  */
661 void WINAPI DrawFocusRect16( HDC16 hdc, const RECT16* rc )
662 {
663     RECT rect32;
664     CONV_RECT16TO32( rc, &rect32 );
665     DrawFocusRect( hdc, &rect32 );
666 }
667
668
669 /***********************************************************************
670  *           DrawFocusRect32    (USER32.156)
671  *
672  * FIXME: PatBlt(PATINVERT) with background brush.
673  */
674 BOOL WINAPI DrawFocusRect( HDC hdc, const RECT* rc )
675 {
676     HBRUSH hOldBrush;
677     HPEN hOldPen, hNewPen;
678     INT oldDrawMode, oldBkMode;
679
680     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
681     if (!dc) 
682     {
683        SetLastError( ERROR_INVALID_HANDLE );
684        return FALSE;
685     }
686
687     hOldBrush = SelectObject(hdc, GetStockObject(NULL_BRUSH));
688     hNewPen = CreatePen(PS_DOT, 1, GetSysColor(COLOR_WINDOWTEXT));
689     hOldPen = SelectObject(hdc, hNewPen);
690     oldDrawMode = SetROP2(hdc, R2_XORPEN);
691     oldBkMode = SetBkMode(hdc, TRANSPARENT);
692
693     Rectangle(hdc, rc->left, rc->top, rc->right, rc->bottom);
694
695     SetBkMode(hdc, oldBkMode);
696     SetROP2(hdc, oldDrawMode);
697     SelectObject(hdc, hOldPen);
698     DeleteObject(hNewPen);
699     SelectObject(hdc, hOldBrush);
700
701     return TRUE;
702 }
703
704
705 /**********************************************************************
706  *          Polyline16  (GDI.37)
707  */
708 BOOL16 WINAPI Polyline16( HDC16 hdc, const POINT16* pt, INT16 count )
709 {
710     register int i;
711     BOOL16 ret;
712     LPPOINT pt32 = (LPPOINT)HeapAlloc( GetProcessHeap(), 0,
713                                            count*sizeof(POINT) );
714
715     if (!pt32) return FALSE;
716     for (i=count;i--;) CONV_POINT16TO32(&(pt[i]),&(pt32[i]));
717     ret = Polyline(hdc,pt32,count);
718     HeapFree( GetProcessHeap(), 0, pt32 );
719     return ret;
720 }
721
722
723 /**********************************************************************
724  *          Polyline32   (GDI32.276)
725  */
726 BOOL WINAPI Polyline( HDC hdc, const POINT* pt, INT count )
727 {
728     DC * dc = DC_GetDCPtr( hdc );
729
730     return dc && dc->funcs->pPolyline &&
731            dc->funcs->pPolyline(dc,pt,count);
732 }
733
734 /**********************************************************************
735  *          PolylineTo32   (GDI32.277)
736  */
737 BOOL WINAPI PolylineTo( HDC hdc, const POINT* pt, DWORD cCount )
738 {
739     POINT *pts = HeapAlloc( GetProcessHeap(), 0,
740                               sizeof(POINT) * (cCount + 1) );
741     if(!pts) return FALSE;
742
743     /* Get the current point */
744     MoveToEx( hdc, 0, 0, pts);
745
746     /* Add in the other points */
747     memcpy( pts + 1, pt, sizeof(POINT) * cCount );
748
749     /* Draw the lines */
750     Polyline( hdc, pts, cCount + 1 );
751
752     /* Move to last point */
753     MoveToEx( hdc, (pts + cCount)->x, (pts + cCount)->y, NULL );
754
755     HeapFree( GetProcessHeap(), 0, pts );
756     return TRUE;
757 }
758
759 /**********************************************************************
760  *          Polygon16  (GDI.36)
761  */
762 BOOL16 WINAPI Polygon16( HDC16 hdc, const POINT16* pt, INT16 count )
763 {
764     register int i;
765     BOOL ret;
766     LPPOINT pt32 = (LPPOINT)HeapAlloc( GetProcessHeap(), 0,
767                                            count*sizeof(POINT) );
768
769     if (!pt32) return FALSE;
770     for (i=count;i--;) CONV_POINT16TO32(&(pt[i]),&(pt32[i]));
771     ret = Polygon(hdc,pt32,count);
772     HeapFree( GetProcessHeap(), 0, pt32 );
773     return ret;
774 }
775
776
777 /**********************************************************************
778  *          Polygon32  (GDI32.275)
779  */
780 BOOL WINAPI Polygon( HDC hdc, const POINT* pt, INT count )
781 {
782     DC * dc = DC_GetDCPtr( hdc );
783
784     return dc && dc->funcs->pPolygon &&
785            dc->funcs->pPolygon(dc,pt,count);
786 }
787
788
789 /**********************************************************************
790  *          PolyPolygon16  (GDI.450)
791  */
792 BOOL16 WINAPI PolyPolygon16( HDC16 hdc, const POINT16* pt, const INT16* counts,
793                              UINT16 polygons )
794 {
795     int         i,nrpts;
796     LPPOINT     pt32;
797     LPINT       counts32;
798     BOOL16      ret;
799
800     nrpts=0;
801     for (i=polygons;i--;)
802         nrpts+=counts[i];
803     pt32 = (LPPOINT)HEAP_xalloc( GetProcessHeap(), 0, sizeof(POINT)*nrpts);
804     for (i=nrpts;i--;)
805         CONV_POINT16TO32(&(pt[i]),&(pt32[i]));
806     counts32 = (LPINT)HEAP_xalloc( GetProcessHeap(), 0,
807                                      polygons*sizeof(INT) );
808     for (i=polygons;i--;) counts32[i]=counts[i];
809    
810     ret = PolyPolygon(hdc,pt32,counts32,polygons);
811     HeapFree( GetProcessHeap(), 0, counts32 );
812     HeapFree( GetProcessHeap(), 0, pt32 );
813     return ret;
814 }
815
816 /**********************************************************************
817  *          PolyPolygon32  (GDI.450)
818  */
819 BOOL WINAPI PolyPolygon( HDC hdc, const POINT* pt, const INT* counts,
820                              UINT polygons )
821 {
822     DC * dc = DC_GetDCPtr( hdc );
823
824     return dc && dc->funcs->pPolyPolygon &&
825            dc->funcs->pPolyPolygon(dc,pt,counts,polygons);
826 }
827
828 /**********************************************************************
829  *          PolyPolyline  (GDI32.272)
830  */
831 BOOL WINAPI PolyPolyline( HDC hdc, const POINT* pt, const DWORD* counts,
832                             DWORD polylines )
833 {
834     DC * dc = DC_GetDCPtr( hdc );
835
836     return dc && dc->funcs->pPolyPolyline &&
837            dc->funcs->pPolyPolyline(dc,pt,counts,polylines);
838 }
839
840 /**********************************************************************
841  *          ExtFloodFill16   (GDI.372)
842  */
843 BOOL16 WINAPI ExtFloodFill16( HDC16 hdc, INT16 x, INT16 y, COLORREF color,
844                               UINT16 fillType )
845 {
846     return ExtFloodFill( hdc, x, y, color, fillType );
847 }
848
849
850 /**********************************************************************
851  *          ExtFloodFill32   (GDI32.96)
852  */
853 BOOL WINAPI ExtFloodFill( HDC hdc, INT x, INT y, COLORREF color,
854                               UINT fillType )
855 {
856     DC *dc = DC_GetDCPtr( hdc );
857
858     return dc && dc->funcs->pExtFloodFill &&
859            dc->funcs->pExtFloodFill(dc,x,y,color,fillType);
860 }
861
862
863 /**********************************************************************
864  *          FloodFill16   (GDI.25)
865  */
866 BOOL16 WINAPI FloodFill16( HDC16 hdc, INT16 x, INT16 y, COLORREF color )
867 {
868     return ExtFloodFill( hdc, x, y, color, FLOODFILLBORDER );
869 }
870
871
872 /**********************************************************************
873  *          FloodFill32   (GDI32.104)
874  */
875 BOOL WINAPI FloodFill( HDC hdc, INT x, INT y, COLORREF color )
876 {
877     return ExtFloodFill( hdc, x, y, color, FLOODFILLBORDER );
878 }
879
880
881 /**********************************************************************
882  *          DrawAnimatedRects16  (USER.448)
883  */
884 BOOL16 WINAPI DrawAnimatedRects16( HWND16 hwnd, INT16 idAni,
885                                    const RECT16* lprcFrom,
886                                    const RECT16* lprcTo )
887 {
888     RECT rcFrom32, rcTo32;
889
890     rcFrom32.left       = (INT)lprcFrom->left;
891     rcFrom32.top        = (INT)lprcFrom->top;
892     rcFrom32.right      = (INT)lprcFrom->right;
893     rcFrom32.bottom     = (INT)lprcFrom->bottom;
894
895     rcTo32.left         = (INT)lprcTo->left;
896     rcTo32.top          = (INT)lprcTo->top;
897     rcTo32.right        = (INT)lprcTo->right;
898     rcTo32.bottom       = (INT)lprcTo->bottom;
899
900     return DrawAnimatedRects((HWND)hwnd, (INT)idAni, &rcFrom32, &rcTo32);
901 }
902
903
904 /**********************************************************************
905  *          DrawAnimatedRects32  (USER32.153)
906  */
907 BOOL WINAPI DrawAnimatedRects( HWND hwnd, int idAni,
908                                    const RECT* lprcFrom,
909                                    const RECT* lprcTo )
910 {
911     FIXME("(0x%x,%d,%p,%p): stub\n",hwnd,idAni,lprcFrom,lprcTo);
912     return TRUE;
913 }
914
915
916 /**********************************************************************
917  *          PAINTING_DrawStateJam
918  *
919  * Jams in the requested type in the dc
920  */
921 static BOOL PAINTING_DrawStateJam(HDC hdc, UINT opcode,
922                                     DRAWSTATEPROC func, LPARAM lp, WPARAM wp, 
923                                     LPRECT rc, UINT dtflags,
924                                     BOOL unicode, BOOL _32bit)
925 {
926     HDC memdc;
927     HBITMAP hbmsave;
928     BOOL retval;
929     INT cx = rc->right - rc->left;
930     INT cy = rc->bottom - rc->top;
931     
932     switch(opcode)
933     {
934     case DST_TEXT:
935     case DST_PREFIXTEXT:
936         if(unicode)
937             return DrawTextW(hdc, (LPWSTR)lp, (INT)wp, rc, dtflags);
938         else if(_32bit)
939             return DrawTextA(hdc, (LPSTR)lp, (INT)wp, rc, dtflags);
940         else
941             return DrawTextA(hdc, (LPSTR)PTR_SEG_TO_LIN(lp), (INT)wp, rc, dtflags);
942
943     case DST_ICON:
944         return DrawIcon(hdc, rc->left, rc->top, (HICON)lp);
945
946     case DST_BITMAP:
947         memdc = CreateCompatibleDC(hdc);
948         if(!memdc) return FALSE;
949         hbmsave = (HBITMAP)SelectObject(memdc, (HBITMAP)lp);
950         if(!hbmsave) 
951         {
952             DeleteDC(memdc);
953             return FALSE;
954         }
955         retval = BitBlt(hdc, rc->left, rc->top, cx, cy, memdc, 0, 0, SRCCOPY);
956         SelectObject(memdc, hbmsave);
957         DeleteDC(memdc);
958         return retval;
959             
960     case DST_COMPLEX:
961         if(func)
962             if(_32bit)
963                 return func(hdc, lp, wp, cx, cy);
964             else
965                 return (BOOL)((DRAWSTATEPROC16)func)((HDC16)hdc, (LPARAM)lp, (WPARAM16)wp, (INT16)cx, (INT16)cy);
966         else
967             return FALSE;
968     }
969     return FALSE;
970 }
971
972 /**********************************************************************
973  *      PAINTING_DrawState32()
974  */
975 static BOOL PAINTING_DrawState(HDC hdc, HBRUSH hbr, 
976                                    DRAWSTATEPROC func, LPARAM lp, WPARAM wp,
977                                    INT x, INT y, INT cx, INT cy, 
978                                    UINT flags, BOOL unicode, BOOL _32bit)
979 {
980     HBITMAP hbm, hbmsave;
981     HFONT hfsave;
982     HBRUSH hbsave;
983     HDC memdc;
984     RECT rc;
985     UINT dtflags = DT_NOCLIP;
986     COLORREF fg, bg;
987     UINT opcode = flags & 0xf;
988     INT len = wp;
989     BOOL retval, tmp;
990
991     if((opcode == DST_TEXT || opcode == DST_PREFIXTEXT) && !len)    /* The string is '\0' terminated */
992     {
993         if(unicode)
994             len = lstrlenW((LPWSTR)lp);
995         else if(_32bit)
996             len = lstrlenA((LPSTR)lp);
997         else
998             len = lstrlenA((LPSTR)PTR_SEG_TO_LIN(lp));
999     }
1000
1001     /* Find out what size the image has if not given by caller */
1002     if(!cx || !cy)
1003     {
1004         SIZE s;
1005         CURSORICONINFO *ici;
1006         BITMAPOBJ *bmp;
1007
1008         switch(opcode)
1009         {
1010         case DST_TEXT:
1011         case DST_PREFIXTEXT:
1012             if(unicode)
1013                 retval = GetTextExtentPoint32W(hdc, (LPWSTR)lp, len, &s);
1014             else if(_32bit)
1015                 retval = GetTextExtentPoint32A(hdc, (LPSTR)lp, len, &s);
1016             else
1017                 retval = GetTextExtentPoint32A(hdc, PTR_SEG_TO_LIN(lp), len, &s);
1018             if(!retval) return FALSE;
1019             break;
1020             
1021         case DST_ICON:
1022             ici = (CURSORICONINFO *)GlobalLock16((HGLOBAL16)lp);
1023             if(!ici) return FALSE;
1024             s.cx = ici->nWidth;
1025             s.cy = ici->nHeight;
1026             GlobalUnlock16((HGLOBAL16)lp);
1027             break;            
1028
1029         case DST_BITMAP:
1030             bmp = (BITMAPOBJ *)GDI_GetObjPtr((HBITMAP16)lp, BITMAP_MAGIC);
1031             if(!bmp) return FALSE;
1032             s.cx = bmp->bitmap.bmWidth;
1033             s.cy = bmp->bitmap.bmHeight;
1034             break;
1035             
1036         case DST_COMPLEX: /* cx and cy must be set in this mode */
1037             return FALSE;
1038         }
1039                     
1040         if(!cx) cx = s.cx;
1041         if(!cy) cy = s.cy;
1042     }
1043
1044     rc.left   = x;
1045     rc.top    = y;
1046     rc.right  = x + cx;
1047     rc.bottom = y + cy;
1048
1049     if(flags & DSS_RIGHT)    /* This one is not documented in the win32.hlp file */
1050         dtflags |= DT_RIGHT;
1051     if(opcode == DST_TEXT)
1052         dtflags |= DT_NOPREFIX;
1053
1054     /* For DSS_NORMAL we just jam in the image and return */
1055     if((flags & 0x7ff0) == DSS_NORMAL)
1056     {
1057         return PAINTING_DrawStateJam(hdc, opcode, func, lp, len, &rc, dtflags, unicode, _32bit);
1058     }
1059
1060     /* For all other states we need to convert the image to B/W in a local bitmap */
1061     /* before it is displayed */
1062     fg = SetTextColor(hdc, RGB(0, 0, 0));
1063     bg = SetBkColor(hdc, RGB(255, 255, 255));
1064     hbm = (HBITMAP)NULL; hbmsave = (HBITMAP)NULL;
1065     memdc = (HDC)NULL; hbsave = (HBRUSH)NULL;
1066     retval = FALSE; /* assume failure */
1067     
1068     /* From here on we must use "goto cleanup" when something goes wrong */
1069     hbm     = CreateBitmap(cx, cy, 1, 1, NULL);
1070     if(!hbm) goto cleanup;
1071     memdc   = CreateCompatibleDC(hdc);
1072     if(!memdc) goto cleanup;
1073     hbmsave = (HBITMAP)SelectObject(memdc, hbm);
1074     if(!hbmsave) goto cleanup;
1075     rc.left = rc.top = 0;
1076     rc.right = cx;
1077     rc.bottom = cy;
1078     if(!FillRect(memdc, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH))) goto cleanup;
1079     SetBkColor(memdc, RGB(255, 255, 255));
1080     SetTextColor(memdc, RGB(0, 0, 0));
1081     hfsave  = (HFONT)SelectObject(memdc, GetCurrentObject(hdc, OBJ_FONT));
1082     if(!hfsave && (opcode == DST_TEXT || opcode == DST_PREFIXTEXT)) goto cleanup;
1083     tmp = PAINTING_DrawStateJam(memdc, opcode, func, lp, len, &rc, dtflags, unicode, _32bit);
1084     if(hfsave) SelectObject(memdc, hfsave);
1085     if(!tmp) goto cleanup;
1086     
1087     /* These states cause the image to be dithered */
1088     if(flags & (DSS_UNION|DSS_DISABLED))
1089     {
1090         hbsave = (HBRUSH)SelectObject(memdc, CACHE_GetPattern55AABrush());
1091         if(!hbsave) goto cleanup;
1092         tmp = PatBlt(memdc, 0, 0, cx, cy, 0x00FA0089);
1093         if(hbsave) SelectObject(memdc, hbsave);
1094         if(!tmp) goto cleanup;
1095     }
1096
1097     hbsave = (HBRUSH)SelectObject(hdc, hbr ? hbr : GetStockObject(WHITE_BRUSH));
1098     if(!hbsave) goto cleanup;
1099     
1100     if(!BitBlt(hdc, x, y, cx, cy, memdc, 0, 0, 0x00B8074A)) goto cleanup;
1101     
1102     /* DSS_DEFAULT makes the image boldface */
1103     if(flags & DSS_DEFAULT)
1104     {
1105         if(!BitBlt(hdc, x+1, y, cx, cy, memdc, 0, 0, 0x00B8074A)) goto cleanup;
1106     }
1107
1108     retval = TRUE; /* We succeeded */
1109     
1110 cleanup:    
1111     SetTextColor(hdc, fg);
1112     SetBkColor(hdc, bg);
1113
1114     if(hbsave)  SelectObject(hdc, hbsave);
1115     if(hbmsave) SelectObject(memdc, hbmsave);
1116     if(hbm)     DeleteObject(hbm);
1117     if(memdc)   DeleteDC(memdc);
1118
1119     return retval;
1120 }
1121
1122 /**********************************************************************
1123  *      DrawState32A()   (USER32.162)
1124  */
1125 BOOL WINAPI DrawStateA(HDC hdc, HBRUSH hbr,
1126                    DRAWSTATEPROC func, LPARAM ldata, WPARAM wdata,
1127                    INT x, INT y, INT cx, INT cy, UINT flags)
1128 {
1129     return PAINTING_DrawState(hdc, hbr, func, ldata, wdata, x, y, cx, cy, flags, FALSE, TRUE);
1130 }
1131
1132 /**********************************************************************
1133  *      DrawState32W()   (USER32.163)
1134  */
1135 BOOL WINAPI DrawStateW(HDC hdc, HBRUSH hbr,
1136                    DRAWSTATEPROC func, LPARAM ldata, WPARAM wdata,
1137                    INT x, INT y, INT cx, INT cy, UINT flags)
1138 {
1139     return PAINTING_DrawState(hdc, hbr, func, ldata, wdata, x, y, cx, cy, flags, TRUE, TRUE);
1140 }
1141
1142 /**********************************************************************
1143  *      DrawState16()   (USER.449)
1144  */
1145 BOOL16 WINAPI DrawState16(HDC16 hdc, HBRUSH16 hbr,
1146                    DRAWSTATEPROC16 func, LPARAM ldata, WPARAM16 wdata,
1147                    INT16 x, INT16 y, INT16 cx, INT16 cy, UINT16 flags)
1148 {
1149     return PAINTING_DrawState(hdc, hbr, (DRAWSTATEPROC)func, ldata, wdata, x, y, cx, cy, flags, FALSE, FALSE);
1150 }
1151
1152
1153 /******************************************************************************
1154  * PolyBezier16 [GDI.502]
1155  */
1156 BOOL16 WINAPI PolyBezier16( HDC16 hDc, const POINT16* lppt, INT16 cPoints )
1157 {
1158     int i;
1159     BOOL16 ret;
1160     LPPOINT pt32 = (LPPOINT)HeapAlloc( GetProcessHeap(), 0,
1161                                            cPoints*sizeof(POINT) );
1162     if(!pt32) return FALSE;
1163     for (i=cPoints;i--;) CONV_POINT16TO32(&(lppt[i]),&(pt32[i]));
1164     ret= PolyBezier(hDc, pt32, cPoints);
1165     HeapFree( GetProcessHeap(), 0, pt32 );
1166     return ret;
1167 }
1168
1169 /******************************************************************************
1170  * PolyBezierTo16 [GDI.503]
1171  */
1172 BOOL16 WINAPI PolyBezierTo16( HDC16 hDc, const POINT16* lppt, INT16 cPoints )
1173 {
1174     int i;
1175     BOOL16 ret;
1176     LPPOINT pt32 = (LPPOINT)HeapAlloc( GetProcessHeap(), 0,
1177                                            cPoints*sizeof(POINT) );
1178     if(!pt32) return FALSE;
1179     for (i=cPoints;i--;) CONV_POINT16TO32(&(lppt[i]),&(pt32[i]));
1180     ret= PolyBezierTo(hDc, pt32, cPoints);
1181     HeapFree( GetProcessHeap(), 0, pt32 );
1182     return ret;
1183 }
1184
1185 /******************************************************************************
1186  * PolyBezier32 [GDI32.268]
1187  * Draws one or more Bezier curves
1188  *
1189  * PARAMS
1190  *    hDc     [I] Handle to device context
1191  *    lppt    [I] Pointer to endpoints and control points
1192  *    cPoints [I] Count of endpoints and control points
1193  *
1194  * RETURNS STD
1195  */
1196 BOOL WINAPI PolyBezier( HDC hdc, const POINT* lppt, DWORD cPoints )
1197 {
1198     DC * dc = DC_GetDCPtr( hdc );
1199     if(!dc) return FALSE;
1200     if(dc && PATH_IsPathOpen(dc->w.path))
1201         FIXME("PATH_PolyBezier is not implemented!\n");
1202 /*        if(!PATH_PolyBezier(hdc, x, y))
1203            return FALSE; */
1204     return dc->funcs->pPolyBezier&&
1205            dc->funcs->pPolyBezier(dc, lppt[0], lppt+1, cPoints-1);
1206 }
1207
1208 /******************************************************************************
1209  * PolyBezierTo32 [GDI32.269]
1210  * Draws one or more Bezier curves
1211  *
1212  * PARAMS
1213  *    hDc     [I] Handle to device context
1214  *    lppt    [I] Pointer to endpoints and control points
1215  *    cPoints [I] Count of endpoints and control points
1216  *
1217  * RETURNS STD
1218  */
1219 BOOL WINAPI PolyBezierTo( HDC hdc, const POINT* lppt, DWORD cPoints )
1220 {
1221     DC * dc = DC_GetDCPtr( hdc );
1222     POINT pt;
1223     BOOL ret;
1224     if(!dc) return FALSE;
1225     pt.x=dc->w.CursPosX;
1226     pt.y=dc->w.CursPosY;
1227     if(dc && PATH_IsPathOpen(dc->w.path))
1228         FIXME("PATH_PolyBezierTo is not implemented!\n");
1229 /*        if(!PATH_PolyBezier(hdc, x, y))
1230            return FALSE; */
1231     ret= dc->funcs->pPolyBezier &&
1232            dc->funcs->pPolyBezier(dc, pt, lppt, cPoints);
1233     if( dc->funcs->pMoveToEx)
1234            dc->funcs->pMoveToEx(dc,lppt[cPoints].x,lppt[cPoints].y,&pt);
1235     return ret;
1236 }
1237
1238 /***************************************************************
1239  *      AngleArc (GDI32.5)
1240  *
1241  */
1242 BOOL WINAPI AngleArc(HDC hdc, INT x, INT y, DWORD dwRadius,
1243                        FLOAT eStartAngle, FLOAT eSweepAngle)
1244 {
1245         FIXME("AngleArc, stub\n");
1246         return 0;
1247 }
1248
1249 /***************************************************************
1250  *      PolyDraw (GDI32.270)
1251  *
1252  */
1253 BOOL WINAPI PolyDraw(HDC hdc, const POINT *lppt, const BYTE *lpbTypes,
1254                        DWORD cCount)
1255 {
1256         FIXME("PolyDraw, stub\n");
1257         return 0;
1258 }