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