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