From f0f8da58707fce042b60ed06f60b662deb01d986 Mon Sep 17 00:00:00 2001
From: Huw D M Davies <h.davies1@physics.ox.ac.uk>
Date: Sun, 5 Dec 1999 23:54:02 +0000
Subject: [PATCH] Fixes several bugs in gdi path handling. Adds *Path functions
 to dc funcs table + add EnhMetaFile recording. Separate out
 Polylne/PolylineTo and PolyBezier/PolyBezierTo in dc funcs table to enable
 proper enhmetafile recording. The current position update in *To functions is
 now handled by the main function and not in the drivers. Move USER functions
 from graphics/painting.c -> windows/painting.c

---
 graphics/enhmetafiledrv/dc.c       | 116 ++++++
 graphics/enhmetafiledrv/graphics.c |  13 +-
 graphics/enhmetafiledrv/init.c     |  19 +-
 graphics/metafiledrv/dc.c          |  49 +++
 graphics/metafiledrv/graphics.c    |  29 +-
 graphics/metafiledrv/init.c        |  19 +-
 graphics/painting.c                | 591 +++++------------------------
 graphics/path.c                    | 274 +++++++++----
 graphics/psdrv/graphics.c          |  19 -
 graphics/psdrv/init.c              |  21 +-
 graphics/ttydrv/graphics.c         |  27 +-
 graphics/ttydrv/init.c             |  21 +-
 graphics/win16drv/init.c           |  19 +-
 graphics/x11drv/graphics.c         |  50 ++-
 graphics/x11drv/init.c             |  21 +-
 include/enhmetafiledrv.h           |  10 +
 include/gdi.h                      |  17 +-
 include/metafiledrv.h              |  11 +
 include/path.h                     |   4 +-
 include/psdrv.h                    |   1 -
 include/ttydrv.h                   |   3 +-
 include/x11drv.h                   |   6 +-
 windows/painting.c                 | 406 ++++++++++++++++++++
 23 files changed, 1070 insertions(+), 676 deletions(-)

diff --git a/graphics/enhmetafiledrv/dc.c b/graphics/enhmetafiledrv/dc.c
index 4eac6c12539..7ad21dd9a40 100644
--- a/graphics/enhmetafiledrv/dc.c
+++ b/graphics/enhmetafiledrv/dc.c
@@ -5,6 +5,9 @@
  *
  */
 #include "enhmetafiledrv.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(enhmetafile)
 
 INT EMFDRV_SaveDC( DC *dc )
 {
@@ -121,3 +124,116 @@ DWORD EMFDRV_SetMapperFlags( DC *dc, DWORD flags )
 
     return EMFDRV_WriteRecord( dc, &emr.emr );
 }
+
+BOOL EMFDRV_AbortPath( DC *dc )
+{
+    EMRABORTPATH emr;
+
+    emr.emr.iType = EMR_ABORTPATH;
+    emr.emr.nSize = sizeof(emr);
+
+    return EMFDRV_WriteRecord( dc, &emr.emr );
+}
+
+BOOL EMFDRV_BeginPath( DC *dc )
+{
+    EMRBEGINPATH emr;
+
+    emr.emr.iType = EMR_BEGINPATH;
+    emr.emr.nSize = sizeof(emr);
+
+    return EMFDRV_WriteRecord( dc, &emr.emr );
+}
+
+BOOL EMFDRV_CloseFigure( DC *dc )
+{
+    EMRCLOSEFIGURE emr;
+
+    emr.emr.iType = EMR_CLOSEFIGURE;
+    emr.emr.nSize = sizeof(emr);
+
+    return EMFDRV_WriteRecord( dc, &emr.emr );
+}
+
+BOOL EMFDRV_EndPath( DC *dc )
+{
+    EMRENDPATH emr;
+
+    emr.emr.iType = EMR_ENDPATH;
+    emr.emr.nSize = sizeof(emr);
+
+    return EMFDRV_WriteRecord( dc, &emr.emr );
+}
+
+BOOL EMFDRV_FillPath( DC *dc )
+{
+    EMRFILLPATH emr;
+
+    emr.emr.iType = EMR_FILLPATH;
+    emr.emr.nSize = sizeof(emr);
+    FIXME("Bounds\n");
+    emr.rclBounds.left = 0;
+    emr.rclBounds.top = 0;
+    emr.rclBounds.right = 0;
+    emr.rclBounds.bottom = 0;
+    return EMFDRV_WriteRecord( dc, &emr.emr );
+}
+
+BOOL EMFDRV_FlattenPath( DC *dc )
+{
+    EMRFLATTENPATH emr;
+
+    emr.emr.iType = EMR_FLATTENPATH;
+    emr.emr.nSize = sizeof(emr);
+
+    return EMFDRV_WriteRecord( dc, &emr.emr );
+}
+
+BOOL EMFDRV_SelectClipPath( DC *dc, INT iMode )
+{
+    EMRSELECTCLIPPATH emr;
+
+    emr.emr.iType = EMR_SELECTCLIPPATH;
+    emr.emr.nSize = sizeof(emr);
+    emr.iMode = iMode;
+
+    return EMFDRV_WriteRecord( dc, &emr.emr );
+}
+
+BOOL EMFDRV_StrokeAndFillPath( DC *dc )
+{
+    EMRSTROKEANDFILLPATH emr;
+
+    emr.emr.iType = EMR_STROKEANDFILLPATH;
+    emr.emr.nSize = sizeof(emr);
+    FIXME("Bounds\n");
+    emr.rclBounds.left = 0;
+    emr.rclBounds.top = 0;
+    emr.rclBounds.right = 0;
+    emr.rclBounds.bottom = 0;
+    return EMFDRV_WriteRecord( dc, &emr.emr );
+}
+
+BOOL EMFDRV_StrokePath( DC *dc )
+{
+    EMRSTROKEPATH emr;
+
+    emr.emr.iType = EMR_STROKEPATH;
+    emr.emr.nSize = sizeof(emr);
+    FIXME("Bounds\n");
+    emr.rclBounds.left = 0;
+    emr.rclBounds.top = 0;
+    emr.rclBounds.right = 0;
+    emr.rclBounds.bottom = 0;
+    return EMFDRV_WriteRecord( dc, &emr.emr );
+}
+
+BOOL EMFDRV_WidenPath( DC *dc )
+{
+    EMRWIDENPATH emr;
+
+    emr.emr.iType = EMR_WIDENPATH;
+    emr.emr.nSize = sizeof(emr);
+
+    return EMFDRV_WriteRecord( dc, &emr.emr );
+}
diff --git a/graphics/enhmetafiledrv/graphics.c b/graphics/enhmetafiledrv/graphics.c
index 242b01fccee..187027a5a77 100644
--- a/graphics/enhmetafiledrv/graphics.c
+++ b/graphics/enhmetafiledrv/graphics.c
@@ -28,16 +28,7 @@ EMFDRV_MoveToEx(DC *dc,INT x,INT y,LPPOINT pt)
     emr.ptl.x = x;
     emr.ptl.y = y;
 
-    if(!EMFDRV_WriteRecord( dc, &emr.emr ))
-    	return FALSE;
-
-    if (pt) {
-	pt->x = dc->w.CursPosX;
-	pt->y = dc->w.CursPosY;
-    }
-    dc->w.CursPosX = x;
-    dc->w.CursPosY = y;
-    return TRUE;
+    return EMFDRV_WriteRecord( dc, &emr.emr );
 }
 
 /***********************************************************************
@@ -64,8 +55,6 @@ EMFDRV_LineTo( DC *dc, INT x, INT y )
 
     EMFDRV_UpdateBBox( dc, &bounds );
 
-    dc->w.CursPosX = x;
-    dc->w.CursPosY = y;
     return TRUE;
 }
 
diff --git a/graphics/enhmetafiledrv/init.c b/graphics/enhmetafiledrv/init.c
index fb51af6bec6..f3a5e149b9d 100644
--- a/graphics/enhmetafiledrv/init.c
+++ b/graphics/enhmetafiledrv/init.c
@@ -21,10 +21,15 @@ DEFAULT_DEBUG_CHANNEL(enhmetafile)
 static const DC_FUNCTIONS EMFDRV_Funcs =
 {
     NULL,                            /* pAbortDoc */
+    EMFDRV_AbortPath,                /* pAbortPath */
+    NULL,                            /* pAngleArc */
     EMFDRV_Arc,                      /* pArc */
+    NULL,                            /* pArcTo */
+    EMFDRV_BeginPath,                /* pBeginPath */
     NULL,                            /* pBitBlt */
     NULL,                            /* pBitmapBits */	
     EMFDRV_Chord,                    /* pChord */
+    EMFDRV_CloseFigure,              /* pCloseFigure */
     NULL,                            /* pCreateBitmap */
     NULL, /* no implementation */    /* pCreateDC */
     NULL,                            /* pCreateDIBSection */
@@ -35,13 +40,16 @@ static const DC_FUNCTIONS EMFDRV_Funcs =
     EMFDRV_Ellipse,                  /* pEllipse */
     NULL,                            /* pEndDoc */
     NULL,                            /* pEndPage */
+    EMFDRV_EndPath,                  /* pEndPath */
     NULL,                            /* pEnumDeviceFonts */
     NULL,                            /* pEscape */
     EMFDRV_ExcludeClipRect,          /* pExcludeClipRect */
     NULL,                            /* pExtDeviceMode */
     EMFDRV_ExtFloodFill,             /* pExtFloodFill */
     NULL,                            /* pExtTextOut */
+    EMFDRV_FillPath,                 /* pFillPath */
     EMFDRV_FillRgn,                  /* pFillRgn */
+    EMFDRV_FlattenPath,              /* pFlattenPath */
     EMFDRV_FrameRgn,                 /* pFrameRgn */
     NULL,                            /* pGetCharWidth */
     NULL, /* no implementation */    /* pGetPixel */
@@ -58,11 +66,14 @@ static const DC_FUNCTIONS EMFDRV_Funcs =
     EMFDRV_PaintRgn,                 /* pPaintRgn */
     NULL,                            /* pPatBlt */
     EMFDRV_Pie,                      /* pPie */
+    NULL,                            /* pPolyBezier */
+    NULL,                            /* pPolyBezierTo */
+    NULL,                            /* pPolyDraw */
     EMFDRV_PolyPolygon,              /* pPolyPolygon */
     EMFDRV_PolyPolyline,             /* pPolyPolyline */
     EMFDRV_Polygon,                  /* pPolygon */
     EMFDRV_Polyline,                 /* pPolyline */
-    NULL,                            /* pPolyBezier */
+    NULL,                            /* pPolylineTo */
     NULL,                            /* pRealizePalette */
     EMFDRV_Rectangle,                /* pRectangle */
     EMFDRV_RestoreDC,                /* pRestoreDC */
@@ -70,6 +81,7 @@ static const DC_FUNCTIONS EMFDRV_Funcs =
     EMFDRV_SaveDC,                   /* pSaveDC */
     EMFDRV_ScaleViewportExt,         /* pScaleViewportExt */
     EMFDRV_ScaleWindowExt,           /* pScaleWindowExt */
+    EMFDRV_SelectClipPath,           /* pSelectClipPath */
     NULL,                            /* pSelectClipRgn */
     EMFDRV_SelectObject,             /* pSelectObject */
     NULL,                            /* pSelectPalette */
@@ -95,7 +107,10 @@ static const DC_FUNCTIONS EMFDRV_Funcs =
     NULL,                            /* pStartDoc */
     NULL,                            /* pStartPage */
     NULL,                            /* pStretchBlt */
-    NULL                             /* pStretchDIBits */
+    NULL,                            /* pStretchDIBits */
+    EMFDRV_StrokeAndFillPath,        /* pStrokeAndFillPath */
+    EMFDRV_StrokePath,               /* pStrokePath */
+    EMFDRV_WidenPath                 /* pWiddenPath */
 };
 
 
diff --git a/graphics/metafiledrv/dc.c b/graphics/metafiledrv/dc.c
index 89e26417e65..0d28dfbd62b 100644
--- a/graphics/metafiledrv/dc.c
+++ b/graphics/metafiledrv/dc.c
@@ -81,3 +81,52 @@ DWORD MFDRV_SetMapperFlags( DC *dc, DWORD flags )
 			     LOWORD(flags) );
 }
 
+BOOL MFDRV_AbortPath( DC *dc )
+{
+    return FALSE;
+}
+
+BOOL MFDRV_BeginPath( DC *dc )
+{
+    return FALSE;
+}
+
+BOOL MFDRV_CloseFigure( DC *dc )
+{
+    return FALSE;
+}
+
+BOOL MFDRV_EndPath( DC *dc )
+{
+    return FALSE;
+}
+
+BOOL MFDRV_FillPath( DC *dc )
+{
+    return FALSE;
+}
+
+BOOL MFDRV_FlattenPath( DC *dc )
+{
+    return FALSE;
+}
+
+BOOL MFDRV_SelectClipPath( DC *dc, INT iMode )
+{
+    return FALSE;
+}
+
+BOOL MFDRV_StrokeAndFillPath( DC *dc )
+{
+    return FALSE;
+}
+
+BOOL MFDRV_StrokePath( DC *dc )
+{
+    return FALSE;
+}
+
+BOOL MFDRV_WidenPath( DC *dc )
+{
+    return FALSE;
+}
diff --git a/graphics/metafiledrv/graphics.c b/graphics/metafiledrv/graphics.c
index 3c29fb81848..c96e6803cc1 100644
--- a/graphics/metafiledrv/graphics.c
+++ b/graphics/metafiledrv/graphics.c
@@ -10,7 +10,6 @@
 #include "gdi.h"
 #include "dc.h"
 #include "region.h"
-#include "xmalloc.h"
 #include "metafiledrv.h"
 #include "heap.h"
 #include "debugtools.h"
@@ -23,17 +22,7 @@ DEFAULT_DEBUG_CHANNEL(metafile)
 BOOL
 MFDRV_MoveToEx(DC *dc,INT x,INT y,LPPOINT pt)
 {
-    if (!MFDRV_MetaParam2(dc,META_MOVETO,x,y))
-    	return FALSE;
-
-    if (pt)
-    {
-	pt->x = dc->w.CursPosX;
-	pt->y = dc->w.CursPosY;
-    }
-    dc->w.CursPosX = x;
-    dc->w.CursPosY = y;
-    return TRUE;
+    return MFDRV_MetaParam2(dc,META_MOVETO,x,y);
 }
 
 /***********************************************************************
@@ -154,11 +143,12 @@ MFDRV_Polyline( DC *dc, const POINT* pt, INT count )
     LPPOINT16	pt16;
     BOOL16	ret;
 
-    pt16 = (LPPOINT16)xmalloc(sizeof(POINT16)*count);
+    pt16 = (LPPOINT16)HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16)*count );
+    if(!pt16) return FALSE;
     for (i=count;i--;) CONV_POINT32TO16(&(pt[i]),&(pt16[i]));
     ret = MFDRV_MetaPoly(dc, META_POLYLINE, pt16, count); 
 
-    free(pt16);
+    HeapFree( GetProcessHeap(), 0, pt16 );
     return ret;
 }
 
@@ -173,11 +163,12 @@ MFDRV_Polygon( DC *dc, const POINT* pt, INT count )
     LPPOINT16	pt16;
     BOOL16	ret;
 
-    pt16 = (LPPOINT16)xmalloc(sizeof(POINT16)*count);
+    pt16 = (LPPOINT16) HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16)*count );
+    if(!pt16) return FALSE;
     for (i=count;i--;) CONV_POINT32TO16(&(pt[i]),&(pt16[i]));
     ret = MFDRV_MetaPoly(dc, META_POLYGON, pt16, count); 
 
-    free(pt16);
+    HeapFree( GetProcessHeap(), 0, pt16 );
     return ret;
 }
 
@@ -194,10 +185,12 @@ MFDRV_PolyPolygon( DC *dc, const POINT* pt, const INT* counts, UINT polygons)
     BOOL	ret;
 
     for (i=0;i<polygons;i++) {
-    	pt16=(LPPOINT16)xmalloc(sizeof(POINT16)*counts[i]);
+    	pt16=(LPPOINT16)HeapAlloc( GetProcessHeap(), 0, 
+				   sizeof(POINT16) * counts[i] );
+	if(!pt16) return FALSE;
 	for (j=counts[i];j--;) CONV_POINT32TO16(&(curpt[j]),&(pt16[j]));
 	ret = MFDRV_MetaPoly(dc, META_POLYGON, pt16, counts[i]);
-	free(pt16);
+	HeapFree( GetProcessHeap(), 0, pt16 );
 	if (!ret)
 	    return FALSE;
 	curpt+=counts[i];
diff --git a/graphics/metafiledrv/init.c b/graphics/metafiledrv/init.c
index 439318d6f3d..5bbb301b780 100644
--- a/graphics/metafiledrv/init.c
+++ b/graphics/metafiledrv/init.c
@@ -20,10 +20,15 @@ DEFAULT_DEBUG_CHANNEL(metafile)
 static const DC_FUNCTIONS MFDRV_Funcs =
 {
     NULL,                            /* pAbortDoc */
+    MFDRV_AbortPath,                 /* pAbortPath */
+    NULL,                            /* pAngleArc */
     MFDRV_Arc,                       /* pArc */
+    NULL,                            /* pArcTo */
+    MFDRV_BeginPath,                 /* pBeginPath */
     MFDRV_BitBlt,                    /* pBitBlt */
     NULL,                            /* pBitmapBits */	
     MFDRV_Chord,                     /* pChord */
+    MFDRV_CloseFigure,               /* pCloseFigure */
     NULL,                            /* pCreateBitmap */
     NULL, /* no implementation */    /* pCreateDC */
     NULL,                            /* pCreateDIBSection */
@@ -34,13 +39,16 @@ static const DC_FUNCTIONS MFDRV_Funcs =
     MFDRV_Ellipse,                   /* pEllipse */
     NULL,                            /* pEndDoc */
     NULL,                            /* pEndPage */
+    MFDRV_EndPath,                   /* pEndPath */
     NULL,                            /* pEnumDeviceFonts */
     NULL,                            /* pEscape */
     MFDRV_ExcludeClipRect,           /* pExcludeClipRect */
     NULL,                            /* pExtDeviceMode */
     MFDRV_ExtFloodFill,              /* pExtFloodFill */
     MFDRV_ExtTextOut,                /* pExtTextOut */
+    MFDRV_FillPath,                  /* pFillPath */
     MFDRV_FillRgn,                   /* pFillRgn */
+    MFDRV_FlattenPath,               /* pFlattenPath */
     MFDRV_FrameRgn,                  /* pFrameRgn */
     NULL,                            /* pGetCharWidth */
     NULL, /* no implementation */    /* pGetPixel */
@@ -57,11 +65,14 @@ static const DC_FUNCTIONS MFDRV_Funcs =
     MFDRV_PaintRgn,                  /* pPaintRgn */
     MFDRV_PatBlt,                    /* pPatBlt */
     MFDRV_Pie,                       /* pPie */
+    NULL,                            /* pPolyBezier */
+    NULL,                            /* pPolyBezierTo */
+    NULL,                            /* pPolyDraw */
     MFDRV_PolyPolygon,               /* pPolyPolygon */
     NULL,                            /* pPolyPolyline */
     MFDRV_Polygon,                   /* pPolygon */
     MFDRV_Polyline,                  /* pPolyline */
-    NULL,                            /* pPolyBezier */
+    NULL,                            /* pPolylineTo */
     NULL,                            /* pRealizePalette */
     MFDRV_Rectangle,                 /* pRectangle */
     MFDRV_RestoreDC,                 /* pRestoreDC */
@@ -69,6 +80,7 @@ static const DC_FUNCTIONS MFDRV_Funcs =
     MFDRV_SaveDC,                    /* pSaveDC */
     MFDRV_ScaleViewportExt,          /* pScaleViewportExt */
     MFDRV_ScaleWindowExt,            /* pScaleWindowExt */
+    MFDRV_SelectClipPath,            /* pSelectClipPath */
     NULL,                            /* pSelectClipRgn */
     MFDRV_SelectObject,              /* pSelectObject */
     NULL,                            /* pSelectPalette */
@@ -94,7 +106,10 @@ static const DC_FUNCTIONS MFDRV_Funcs =
     NULL,                            /* pStartDoc */
     NULL,                            /* pStartPage */
     MFDRV_StretchBlt,                /* pStretchBlt */
-    MFDRV_StretchDIBits              /* pStretchDIBits */
+    MFDRV_StretchDIBits,             /* pStretchDIBits */
+    MFDRV_StrokeAndFillPath,         /* pStrokeAndFillPath */
+    MFDRV_StrokePath,                /* pStrokePath */
+    MFDRV_WidenPath                  /* pWidenPath */
 };
 
 
diff --git a/graphics/painting.c b/graphics/painting.c
index cb32e17aa85..54a0190da9d 100644
--- a/graphics/painting.c
+++ b/graphics/painting.c
@@ -31,23 +31,29 @@ BOOL16 WINAPI LineTo16( HDC16 hdc, INT16 x, INT16 y )
 
 
 /***********************************************************************
- *           LineTo32    (GDI32.249)
+ *           LineTo    (GDI32.249)
  */
 BOOL WINAPI LineTo( HDC hdc, INT x, INT y )
 {
     DC * dc = DC_GetDCPtr( hdc );
+    BOOL ret;
 
-    if(dc && PATH_IsPathOpen(dc->w.path))
-        if(!PATH_LineTo(hdc, x, y))
-	   return FALSE;
-    
-    return dc && dc->funcs->pLineTo &&
-    	   dc->funcs->pLineTo(dc,x,y);
+    if(!dc) return FALSE;
+
+    if(PATH_IsPathOpen(dc->w.path))
+        ret = PATH_LineTo(hdc, x, y);
+    else
+        ret = dc->funcs->pLineTo && dc->funcs->pLineTo(dc,x,y);
+    if(ret) {
+        dc->w.CursPosX = x;
+        dc->w.CursPosY = y;
+    }
+    return ret;
 }
 
 
 /***********************************************************************
- *           MoveTo    (GDI.20)
+ *           MoveTo16    (GDI.20)
  */
 DWORD WINAPI MoveTo16( HDC16 hdc, INT16 x, INT16 y )
 {
@@ -74,18 +80,27 @@ BOOL16 WINAPI MoveToEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
 
 
 /***********************************************************************
- *           MoveToEx32    (GDI32.254)
+ *           MoveToEx    (GDI32.254)
  */
 BOOL WINAPI MoveToEx( HDC hdc, INT x, INT y, LPPOINT pt )
 {
     DC * dc = DC_GetDCPtr( hdc );
-  
-    if(dc && PATH_IsPathOpen(dc->w.path))
-        if(!PATH_MoveTo(hdc))
-	    return FALSE;
 
-    return dc && dc->funcs->pMoveToEx &&
-    	   dc->funcs->pMoveToEx(dc,x,y,pt);
+    if(!dc) return FALSE;
+
+    if(pt) {
+        pt->x = dc->w.CursPosX;
+        pt->y = dc->w.CursPosY;
+    }
+    dc->w.CursPosX = x;
+    dc->w.CursPosY = y;
+
+    if(PATH_IsPathOpen(dc->w.path))
+        return PATH_MoveTo(hdc);
+
+    if(dc->funcs->pMoveToEx)
+        return dc->funcs->pMoveToEx(dc,x,y,pt);
+    return TRUE;
 }
 
 
@@ -103,7 +118,7 @@ BOOL16 WINAPI Arc16( HDC16 hdc, INT16 left, INT16 top, INT16 right,
 
 
 /***********************************************************************
- *           Arc32    (GDI32.7)
+ *           Arc    (GDI32.7)
  */
 BOOL WINAPI Arc( HDC hdc, INT left, INT top, INT right,
                      INT bottom, INT xstart, INT ystart,
@@ -112,9 +127,8 @@ BOOL WINAPI Arc( HDC hdc, INT left, INT top, INT right,
     DC * dc = DC_GetDCPtr( hdc );
   
     if(dc && PATH_IsPathOpen(dc->w.path))
-        if(!PATH_Arc(hdc, left, top, right, bottom, xstart, ystart, xend,
-	   yend))
-	   return FALSE;
+        return PATH_Arc(hdc, left, top, right, bottom, xstart, ystart, xend,
+	   yend);
     
     return dc && dc->funcs->pArc &&
     	   dc->funcs->pArc(dc,left,top,right,bottom,xstart,ystart,xend,yend);
@@ -130,8 +144,15 @@ BOOL WINAPI ArcTo( HDC hdc,
                      INT xend,   INT yend )
 {
     BOOL result;
+    DC * dc = DC_GetDCPtr( hdc );
 
-    /*
+    if(!dc) return FALSE;
+
+    if(dc->funcs->pArcTo)
+        return dc->funcs->pArcTo( dc, left, top, right, bottom,
+				  xstart, ystart, xend, yend );
+    /* 
+     * Else emulate it.
      * According to the documentation, a line is drawn from the current
      * position to the starting point of the arc.
      */
@@ -172,7 +193,7 @@ BOOL16 WINAPI Pie16( HDC16 hdc, INT16 left, INT16 top,
 
 
 /***********************************************************************
- *           Pie32   (GDI32.262)
+ *           Pie   (GDI32.262)
  */
 BOOL WINAPI Pie( HDC hdc, INT left, INT top,
                      INT right, INT bottom, INT xstart, INT ystart,
@@ -197,7 +218,7 @@ BOOL16 WINAPI Chord16( HDC16 hdc, INT16 left, INT16 top,
 
 
 /***********************************************************************
- *           Chord32    (GDI32.14)
+ *           Chord    (GDI32.14)
  */
 BOOL WINAPI Chord( HDC hdc, INT left, INT top,
                        INT right, INT bottom, INT xstart, INT ystart,
@@ -221,7 +242,7 @@ BOOL16 WINAPI Ellipse16( HDC16 hdc, INT16 left, INT16 top,
 
 
 /***********************************************************************
- *           Ellipse32    (GDI32.75)
+ *           Ellipse    (GDI32.75)
  */
 BOOL WINAPI Ellipse( HDC hdc, INT left, INT top,
                          INT right, INT bottom )
@@ -244,7 +265,7 @@ BOOL16 WINAPI Rectangle16( HDC16 hdc, INT16 left, INT16 top,
 
 
 /***********************************************************************
- *           Rectangle32    (GDI32.283)
+ *           Rectangle    (GDI32.283)
  */
 BOOL WINAPI Rectangle( HDC hdc, INT left, INT top,
                            INT right, INT bottom )
@@ -252,8 +273,7 @@ BOOL WINAPI Rectangle( HDC hdc, INT left, INT top,
     DC * dc = DC_GetDCPtr( hdc );
   
     if(dc && PATH_IsPathOpen(dc->w.path))
-        if(!PATH_Rectangle(hdc, left, top, right, bottom))
-           return FALSE;
+        return PATH_Rectangle(hdc, left, top, right, bottom);
 
     return dc && dc->funcs->pRectangle &&
     	   dc->funcs->pRectangle(dc,left,top,right,bottom);
@@ -271,7 +291,7 @@ BOOL16 WINAPI RoundRect16( HDC16 hdc, INT16 left, INT16 top, INT16 right,
 
 
 /***********************************************************************
- *           RoundRect32    (GDI32.291)
+ *           RoundRect    (GDI32.291)
  */
 BOOL WINAPI RoundRect( HDC hdc, INT left, INT top, INT right,
                            INT bottom, INT ell_width, INT ell_height )
@@ -288,106 +308,6 @@ BOOL WINAPI RoundRect( HDC hdc, INT left, INT top, INT right,
     }
 }
 
-
-/***********************************************************************
- *           FillRect16    (USER.81)
- */
-INT16 WINAPI FillRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
-{
-    HBRUSH16 prevBrush;
-
-    /* coordinates are logical so we cannot fast-check 'rect',
-     * it will be done later in the PatBlt().
-     */
-
-    if (!(prevBrush = SelectObject16( hdc, hbrush ))) return 0;
-    PatBlt( hdc, rect->left, rect->top,
-              rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
-    SelectObject16( hdc, prevBrush );
-    return 1;
-}
-
-
-/***********************************************************************
- *           FillRect32    (USER32.197)
- */
-INT WINAPI FillRect( HDC hdc, const RECT *rect, HBRUSH hbrush )
-{
-    HBRUSH prevBrush;
-
-    if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
-    PatBlt( hdc, rect->left, rect->top,
-              rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
-    SelectObject( hdc, prevBrush );
-    return 1;
-}
-
-
-/***********************************************************************
- *           InvertRect16    (USER.82)
- */
-void WINAPI InvertRect16( HDC16 hdc, const RECT16 *rect )
-{
-    PatBlt( hdc, rect->left, rect->top,
-              rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
-}
-
-
-/***********************************************************************
- *           InvertRect32    (USER32.330)
- */
-BOOL WINAPI InvertRect( HDC hdc, const RECT *rect )
-{
-    return PatBlt( hdc, rect->left, rect->top,
-		     rect->right - rect->left, rect->bottom - rect->top, 
-		     DSTINVERT );
-}
-
-
-/***********************************************************************
- *           FrameRect16    (USER.83)
- */
-INT16 WINAPI FrameRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
-{
-    HBRUSH16 prevBrush;
-    int left, top, right, bottom;
-
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) return FALSE;
-
-    left   = XLPTODP( dc, rect->left );
-    top    = YLPTODP( dc, rect->top );
-    right  = XLPTODP( dc, rect->right );
-    bottom = YLPTODP( dc, rect->bottom );
-
-    if ( (right <= left) || (bottom <= top) ) return 0;
-    if (!(prevBrush = SelectObject16( hdc, hbrush ))) return 0;
-    
-    PatBlt( hdc, rect->left, rect->top, 1,
-	      rect->bottom - rect->top, PATCOPY );
-    PatBlt( hdc, rect->right - 1, rect->top, 1,
-	      rect->bottom - rect->top, PATCOPY );
-    PatBlt( hdc, rect->left, rect->top,
-	      rect->right - rect->left, 1, PATCOPY );
-    PatBlt( hdc, rect->left, rect->bottom - 1,
-	      rect->right - rect->left, 1, PATCOPY );
-
-    SelectObject16( hdc, prevBrush );
-    return 1;
-}
-
-
-/***********************************************************************
- *           FrameRect32    (USER32.203)
- */
-INT WINAPI FrameRect( HDC hdc, const RECT *rect, HBRUSH hbrush )
-{
-    RECT16 rect16;
-    CONV_RECT32TO16( rect, &rect16 );
-    return FrameRect16( (HDC16)hdc, &rect16, (HBRUSH16)hbrush );
-}
-
-
 /***********************************************************************
  *           SetPixel16    (GDI.31)
  */
@@ -398,7 +318,7 @@ COLORREF WINAPI SetPixel16( HDC16 hdc, INT16 x, INT16 y, COLORREF color )
 
 
 /***********************************************************************
- *           SetPixel32    (GDI32.327)
+ *           SetPixel    (GDI32.327)
  */
 COLORREF WINAPI SetPixel( HDC hdc, INT x, INT y, COLORREF color )
 {
@@ -409,7 +329,7 @@ COLORREF WINAPI SetPixel( HDC hdc, INT x, INT y, COLORREF color )
 }
 
 /***********************************************************************
- *           SetPixelV32    (GDI32.329)
+ *           SetPixelV    (GDI32.329)
  */
 BOOL WINAPI SetPixelV( HDC hdc, INT x, INT y, COLORREF color )
 {
@@ -430,7 +350,7 @@ COLORREF WINAPI GetPixel16( HDC16 hdc, INT16 x, INT16 y )
 
 
 /***********************************************************************
- *           GetPixel32    (GDI32.211)
+ *           GetPixel    (GDI32.211)
  */
 COLORREF WINAPI GetPixel( HDC hdc, INT x, INT y )
 {
@@ -554,7 +474,7 @@ BOOL16 WINAPI PaintRgn16( HDC16 hdc, HRGN16 hrgn )
 
 
 /***********************************************************************
- *           PaintRgn32    (GDI32.259)
+ *           PaintRgn    (GDI32.259)
  */
 BOOL WINAPI PaintRgn( HDC hdc, HRGN hrgn )
 {
@@ -575,7 +495,7 @@ BOOL16 WINAPI FillRgn16( HDC16 hdc, HRGN16 hrgn, HBRUSH16 hbrush )
 
     
 /***********************************************************************
- *           FillRgn32    (GDI32.101)
+ *           FillRgn    (GDI32.101)
  */
 BOOL WINAPI FillRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush )
 {
@@ -606,7 +526,7 @@ BOOL16 WINAPI FrameRgn16( HDC16 hdc, HRGN16 hrgn, HBRUSH16 hbrush,
 
 
 /***********************************************************************
- *           FrameRgn32     (GDI32.105)
+ *           FrameRgn     (GDI32.105)
  */
 BOOL WINAPI FrameRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush,
                           INT nWidth, INT nHeight )
@@ -635,7 +555,7 @@ BOOL16 WINAPI InvertRgn16( HDC16 hdc, HRGN16 hrgn )
 
 
 /***********************************************************************
- *           InvertRgn32    (GDI32.246)
+ *           InvertRgn    (GDI32.246)
  */
 BOOL WINAPI InvertRgn( HDC hdc, HRGN hrgn )
 {
@@ -655,54 +575,6 @@ BOOL WINAPI InvertRgn( HDC hdc, HRGN hrgn )
     return retval;
 }
 
-
-/***********************************************************************
- *           DrawFocusRect16    (USER.466)
- */
-void WINAPI DrawFocusRect16( HDC16 hdc, const RECT16* rc )
-{
-    RECT rect32;
-    CONV_RECT16TO32( rc, &rect32 );
-    DrawFocusRect( hdc, &rect32 );
-}
-
-
-/***********************************************************************
- *           DrawFocusRect32    (USER32.156)
- *
- * FIXME: PatBlt(PATINVERT) with background brush.
- */
-BOOL WINAPI DrawFocusRect( HDC hdc, const RECT* rc )
-{
-    HBRUSH hOldBrush;
-    HPEN hOldPen, hNewPen;
-    INT oldDrawMode, oldBkMode;
-
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    if (!dc) 
-    {
-       SetLastError( ERROR_INVALID_HANDLE );
-       return FALSE;
-    }
-
-    hOldBrush = SelectObject(hdc, GetStockObject(NULL_BRUSH));
-    hNewPen = CreatePen(PS_DOT, 1, GetSysColor(COLOR_WINDOWTEXT));
-    hOldPen = SelectObject(hdc, hNewPen);
-    oldDrawMode = SetROP2(hdc, R2_XORPEN);
-    oldBkMode = SetBkMode(hdc, TRANSPARENT);
-
-    Rectangle(hdc, rc->left, rc->top, rc->right, rc->bottom);
-
-    SetBkMode(hdc, oldBkMode);
-    SetROP2(hdc, oldDrawMode);
-    SelectObject(hdc, hOldPen);
-    DeleteObject(hNewPen);
-    SelectObject(hdc, hOldBrush);
-
-    return TRUE;
-}
-
-
 /**********************************************************************
  *          Polyline16  (GDI.37)
  */
@@ -722,7 +594,7 @@ BOOL16 WINAPI Polyline16( HDC16 hdc, const POINT16* pt, INT16 count )
 
 
 /**********************************************************************
- *          Polyline32   (GDI32.276)
+ *          Polyline   (GDI32.276)
  */
 BOOL WINAPI Polyline( HDC hdc, const POINT* pt, INT count )
 {
@@ -733,28 +605,34 @@ BOOL WINAPI Polyline( HDC hdc, const POINT* pt, INT count )
 }
 
 /**********************************************************************
- *          PolylineTo32   (GDI32.277)
+ *          PolylineTo   (GDI32.277)
  */
 BOOL WINAPI PolylineTo( HDC hdc, const POINT* pt, DWORD cCount )
 {
-    POINT *pts = HeapAlloc( GetProcessHeap(), 0,
-			      sizeof(POINT) * (cCount + 1) );
-    if(!pts) return FALSE;
-
-    /* Get the current point */
-    MoveToEx( hdc, 0, 0, pts);
+    DC * dc = DC_GetDCPtr( hdc );
+    BOOL ret;
 
-    /* Add in the other points */
-    memcpy( pts + 1, pt, sizeof(POINT) * cCount );
+    if(!dc) return FALSE;
 
-    /* Draw the lines */
-    Polyline( hdc, pts, cCount + 1 );
+    if(dc->funcs->pPolylineTo)
+        ret = dc->funcs->pPolylineTo(dc, pt, cCount);
 
-    /* Move to last point */
-    MoveToEx( hdc, (pts + cCount)->x, (pts + cCount)->y, NULL );
+    else { /* do it using Polyline */
+        POINT *pts = HeapAlloc( GetProcessHeap(), 0,
+				sizeof(POINT) * (cCount + 1) );
+	if(!pts) return FALSE;
 
-    HeapFree( GetProcessHeap(), 0, pts );
-    return TRUE;
+	pts[0].x = dc->w.CursPosX;
+	pts[0].y = dc->w.CursPosY;
+	memcpy( pts + 1, pt, sizeof(POINT) * cCount );
+	ret = Polyline( hdc, pts, cCount + 1 );
+	HeapFree( GetProcessHeap(), 0, pts );
+    }
+    if(ret) {
+        dc->w.CursPosX = pt[cCount-1].x;
+	dc->w.CursPosY = pt[cCount-1].y;
+    }
+    return ret;
 }
 
 /**********************************************************************
@@ -776,7 +654,7 @@ BOOL16 WINAPI Polygon16( HDC16 hdc, const POINT16* pt, INT16 count )
 
 
 /**********************************************************************
- *          Polygon32  (GDI32.275)
+ *          Polygon  (GDI32.275)
  */
 BOOL WINAPI Polygon( HDC hdc, const POINT* pt, INT count )
 {
@@ -815,7 +693,7 @@ BOOL16 WINAPI PolyPolygon16( HDC16 hdc, const POINT16* pt, const INT16* counts,
 }
 
 /**********************************************************************
- *          PolyPolygon32  (GDI.450)
+ *          PolyPolygon  (GDI.450)
  */
 BOOL WINAPI PolyPolygon( HDC hdc, const POINT* pt, const INT* counts,
                              UINT polygons )
@@ -849,7 +727,7 @@ BOOL16 WINAPI ExtFloodFill16( HDC16 hdc, INT16 x, INT16 y, COLORREF color,
 
 
 /**********************************************************************
- *          ExtFloodFill32   (GDI32.96)
+ *          ExtFloodFill   (GDI32.96)
  */
 BOOL WINAPI ExtFloodFill( HDC hdc, INT x, INT y, COLORREF color,
                               UINT fillType )
@@ -871,7 +749,7 @@ BOOL16 WINAPI FloodFill16( HDC16 hdc, INT16 x, INT16 y, COLORREF color )
 
 
 /**********************************************************************
- *          FloodFill32   (GDI32.104)
+ *          FloodFill   (GDI32.104)
  */
 BOOL WINAPI FloodFill( HDC hdc, INT x, INT y, COLORREF color )
 {
@@ -879,278 +757,6 @@ BOOL WINAPI FloodFill( HDC hdc, INT x, INT y, COLORREF color )
 }
 
 
-/**********************************************************************
- *          DrawAnimatedRects16  (USER.448)
- */
-BOOL16 WINAPI DrawAnimatedRects16( HWND16 hwnd, INT16 idAni,
-                                   const RECT16* lprcFrom,
-                                   const RECT16* lprcTo )
-{
-    RECT rcFrom32, rcTo32;
-
-    rcFrom32.left	= (INT)lprcFrom->left;
-    rcFrom32.top	= (INT)lprcFrom->top;
-    rcFrom32.right	= (INT)lprcFrom->right;
-    rcFrom32.bottom	= (INT)lprcFrom->bottom;
-
-    rcTo32.left		= (INT)lprcTo->left;
-    rcTo32.top		= (INT)lprcTo->top;
-    rcTo32.right	= (INT)lprcTo->right;
-    rcTo32.bottom	= (INT)lprcTo->bottom;
-
-    return DrawAnimatedRects((HWND)hwnd, (INT)idAni, &rcFrom32, &rcTo32);
-}
-
-
-/**********************************************************************
- *          DrawAnimatedRects32  (USER32.153)
- */
-BOOL WINAPI DrawAnimatedRects( HWND hwnd, int idAni,
-                                   const RECT* lprcFrom,
-                                   const RECT* lprcTo )
-{
-    FIXME("(0x%x,%d,%p,%p): stub\n",hwnd,idAni,lprcFrom,lprcTo);
-    return TRUE;
-}
-
-
-/**********************************************************************
- *          PAINTING_DrawStateJam
- *
- * Jams in the requested type in the dc
- */
-static BOOL PAINTING_DrawStateJam(HDC hdc, UINT opcode,
-                                    DRAWSTATEPROC func, LPARAM lp, WPARAM wp, 
-                                    LPRECT rc, UINT dtflags,
-                                    BOOL unicode, BOOL _32bit)
-{
-    HDC memdc;
-    HBITMAP hbmsave;
-    BOOL retval;
-    INT cx = rc->right - rc->left;
-    INT cy = rc->bottom - rc->top;
-    
-    switch(opcode)
-    {
-    case DST_TEXT:
-    case DST_PREFIXTEXT:
-        if(unicode)
-            return DrawTextW(hdc, (LPWSTR)lp, (INT)wp, rc, dtflags);
-        else if(_32bit)
-            return DrawTextA(hdc, (LPSTR)lp, (INT)wp, rc, dtflags);
-        else
-            return DrawTextA(hdc, (LPSTR)PTR_SEG_TO_LIN(lp), (INT)wp, rc, dtflags);
-
-    case DST_ICON:
-        return DrawIcon(hdc, rc->left, rc->top, (HICON)lp);
-
-    case DST_BITMAP:
-        memdc = CreateCompatibleDC(hdc);
-        if(!memdc) return FALSE;
-        hbmsave = (HBITMAP)SelectObject(memdc, (HBITMAP)lp);
-        if(!hbmsave) 
-        {
-            DeleteDC(memdc);
-            return FALSE;
-        }
-        retval = BitBlt(hdc, rc->left, rc->top, cx, cy, memdc, 0, 0, SRCCOPY);
-        SelectObject(memdc, hbmsave);
-        DeleteDC(memdc);
-        return retval;
-            
-    case DST_COMPLEX:
-        if(func)
-            if(_32bit)
-                return func(hdc, lp, wp, cx, cy);
-            else
-                return (BOOL)((DRAWSTATEPROC16)func)((HDC16)hdc, (LPARAM)lp, (WPARAM16)wp, (INT16)cx, (INT16)cy);
-        else
-            return FALSE;
-    }
-    return FALSE;
-}
-
-/**********************************************************************
- *      PAINTING_DrawState32()
- */
-static BOOL PAINTING_DrawState(HDC hdc, HBRUSH hbr, 
-                                   DRAWSTATEPROC func, LPARAM lp, WPARAM wp,
-                                   INT x, INT y, INT cx, INT cy, 
-                                   UINT flags, BOOL unicode, BOOL _32bit)
-{
-    HBITMAP hbm, hbmsave;
-    HFONT hfsave;
-    HBRUSH hbsave;
-    HDC memdc;
-    RECT rc;
-    UINT dtflags = DT_NOCLIP;
-    COLORREF fg, bg;
-    UINT opcode = flags & 0xf;
-    INT len = wp;
-    BOOL retval, tmp;
-
-    if((opcode == DST_TEXT || opcode == DST_PREFIXTEXT) && !len)    /* The string is '\0' terminated */
-    {
-        if(unicode)
-            len = lstrlenW((LPWSTR)lp);
-        else if(_32bit)
-            len = lstrlenA((LPSTR)lp);
-        else
-            len = lstrlenA((LPSTR)PTR_SEG_TO_LIN(lp));
-    }
-
-    /* Find out what size the image has if not given by caller */
-    if(!cx || !cy)
-    {
-        SIZE s;
-        CURSORICONINFO *ici;
-        BITMAPOBJ *bmp;
-
-        switch(opcode)
-        {
-        case DST_TEXT:
-        case DST_PREFIXTEXT:
-            if(unicode)
-                retval = GetTextExtentPoint32W(hdc, (LPWSTR)lp, len, &s);
-            else if(_32bit)
-                retval = GetTextExtentPoint32A(hdc, (LPSTR)lp, len, &s);
-            else
-                retval = GetTextExtentPoint32A(hdc, PTR_SEG_TO_LIN(lp), len, &s);
-            if(!retval) return FALSE;
-            break;
-            
-        case DST_ICON:
-            ici = (CURSORICONINFO *)GlobalLock16((HGLOBAL16)lp);
-            if(!ici) return FALSE;
-            s.cx = ici->nWidth;
-            s.cy = ici->nHeight;
-            GlobalUnlock16((HGLOBAL16)lp);
-            break;            
-
-        case DST_BITMAP:
-            bmp = (BITMAPOBJ *)GDI_GetObjPtr((HBITMAP16)lp, BITMAP_MAGIC);
-            if(!bmp) return FALSE;
-            s.cx = bmp->bitmap.bmWidth;
-            s.cy = bmp->bitmap.bmHeight;
-            break;
-            
-        case DST_COMPLEX: /* cx and cy must be set in this mode */
-            return FALSE;
-	}
-	            
-        if(!cx) cx = s.cx;
-        if(!cy) cy = s.cy;
-    }
-
-    rc.left   = x;
-    rc.top    = y;
-    rc.right  = x + cx;
-    rc.bottom = y + cy;
-
-    if(flags & DSS_RIGHT)    /* This one is not documented in the win32.hlp file */
-        dtflags |= DT_RIGHT;
-    if(opcode == DST_TEXT)
-        dtflags |= DT_NOPREFIX;
-
-    /* For DSS_NORMAL we just jam in the image and return */
-    if((flags & 0x7ff0) == DSS_NORMAL)
-    {
-        return PAINTING_DrawStateJam(hdc, opcode, func, lp, len, &rc, dtflags, unicode, _32bit);
-    }
-
-    /* For all other states we need to convert the image to B/W in a local bitmap */
-    /* before it is displayed */
-    fg = SetTextColor(hdc, RGB(0, 0, 0));
-    bg = SetBkColor(hdc, RGB(255, 255, 255));
-    hbm = (HBITMAP)NULL; hbmsave = (HBITMAP)NULL;
-    memdc = (HDC)NULL; hbsave = (HBRUSH)NULL;
-    retval = FALSE; /* assume failure */
-    
-    /* From here on we must use "goto cleanup" when something goes wrong */
-    hbm     = CreateBitmap(cx, cy, 1, 1, NULL);
-    if(!hbm) goto cleanup;
-    memdc   = CreateCompatibleDC(hdc);
-    if(!memdc) goto cleanup;
-    hbmsave = (HBITMAP)SelectObject(memdc, hbm);
-    if(!hbmsave) goto cleanup;
-    rc.left = rc.top = 0;
-    rc.right = cx;
-    rc.bottom = cy;
-    if(!FillRect(memdc, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH))) goto cleanup;
-    SetBkColor(memdc, RGB(255, 255, 255));
-    SetTextColor(memdc, RGB(0, 0, 0));
-    hfsave  = (HFONT)SelectObject(memdc, GetCurrentObject(hdc, OBJ_FONT));
-    if(!hfsave && (opcode == DST_TEXT || opcode == DST_PREFIXTEXT)) goto cleanup;
-    tmp = PAINTING_DrawStateJam(memdc, opcode, func, lp, len, &rc, dtflags, unicode, _32bit);
-    if(hfsave) SelectObject(memdc, hfsave);
-    if(!tmp) goto cleanup;
-    
-    /* These states cause the image to be dithered */
-    if(flags & (DSS_UNION|DSS_DISABLED))
-    {
-        hbsave = (HBRUSH)SelectObject(memdc, CACHE_GetPattern55AABrush());
-        if(!hbsave) goto cleanup;
-        tmp = PatBlt(memdc, 0, 0, cx, cy, 0x00FA0089);
-        if(hbsave) SelectObject(memdc, hbsave);
-        if(!tmp) goto cleanup;
-    }
-
-    hbsave = (HBRUSH)SelectObject(hdc, hbr ? hbr : GetStockObject(WHITE_BRUSH));
-    if(!hbsave) goto cleanup;
-    
-    if(!BitBlt(hdc, x, y, cx, cy, memdc, 0, 0, 0x00B8074A)) goto cleanup;
-    
-    /* DSS_DEFAULT makes the image boldface */
-    if(flags & DSS_DEFAULT)
-    {
-        if(!BitBlt(hdc, x+1, y, cx, cy, memdc, 0, 0, 0x00B8074A)) goto cleanup;
-    }
-
-    retval = TRUE; /* We succeeded */
-    
-cleanup:    
-    SetTextColor(hdc, fg);
-    SetBkColor(hdc, bg);
-
-    if(hbsave)  SelectObject(hdc, hbsave);
-    if(hbmsave) SelectObject(memdc, hbmsave);
-    if(hbm)     DeleteObject(hbm);
-    if(memdc)   DeleteDC(memdc);
-
-    return retval;
-}
-
-/**********************************************************************
- *      DrawState32A()   (USER32.162)
- */
-BOOL WINAPI DrawStateA(HDC hdc, HBRUSH hbr,
-                   DRAWSTATEPROC func, LPARAM ldata, WPARAM wdata,
-                   INT x, INT y, INT cx, INT cy, UINT flags)
-{
-    return PAINTING_DrawState(hdc, hbr, func, ldata, wdata, x, y, cx, cy, flags, FALSE, TRUE);
-}
-
-/**********************************************************************
- *      DrawState32W()   (USER32.163)
- */
-BOOL WINAPI DrawStateW(HDC hdc, HBRUSH hbr,
-                   DRAWSTATEPROC func, LPARAM ldata, WPARAM wdata,
-                   INT x, INT y, INT cx, INT cy, UINT flags)
-{
-    return PAINTING_DrawState(hdc, hbr, func, ldata, wdata, x, y, cx, cy, flags, TRUE, TRUE);
-}
-
-/**********************************************************************
- *      DrawState16()   (USER.449)
- */
-BOOL16 WINAPI DrawState16(HDC16 hdc, HBRUSH16 hbr,
-                   DRAWSTATEPROC16 func, LPARAM ldata, WPARAM16 wdata,
-                   INT16 x, INT16 y, INT16 cx, INT16 cy, UINT16 flags)
-{
-    return PAINTING_DrawState(hdc, hbr, (DRAWSTATEPROC)func, ldata, wdata, x, y, cx, cy, flags, FALSE, FALSE);
-}
-
-
 /******************************************************************************
  * PolyBezier16 [GDI.502]
  */
@@ -1184,7 +790,7 @@ BOOL16 WINAPI PolyBezierTo16( HDC16 hDc, const POINT16* lppt, INT16 cPoints )
 }
 
 /******************************************************************************
- * PolyBezier32 [GDI32.268]
+ * PolyBezier [GDI32.268]
  * Draws one or more Bezier curves
  *
  * PARAMS
@@ -1197,17 +803,13 @@ BOOL16 WINAPI PolyBezierTo16( HDC16 hDc, const POINT16* lppt, INT16 cPoints )
 BOOL WINAPI PolyBezier( HDC hdc, const POINT* lppt, DWORD cPoints )
 {
     DC * dc = DC_GetDCPtr( hdc );
-    if(!dc) return FALSE;
-    if(dc && PATH_IsPathOpen(dc->w.path))
-        FIXME("PATH_PolyBezier is not implemented!\n");
-/*        if(!PATH_PolyBezier(hdc, x, y))
-	   return FALSE; */
-    return dc->funcs->pPolyBezier&&
-    	   dc->funcs->pPolyBezier(dc, lppt[0], lppt+1, cPoints-1);
+
+    return dc && dc->funcs->pPolyBezier &&
+    	   dc->funcs->pPolyBezier(dc, lppt, cPoints);
 }
 
 /******************************************************************************
- * PolyBezierTo32 [GDI32.269]
+ * PolyBezierTo [GDI32.269]
  * Draws one or more Bezier curves
  *
  * PARAMS
@@ -1220,19 +822,20 @@ BOOL WINAPI PolyBezier( HDC hdc, const POINT* lppt, DWORD cPoints )
 BOOL WINAPI PolyBezierTo( HDC hdc, const POINT* lppt, DWORD cPoints )
 {
     DC * dc = DC_GetDCPtr( hdc );
-    POINT pt;
     BOOL ret;
+
     if(!dc) return FALSE;
-    pt.x=dc->w.CursPosX;
-    pt.y=dc->w.CursPosY;
-    if(dc && PATH_IsPathOpen(dc->w.path))
-        FIXME("PATH_PolyBezierTo is not implemented!\n");
-/*        if(!PATH_PolyBezier(hdc, x, y))
-	   return FALSE; */
-    ret= dc->funcs->pPolyBezier &&
-    	   dc->funcs->pPolyBezier(dc, pt, lppt, cPoints);
-    if( dc->funcs->pMoveToEx)
-    	   dc->funcs->pMoveToEx(dc,lppt[cPoints].x,lppt[cPoints].y,&pt);
+
+    if(PATH_IsPathOpen(dc->w.path))
+        ret = PATH_PolyBezierTo(hdc, lppt, cPoints);
+    else 
+        ret = dc->funcs->pPolyBezierTo &&
+	    dc->funcs->pPolyBezierTo(dc, lppt, cPoints);
+
+    if(ret) {
+        dc->w.CursPosX = lppt[cPoints-1].x;
+        dc->w.CursPosY = lppt[cPoints-1].y;
+    }
     return ret;
 }
 
diff --git a/graphics/path.c b/graphics/path.c
index b7023bfc503..43d19d3c5cb 100644
--- a/graphics/path.c
+++ b/graphics/path.c
@@ -5,7 +5,6 @@
  */
 
 #include <assert.h>
-#include <malloc.h>
 #include <math.h>
 #include <string.h>
 #include "config.h"
@@ -92,19 +91,23 @@ BOOL16 WINAPI BeginPath16(HDC16 hdc)
 
 
 /***********************************************************************
- *           BeginPath32    (GDI32.9)
+ *           BeginPath    (GDI32.9)
  */
 BOOL WINAPI BeginPath(HDC hdc)
 {
+   DC *dc = DC_GetDCPtr( hdc );
    GdiPath *pPath;
    
-   /* Get pointer to path */
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-   {
-      SetLastError(ERROR_INVALID_HANDLE);
-      return FALSE;
+   if(!dc) {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
    }
-   
+
+   if(dc->funcs->pBeginPath)
+     return dc->funcs->pBeginPath(dc);
+
+   pPath = &dc->w.path;
+
    /* If path is already open, do nothing */
    if(pPath->state==PATH_Open)
       return TRUE;
@@ -130,19 +133,23 @@ BOOL16 WINAPI EndPath16(HDC16 hdc)
 
 
 /***********************************************************************
- *           EndPath32    (GDI32.78)
+ *           EndPath    (GDI32.78)
  */
 BOOL WINAPI EndPath(HDC hdc)
 {
+   DC *dc = DC_GetDCPtr( hdc );
    GdiPath *pPath;
    
-   /* Get pointer to path */
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-   {
-      SetLastError(ERROR_INVALID_HANDLE);
-      return FALSE;
+   if(!dc) {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
    }
-   
+
+   if(dc->funcs->pEndPath)
+     return dc->funcs->pEndPath(dc);
+
+   pPath = &dc->w.path;
+
    /* Check that path is currently being constructed */
    if(pPath->state!=PATH_Open)
    {
@@ -167,7 +174,7 @@ BOOL16 WINAPI AbortPath16(HDC16 hdc)
 
 
 /******************************************************************************
- * AbortPath32 [GDI32.1]
+ * AbortPath [GDI32.1]
  * Closes and discards paths from device context
  *
  * NOTES
@@ -180,14 +187,18 @@ BOOL16 WINAPI AbortPath16(HDC16 hdc)
  */
 BOOL WINAPI AbortPath( HDC hdc )
 {
+   DC *dc = DC_GetDCPtr( hdc );
    GdiPath *pPath;
    
-   /* Get pointer to path */
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-   {
-      SetLastError(ERROR_INVALID_PARAMETER);
-      return FALSE;
+   if(!dc) {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
    }
+
+   if(dc->funcs->pAbortPath)
+     return dc->funcs->pAbortPath(dc);
+
+   pPath = &dc->w.path;
    
    /* Remove all entries from the path */
    PATH_EmptyPath(pPath);
@@ -206,21 +217,25 @@ BOOL16 WINAPI CloseFigure16(HDC16 hdc)
 
 
 /***********************************************************************
- *           CloseFigure32    (GDI32.16)
+ *           CloseFigure    (GDI32.16)
  *
  * FIXME: Check that SetLastError is being called correctly 
  */
 BOOL WINAPI CloseFigure(HDC hdc)
 {
+   DC *dc = DC_GetDCPtr( hdc );
    GdiPath *pPath;
    
-   /* Get pointer to path */
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-   {
-      SetLastError(ERROR_INVALID_PARAMETER);
-      return FALSE;
+   if(!dc) {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
    }
-   
+
+   if(dc->funcs->pCloseFigure)
+     return dc->funcs->pCloseFigure(dc);
+
+   pPath = &dc->w.path;
+
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
    {
@@ -254,7 +269,7 @@ INT16 WINAPI GetPath16(HDC16 hdc, LPPOINT16 pPoints, LPBYTE pTypes,
 
 
 /***********************************************************************
- *           GetPath32    (GDI32.210)
+ *           GetPath    (GDI32.210)
  */
 INT WINAPI GetPath(HDC hdc, LPPOINT pPoints, LPBYTE pTypes,
    INT nSize)
@@ -308,7 +323,7 @@ HRGN16 WINAPI PathToRegion16(HDC16 hdc)
 }
 
 /***********************************************************************
- *           PathToRegion32    (GDI32.261)
+ *           PathToRegion    (GDI32.261)
  *
  * FIXME 
  *   Check that SetLastError is being called correctly 
@@ -353,7 +368,7 @@ BOOL16 WINAPI FillPath16(HDC16 hdc)
 }
 
 /***********************************************************************
- *           FillPath32    (GDI32.100)
+ *           FillPath    (GDI32.100)
  *
  * FIXME
  *    Check that SetLastError is being called correctly 
@@ -366,14 +381,18 @@ BOOL WINAPI FillPath(HDC hdc)
    POINT ptViewportOrg, ptWindowOrg;
    XFORM   xform;
    HRGN  hrgn;
+   DC *dc = DC_GetDCPtr( hdc );
    
-   /* Get pointer to path */
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-   {
-      SetLastError(ERROR_INVALID_PARAMETER);
-      return FALSE;
+   if(!dc) {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
    }
-   
+
+   if(dc->funcs->pFillPath)
+     return dc->funcs->pFillPath(dc);
+
+   pPath = &dc->w.path;
+
    /* Check that path is closed */
    if(pPath->state!=PATH_Closed)
    {
@@ -409,7 +428,9 @@ BOOL WINAPI FillPath(HDC hdc)
       
       /* Set MM_TEXT */
       SetMapMode(hdc, MM_TEXT);
-      
+      SetViewportOrgEx(hdc, 0, 0, NULL);
+      SetWindowOrgEx(hdc, 0, 0, NULL);
+
       /* Paint the region */
       PaintRgn(hdc, hrgn);
 
@@ -447,7 +468,7 @@ BOOL16 WINAPI SelectClipPath16(HDC16 hdc, INT16 iMode)
 }
 
 /***********************************************************************
- *           SelectClipPath32    (GDI32.296)
+ *           SelectClipPath    (GDI32.296)
  * FIXME 
  *  Check that SetLastError is being called correctly 
  */
@@ -456,13 +477,17 @@ BOOL WINAPI SelectClipPath(HDC hdc, INT iMode)
    GdiPath *pPath;
    HRGN  hrgnPath;
    BOOL  success;
+   DC *dc = DC_GetDCPtr( hdc );
    
-   /* Get pointer to path */
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-   {
-      SetLastError(ERROR_INVALID_PARAMETER);
-      return FALSE;
+   if(!dc) {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
    }
+
+   if(dc->funcs->pSelectClipPath)
+     return dc->funcs->pSelectClipPath(dc, iMode);
+
+   pPath = &dc->w.path;
    
    /* Check that path is closed */
    if(pPath->state!=PATH_Closed)
@@ -516,8 +541,8 @@ void PATH_DestroyGdiPath(GdiPath *pPath)
 {
    assert(pPath!=NULL);
 
-   free(pPath->pPoints);
-   free(pPath->pFlags);
+   HeapFree( GetProcessHeap(), 0, pPath->pPoints );
+   HeapFree( GetProcessHeap(), 0, pPath->pFlags );
 }
 
 /* PATH_AssignGdiPath
@@ -542,7 +567,8 @@ BOOL PATH_AssignGdiPath(GdiPath *pPathDest, const GdiPath *pPathSrc)
    memcpy(pPathDest->pPoints, pPathSrc->pPoints,
       sizeof(POINT)*pPathSrc->numEntriesUsed);
    memcpy(pPathDest->pFlags, pPathSrc->pFlags,
-      sizeof(INT)*pPathSrc->numEntriesUsed);
+      sizeof(BYTE)*pPathSrc->numEntriesUsed);
+
    pPathDest->state=pPathSrc->state;
    pPathDest->numEntriesUsed=pPathSrc->numEntriesUsed;
    pPathDest->newStroke=pPathSrc->newStroke;
@@ -854,6 +880,38 @@ BOOL PATH_Arc(HDC hdc, INT x1, INT y1, INT x2, INT y2,
    return TRUE;
 }
 
+BOOL PATH_PolyBezierTo(HDC hdc, const POINT *pts, DWORD cbPoints)
+{
+   GdiPath     *pPath;
+   POINT       pt;
+   INT         i;
+
+   if(!PATH_GetPathFromHDC(hdc, &pPath))
+      return FALSE;
+   
+   /* Check that path is open */
+   if(pPath->state!=PATH_Open)
+      return FALSE;
+
+   /* Add a PT_MOVETO if necessary */
+   if(pPath->newStroke)
+   {
+      pPath->newStroke=FALSE;
+      if(!GetCurrentPositionEx(hdc, &pt) ||
+         !LPtoDP(hdc, &pt, 1))
+         return FALSE;
+      if(!PATH_AddEntry(pPath, &pt, PT_MOVETO))
+         return FALSE;
+   }
+   for(i = 0; i < cbPoints; i++) {
+       pt = pts[i];
+       if(!LPtoDP(hdc, &pt, 1))
+	   return FALSE;
+       PATH_AddEntry(pPath, &pt, PT_BEZIERTO);
+   }
+   return TRUE;
+}
+   
 /***********************************************************************
  * Internal functions
  */
@@ -886,7 +944,8 @@ static BOOL PATH_PathToRegion(const GdiPath *pPath, INT nPolyFillMode,
          numStrokes++;
 
    /* Allocate memory for number-of-points-in-stroke array */
-   pNumPointsInStroke=(int *)malloc(sizeof(int)*numStrokes);
+   pNumPointsInStroke=(int *)HeapAlloc( GetProcessHeap(), 0, 
+					sizeof(int) * numStrokes );
    if(!pNumPointsInStroke)
    {
       SetLastError(ERROR_NOT_ENOUGH_MEMORY);
@@ -917,7 +976,7 @@ static BOOL PATH_PathToRegion(const GdiPath *pPath, INT nPolyFillMode,
    }
 
    /* Free memory for number-of-points-in-stroke array */
-   free(pNumPointsInStroke);
+   HeapFree( GetProcessHeap(), 0, pNumPointsInStroke );
 
    /* Success! */
    *pHrgn=hrgn;
@@ -1001,16 +1060,18 @@ static BOOL PATH_ReserveEntries(GdiPath *pPath, INT numEntries)
 	       GROW_FACTOR_DENOM;
       }
       else
-         numEntriesToAllocate=NUM_ENTRIES_INITIAL;
+         numEntriesToAllocate=numEntries;
 
       /* Allocate new arrays */
-      pPointsNew=(POINT *)malloc(numEntriesToAllocate * sizeof(POINT));
+      pPointsNew=(POINT *)HeapAlloc( GetProcessHeap(), 0, 
+				     numEntriesToAllocate * sizeof(POINT) );
       if(!pPointsNew)
          return FALSE;
-      pFlagsNew=(BYTE *)malloc(numEntriesToAllocate * sizeof(BYTE));
+      pFlagsNew=(BYTE *)HeapAlloc( GetProcessHeap(), 0, 
+				   numEntriesToAllocate * sizeof(BYTE) );
       if(!pFlagsNew)
       {
-         free(pPointsNew);
+         HeapFree( GetProcessHeap(), 0, pPointsNew );
 	 return FALSE;
       }
 
@@ -1024,8 +1085,8 @@ static BOOL PATH_ReserveEntries(GdiPath *pPath, INT numEntries)
 	 memcpy(pFlagsNew, pPath->pFlags,
 	     sizeof(BYTE)*pPath->numEntriesUsed);
 
-	 free(pPath->pPoints);
-	 free(pPath->pFlags);
+	 HeapFree( GetProcessHeap(), 0, pPath->pPoints );
+	 HeapFree( GetProcessHeap(), 0, pPath->pFlags );
       }
       pPath->pPoints=pPointsNew;
       pPath->pFlags=pFlagsNew;
@@ -1157,14 +1218,24 @@ BOOL16 WINAPI FlattenPath16(HDC16 hdc)
 }
 
 /*******************************************************************
- *      FlattenPath32 [GDI32.103]
+ *      FlattenPath [GDI32.103]
  *
  *
  */
 BOOL WINAPI FlattenPath(HDC hdc)
 {
-        FIXME("FlattenPath, stub\n");
-        return 0;
+   DC *dc = DC_GetDCPtr( hdc );
+   
+   if(!dc) {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
+   }
+
+   if(dc->funcs->pFlattenPath)
+     return dc->funcs->pFlattenPath(dc);
+
+   FIXME("stub\n");
+   return 0;
 }
 
 /*******************************************************************
@@ -1184,8 +1255,18 @@ BOOL16 WINAPI StrokeAndFillPath16(HDC16 hdc)
  */
 BOOL WINAPI StrokeAndFillPath(HDC hdc)
 {
-        FIXME("StrokeAndFillPath, stub\n");
-        return 0;
+   DC *dc = DC_GetDCPtr( hdc );
+   
+   if(!dc) {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
+   }
+
+   if(dc->funcs->pStrokeAndFillPath)
+     return dc->funcs->pStrokeAndFillPath(dc);
+
+   FIXME("stub\n");
+   return StrokePath(hdc);
 }
 
 /*******************************************************************
@@ -1205,8 +1286,62 @@ BOOL16 WINAPI StrokePath16(HDC16 hdc)
  */
 BOOL WINAPI StrokePath(HDC hdc)
 {
-        FIXME("StrokePath, stub\n");
-        return 0;
+    DC *dc = DC_GetDCPtr( hdc );
+    GdiPath *pPath;
+    INT i;
+    POINT ptLastMove = {0,0};
+
+    TRACE("(%08x)\n", hdc);
+    if(!dc) {
+        SetLastError(ERROR_INVALID_HANDLE);
+	return FALSE;
+    }
+
+    if(dc->funcs->pStrokePath)
+        return dc->funcs->pStrokePath(dc);
+
+    pPath = &dc->w.path;
+    if(pPath->state != PATH_Closed)
+        return FALSE;
+
+    SaveDC(hdc);
+    SetMapMode(hdc, MM_TEXT);
+    SetViewportOrgEx(hdc, 0, 0, NULL);
+    SetWindowOrgEx(hdc, 0, 0, NULL);
+    for(i = 0; i < pPath->numEntriesUsed; i++) {
+	switch(pPath->pFlags[i]) {
+	case PT_MOVETO:
+	    TRACE("Got PT_MOVETO (%ld, %ld)\n",
+		  pPath->pPoints[i].x, pPath->pPoints[i].y);
+	    MoveToEx(hdc, pPath->pPoints[i].x, pPath->pPoints[i].y, NULL);
+	    ptLastMove = pPath->pPoints[i];
+	    break;
+	case PT_LINETO:
+	case (PT_LINETO | PT_CLOSEFIGURE):
+	    TRACE("Got PT_LINETO (%ld, %ld)\n",
+		  pPath->pPoints[i].x, pPath->pPoints[i].y);
+	    LineTo(hdc, pPath->pPoints[i].x, pPath->pPoints[i].y);
+	    break;
+	case PT_BEZIERTO:
+	    TRACE("Got PT_BEZIERTO\n");
+	    if(pPath->pFlags[i+1] != PT_BEZIERTO || 
+	       (pPath->pFlags[i+2] & ~PT_CLOSEFIGURE) != PT_BEZIERTO) {
+	        ERR("Path didn't contain 3 successive PT_BEZIERTOs\n");
+		return FALSE;
+	    }
+	    PolyBezierTo(hdc, &pPath->pPoints[i], 3);
+	    i += 2;
+	    break;
+	default:
+	    ERR("Got path flag %d\n", (INT)pPath->pFlags[i]);
+	    return FALSE;
+	}
+	if(pPath->pFlags[i] & PT_CLOSEFIGURE)
+	    LineTo(hdc, ptLastMove.x, ptLastMove.y);
+    }
+    RestoreDC(hdc, -1);
+    PATH_EmptyPath(pPath);
+    return TRUE;
 }
 
 /*******************************************************************
@@ -1226,7 +1361,16 @@ BOOL16 WINAPI WidenPath16(HDC16 hdc)
  */
 BOOL WINAPI WidenPath(HDC hdc)
 {
-        FIXME("WidenPath, stub\n");
-        return 0;
-}
+   DC *dc = DC_GetDCPtr( hdc );
    
+   if(!dc) {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
+   }
+
+   if(dc->funcs->pWidenPath)
+     return dc->funcs->pWidenPath(dc);
+
+   FIXME("stub\n");
+   return 0;
+}
diff --git a/graphics/psdrv/graphics.c b/graphics/psdrv/graphics.c
index cfcd43e6775..7c1c0dffb4b 100644
--- a/graphics/psdrv/graphics.c
+++ b/graphics/psdrv/graphics.c
@@ -19,23 +19,6 @@
 
 DEFAULT_DEBUG_CHANNEL(psdrv)
 
-/**********************************************************************
- *	     PSDRV_MoveToEx
- */
-BOOL PSDRV_MoveToEx(DC *dc, INT x, INT y, LPPOINT pt)
-{
-    TRACE("%d %d\n", x, y);
-    if (pt)
-    {
-	pt->x = dc->w.CursPosX;
-	pt->y = dc->w.CursPosY;
-    }
-    dc->w.CursPosX = x;
-    dc->w.CursPosY = y;
-
-    return TRUE;
-}
-
 
 /***********************************************************************
  *           PSDRV_LineTo
@@ -50,8 +33,6 @@ BOOL PSDRV_LineTo(DC *dc, INT x, INT y)
     PSDRV_WriteLineTo(dc, XLPTODP(dc, x), YLPTODP(dc, y));
     PSDRV_DrawLine(dc);
 
-    dc->w.CursPosX = x;
-    dc->w.CursPosY = y;
     return TRUE;
 }
 
diff --git a/graphics/psdrv/init.c b/graphics/psdrv/init.c
index f7d104d7ef0..ed0daed96d9 100644
--- a/graphics/psdrv/init.c
+++ b/graphics/psdrv/init.c
@@ -24,10 +24,15 @@ static BOOL PSDRV_DeleteDC( DC *dc );
 static const DC_FUNCTIONS PSDRV_Funcs =
 {
     NULL,                            /* pAbortDoc */
+    NULL,                            /* pAbortPath */
+    NULL,                            /* pAngleArc */
     PSDRV_Arc,                       /* pArc */
+    NULL,                            /* pArcTo */
+    NULL,                            /* pBeginPath */
     NULL,                            /* pBitBlt */
     NULL,                            /* pBitmapBits */
     PSDRV_Chord,                     /* pChord */
+    NULL,                            /* pCloseFigure */
     NULL,                            /* pCreateBitmap */
     PSDRV_CreateDC,                  /* pCreateDC */
     NULL,                            /* pCreateDIBSection */
@@ -38,13 +43,16 @@ static const DC_FUNCTIONS PSDRV_Funcs =
     PSDRV_Ellipse,                   /* pEllipse */
     PSDRV_EndDoc,                    /* pEndDoc */
     PSDRV_EndPage,                   /* pEndPage */
+    NULL,                            /* pEndPath */
     PSDRV_EnumDeviceFonts,           /* pEnumDeviceFonts */
     PSDRV_Escape,                    /* pEscape */
     NULL,                            /* pExcludeClipRect */
     PSDRV_ExtDeviceMode,             /* pExtDeviceMode */
     NULL,                            /* pExtFloodFill */
     PSDRV_ExtTextOut,                /* pExtTextOut */
+    NULL,                            /* pFillPath */
     NULL,                            /* pFillRgn */
+    NULL,                            /* pFlattenPath */
     NULL,                            /* pFrameRgn */
     PSDRV_GetCharWidth,              /* pGetCharWidth */
     NULL,                            /* pGetPixel */
@@ -54,18 +62,21 @@ static const DC_FUNCTIONS PSDRV_Funcs =
     NULL,                            /* pInvertRgn */
     PSDRV_LineTo,                    /* pLineTo */
     NULL,                            /* pLoadOEMResource */
-    PSDRV_MoveToEx,                  /* pMoveToEx */
+    NULL,                            /* pMoveToEx */
     NULL,                            /* pOffsetClipRgn */
     NULL,                            /* pOffsetViewportOrg (optional) */
     NULL,                            /* pOffsetWindowOrg (optional) */
     NULL,                            /* pPaintRgn */
     PSDRV_PatBlt,                    /* pPatBlt */
     PSDRV_Pie,                       /* pPie */
+    NULL,                            /* pPolyBezier */
+    NULL,                            /* pPolyBezierTo */
+    NULL,                            /* pPolyDraw */
     PSDRV_PolyPolygon,               /* pPolyPolygon */
     PSDRV_PolyPolyline,              /* pPolyPolyline */
     PSDRV_Polygon,                   /* pPolygon */
     PSDRV_Polyline,                  /* pPolyline */
-    NULL,                            /* pPolyBezier */		     
+    NULL,                            /* pPolylineTo */
     NULL,                            /* pRealizePalette */
     PSDRV_Rectangle,                 /* pRectangle */
     NULL,                            /* pRestoreDC */
@@ -73,6 +84,7 @@ static const DC_FUNCTIONS PSDRV_Funcs =
     NULL,                            /* pSaveDC */
     NULL,                            /* pScaleViewportExt (optional) */
     NULL,                            /* pScaleWindowExt (optional) */
+    NULL,                            /* pSelectClipPath */
     NULL,                            /* pSelectClipRgn */
     PSDRV_SelectObject,              /* pSelectObject */
     NULL,                            /* pSelectPalette */
@@ -98,7 +110,10 @@ static const DC_FUNCTIONS PSDRV_Funcs =
     PSDRV_StartDoc,                  /* pStartDoc */
     PSDRV_StartPage,                 /* pStartPage */
     NULL,                            /* pStretchBlt */
-    PSDRV_StretchDIBits              /* pStretchDIBits */
+    PSDRV_StretchDIBits,             /* pStretchDIBits */
+    NULL,                            /* pStrokeAndFillPath */
+    NULL,                            /* pStrokePath */
+    NULL                             /* pWidenPath */
 };
 
 
diff --git a/graphics/ttydrv/graphics.c b/graphics/ttydrv/graphics.c
index aee68104ec8..4a5f35ad585 100644
--- a/graphics/ttydrv/graphics.c
+++ b/graphics/ttydrv/graphics.c
@@ -106,9 +106,6 @@ BOOL TTYDRV_DC_LineTo(DC *dc, INT x, INT y)
   }
   wrefresh(physDev->window);
 
-  dc->w.CursPosX = x;
-  dc->w.CursPosY = y;
-
   return TRUE;
 #else /* defined(HAVE_LIBCURSES) */
   FIXME("(%p, %d, %d): stub\n", dc, x, y);
@@ -117,24 +114,6 @@ BOOL TTYDRV_DC_LineTo(DC *dc, INT x, INT y)
 #endif /* defined(HAVE_LIBCURSES) */
 }
 
-/***********************************************************************
- *		TTYDRV_DC_MoveToEx
- */
-BOOL TTYDRV_DC_MoveToEx(DC *dc, INT x, INT y, LPPOINT pt)
-{
-  TRACE("(%p, %d, %d, %p)\n", dc, x, y, pt);
-
-  if(pt) {
-    pt->x = dc->w.CursPosX;
-    pt->y = dc->w.CursPosY;
-  }
-  
-  dc->w.CursPosX = x;
-  dc->w.CursPosY = y;
-
-  return TRUE;
-}
-
 /***********************************************************************
  *		TTYDRV_DC_PaintRgn
  */
@@ -160,11 +139,9 @@ BOOL TTYDRV_DC_Pie(DC *dc, INT left, INT top, INT right, INT bottom,
 /***********************************************************************
  *		TTYDRV_DC_PolyBezier
  */
-BOOL TTYDRV_DC_PolyBezier(DC *dc, POINT start,
-			  const POINT* BezierPoints, DWORD count)
+BOOL TTYDRV_DC_PolyBezier(DC *dc, const POINT* BezierPoints, DWORD count)
 {
-  FIXME("(%p, {%ld, %ld}, %p, %lu): stub\n",
-	dc, start.x, start.y, BezierPoints, count);
+  FIXME("(%p, %p, %lu): stub\n", dc, BezierPoints, count);
 
   return TRUE;
 }
diff --git a/graphics/ttydrv/init.c b/graphics/ttydrv/init.c
index ae3cdf122f1..079d4644480 100644
--- a/graphics/ttydrv/init.c
+++ b/graphics/ttydrv/init.c
@@ -21,10 +21,15 @@ DEFAULT_DEBUG_CHANNEL(ttydrv)
 static const DC_FUNCTIONS TTYDRV_DC_Driver =
 {
   NULL,                /* pAbortDoc */
+  NULL,                /* pAbortPath */
+  NULL,                /* pAngleArc */
   TTYDRV_DC_Arc,       /* pArc */
+  NULL,                /* pArcTo */
+  NULL,                /* pBeginPath */
   TTYDRV_DC_BitBlt,    /* pBitBlt */
   NULL,                /* pBitmapBits */
   TTYDRV_DC_Chord,     /* pChord */
+  NULL,                /* pCloseFigure */
   TTYDRV_DC_CreateBitmap, /* pCreateBitmap */
   TTYDRV_DC_CreateDC,  /* pCreateDC */
   NULL,                /* pCreateDIBSection */
@@ -35,13 +40,16 @@ static const DC_FUNCTIONS TTYDRV_DC_Driver =
   TTYDRV_DC_Ellipse,   /* pEllipse */
   NULL,                /* pEndDoc */
   NULL,                /* pEndPage */
+  NULL,                /* pEndPath */
   NULL,                /* pEnumDeviceFonts */
   TTYDRV_DC_Escape,    /* pEscape */
   NULL,                /* pExcludeClipRect */
   NULL,                /* pExtDeviceMode */
   TTYDRV_DC_ExtFloodFill, /* pExtFloodFill */
   TTYDRV_DC_ExtTextOut, /* pExtTextOut */
+  NULL,                /* pFillPath */
   NULL,                /* pFillRgn */
+  NULL,                /* pFlattenPath */
   NULL,                /* pFrameRgn */
   TTYDRV_DC_GetCharWidth, /* pGetCharWidth */
   TTYDRV_DC_GetPixel,  /* pGetPixel */
@@ -51,18 +59,21 @@ static const DC_FUNCTIONS TTYDRV_DC_Driver =
   NULL,                /* pIntersectVisRect */
   TTYDRV_DC_LineTo,    /* pLineTo */
   TTYDRV_DC_LoadOEMResource, /* pLoadOEMResource */
-  TTYDRV_DC_MoveToEx,  /* pMoveToEx */
+  NULL,                /* pMoveToEx */
   NULL,                /* pOffsetClipRgn */
   NULL,                /* pOffsetViewportOrg (optional) */
   NULL,                /* pOffsetWindowOrg (optional) */
   TTYDRV_DC_PaintRgn,  /* pPaintRgn */
   TTYDRV_DC_PatBlt,    /* pPatBlt */
   TTYDRV_DC_Pie,       /* pPie */
+  TTYDRV_DC_PolyBezier, /* pPolyBezier */
+  NULL,                /* pPolyBezierTo */
+  NULL,                /* pPolyDraw */
   TTYDRV_DC_PolyPolygon, /* pPolyPolygon */
   TTYDRV_DC_PolyPolyline, /* pPolyPolyline */
   TTYDRV_DC_Polygon,   /* pPolygon */
   TTYDRV_DC_Polyline,  /* pPolyline */
-  TTYDRV_DC_PolyBezier, /* pPolyBezier */
+  NULL,                /* pPolylineTo */
   NULL,                /* pRealizePalette */
   TTYDRV_DC_Rectangle, /* pRectangle */
   NULL,                /* pRestoreDC */
@@ -70,6 +81,7 @@ static const DC_FUNCTIONS TTYDRV_DC_Driver =
   NULL,                /* pSaveDC */
   NULL,                /* pScaleViewportExt (optional) */
   NULL,                /* pScaleWindowExt (optional) */
+  NULL,                /* pSelectClipPath */
   NULL,                /* pSelectClipRgn */
   TTYDRV_DC_SelectObject, /* pSelectObject */
   NULL,                /* pSelectPalette */
@@ -95,7 +107,10 @@ static const DC_FUNCTIONS TTYDRV_DC_Driver =
   NULL,                /* pStartDoc */
   NULL,                /* pStartPage */
   TTYDRV_DC_StretchBlt, /* pStretchBlt */
-  NULL                 /* pStretchDIBits */
+  NULL,                /* pStretchDIBits */
+  NULL,                /* pStrokeAndFillPath */
+  NULL,                /* pStrokePath */
+  NULL                 /* pWidenPath */
 };
 
 
diff --git a/graphics/win16drv/init.c b/graphics/win16drv/init.c
index 267aa891e70..27ca8120469 100644
--- a/graphics/win16drv/init.c
+++ b/graphics/win16drv/init.c
@@ -45,10 +45,15 @@ static INT WIN16DRV_Escape( DC *dc, INT nEscape, INT cbInput,
 static const DC_FUNCTIONS WIN16DRV_Funcs =
 {
     NULL,                            /* pAbortDoc */
+    NULL,                            /* pAbortPath */
+    NULL,                            /* pAngleArc */
     NULL,                            /* pArc */
+    NULL,                            /* pArcTo */
+    NULL,                            /* pBeginPath */
     NULL,                            /* pBitBlt */
     NULL,                            /* pBitmapBits */
     NULL,                            /* pChord */
+    NULL,                            /* pCloseFigure */
     NULL,                            /* pCreateBitmap */
     WIN16DRV_CreateDC,               /* pCreateDC */
     NULL,                            /* pCreateDIBSection */
@@ -59,13 +64,16 @@ static const DC_FUNCTIONS WIN16DRV_Funcs =
     WIN16DRV_Ellipse,                /* pEllipse */
     NULL,                            /* pEndDoc */
     NULL,                            /* pEndPage */
+    NULL,                            /* pEndPath */
     WIN16DRV_EnumDeviceFonts,        /* pEnumDeviceFonts */
     WIN16DRV_Escape,                 /* pEscape */
     NULL,                            /* pExcludeClipRect */
     WIN16DRV_ExtDeviceMode,          /* pExtDeviceMode */
     NULL,                            /* pExtFloodFill */
     WIN16DRV_ExtTextOut,             /* pExtTextOut */
+    NULL,                            /* pFillPath */
     NULL,                            /* pFillRgn */
+    NULL,                            /* pFlattenPath */
     NULL,                            /* pFrameRgn */
     WIN16DRV_GetCharWidth,           /* pGetCharWidth */
     NULL,                            /* pGetPixel */
@@ -82,11 +90,14 @@ static const DC_FUNCTIONS WIN16DRV_Funcs =
     NULL,                            /* pPaintRgn */
     WIN16DRV_PatBlt,                 /* pPatBlt */
     NULL,                            /* pPie */
+    NULL,                            /* pPolyBezier */
+    NULL,                            /* pPolyBezierTo */
+    NULL,                            /* pPolyDraw */
     NULL,                            /* pPolyPolygon */
     NULL,                            /* pPolyPolyline */
     WIN16DRV_Polygon,                /* pPolygon */
     WIN16DRV_Polyline,               /* pPolyline */
-    NULL,                            /* pPolyBezier */
+    NULL,                            /* pPolylineTo */
     NULL,                            /* pRealizePalette */
     WIN16DRV_Rectangle,              /* pRectangle */
     NULL,                            /* pRestoreDC */
@@ -94,6 +105,7 @@ static const DC_FUNCTIONS WIN16DRV_Funcs =
     NULL,                            /* pSaveDC */
     NULL,                            /* pScaleViewportExtEx */
     NULL,                            /* pScaleWindowExtEx */
+    NULL,                            /* pSelectClipPath */
     NULL,                            /* pSelectClipRgn */
     WIN16DRV_SelectObject,           /* pSelectObject */
     NULL,                            /* pSelectPalette */
@@ -119,7 +131,10 @@ static const DC_FUNCTIONS WIN16DRV_Funcs =
     NULL,                            /* pStartDoc */
     NULL,                            /* pStartPage */
     NULL,                            /* pStretchBlt */
-    NULL                             /* pStretchDIBits */
+    NULL,                            /* pStretchDIBits */
+    NULL,                            /* pStrokeAndFillPath */
+    NULL,                            /* pStrokePath */
+    NULL                             /* pWidenPath */
 };
 
 
diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c
index 3f43619bdfd..40cf348f86a 100644
--- a/graphics/x11drv/graphics.c
+++ b/graphics/x11drv/graphics.c
@@ -298,22 +298,6 @@ BOOL X11DRV_SetupGCForText( DC * dc )
     return FALSE;
 }
 
-
-/**********************************************************************
- *	     X11DRV_MoveToEx
- */
-BOOL
-X11DRV_MoveToEx(DC *dc,INT x,INT y,LPPOINT pt) {
-    if (pt)
-    {
-	pt->x = dc->w.CursPosX;
-	pt->y = dc->w.CursPosY;
-    }
-    dc->w.CursPosX = x;
-    dc->w.CursPosY = y;
-    return TRUE;
-}
-
 /***********************************************************************
  *           X11DRV_LineTo
  */
@@ -328,8 +312,6 @@ X11DRV_LineTo( DC *dc, INT x, INT y )
 		  dc->w.DCOrgY + YLPTODP( dc, dc->w.CursPosY ),
 		  dc->w.DCOrgX + XLPTODP( dc, x ),
 		  dc->w.DCOrgY + YLPTODP( dc, y ) );
-    dc->w.CursPosX = x;
-    dc->w.CursPosY = y;
     return TRUE;
 }
 
@@ -1364,8 +1346,11 @@ static void X11DRV_Bezier(int level, DC * dc, POINT *Points,
     }
 }
 
+
+    
+
 /***********************************************************************
- *           X11DRV_PolyBezier
+ *           X11DRV_InternalPolyBezier
  *      Implement functionality for PolyBezier and PolyBezierTo
  *      calls. 
  *      [i] dc pointer to device context
@@ -1374,8 +1359,9 @@ static void X11DRV_Bezier(int level, DC * dc, POINT *Points,
  *      [i] count, number of points in BezierPoints, must be a 
  *          multiple of 3.
  */
-BOOL
-X11DRV_PolyBezier(DC *dc, POINT start, const POINT* BezierPoints, DWORD count)
+static BOOL
+X11DRV_InternalPolyBezier(DC *dc, POINT start, const POINT* BezierPoints,
+DWORD count)
 {
     POINT Points[4]; 
     int i;
@@ -1414,6 +1400,28 @@ X11DRV_PolyBezier(DC *dc, POINT start, const POINT* BezierPoints, DWORD count)
     return TRUE;
 }
 
+/**********************************************************************
+ *          X11DRV_PolyBezier
+ */
+BOOL
+X11DRV_PolyBezier(DC *dc, const POINT *Points, DWORD count)
+{
+    return X11DRV_InternalPolyBezier(dc, Points[0], Points+1, count-1);
+}
+
+/**********************************************************************
+ *          X11DRV_PolyBezierTo
+ */
+BOOL
+X11DRV_PolyBezierTo(DC *dc, const POINT *Points, DWORD count)
+{
+    POINT pt;
+
+    pt.x = dc->w.CursPosX;
+    pt.y = dc->w.CursPosY;
+    return X11DRV_InternalPolyBezier(dc, pt, Points, count);
+}
+
 /**********************************************************************
  *          X11DRV_SetBkColor
  */
diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c
index 2ea67e73570..ad33c947765 100644
--- a/graphics/x11drv/init.c
+++ b/graphics/x11drv/init.c
@@ -33,10 +33,15 @@ static INT X11DRV_Escape( DC *dc, INT nEscape, INT cbInput,
 static const DC_FUNCTIONS X11DRV_Funcs =
 {
     NULL,                            /* pAbortDoc */
+    NULL,                            /* pAbortPath */
+    NULL,                            /* pAngleArc */
     X11DRV_Arc,                      /* pArc */
+    NULL,                            /* pArcTo */
+    NULL,                            /* pBeginPath */
     X11DRV_BitBlt,                   /* pBitBlt */
     X11DRV_BitmapBits,               /* pBitmapBits */
     X11DRV_Chord,                    /* pChord */
+    NULL,                            /* pCloseFigure */
     X11DRV_CreateBitmap,             /* pCreateBitmap */
     X11DRV_CreateDC,                 /* pCreateDC */
     X11DRV_DIB_CreateDIBSection,     /* pCreateDIBSection */
@@ -47,13 +52,16 @@ static const DC_FUNCTIONS X11DRV_Funcs =
     X11DRV_Ellipse,                  /* pEllipse */
     NULL,                            /* pEndDoc */
     NULL,                            /* pEndPage */
+    NULL,                            /* pEndPath */
     X11DRV_EnumDeviceFonts,          /* pEnumDeviceFonts */
     X11DRV_Escape,                   /* pEscape */
     NULL,                            /* pExcludeClipRect */
     NULL,                            /* pExtDeviceMode */
     X11DRV_ExtFloodFill,             /* pExtFloodFill */
     X11DRV_ExtTextOut,               /* pExtTextOut */
+    NULL,                            /* pFillPath */
     NULL,                            /* pFillRgn */
+    NULL,                            /* pFlattenPath */
     NULL,                            /* pFrameRgn */
     X11DRV_GetCharWidth,             /* pGetCharWidth */
     X11DRV_GetPixel,                 /* pGetPixel */
@@ -63,18 +71,21 @@ static const DC_FUNCTIONS X11DRV_Funcs =
     NULL,                            /* pInvertRgn */
     X11DRV_LineTo,                   /* pLineTo */
     X11DRV_LoadOEMResource,          /* pLoadOEMResource */
-    X11DRV_MoveToEx,                 /* pMoveToEx */
+    NULL,                            /* pMoveToEx */
     NULL,                            /* pOffsetClipRgn */
     NULL,                            /* pOffsetViewportOrg (optional) */
     NULL,                            /* pOffsetWindowOrg (optional) */
     X11DRV_PaintRgn,                 /* pPaintRgn */
     X11DRV_PatBlt,                   /* pPatBlt */
     X11DRV_Pie,                      /* pPie */
+    X11DRV_PolyBezier,               /* pPolyBezier */
+    X11DRV_PolyBezierTo,             /* pPolyBezierTo */
+    NULL,                            /* pPolyDraw */
     X11DRV_PolyPolygon,              /* pPolyPolygon */
     X11DRV_PolyPolyline,             /* pPolyPolyline */
     X11DRV_Polygon,                  /* pPolygon */
     X11DRV_Polyline,                 /* pPolyline */
-    X11DRV_PolyBezier,               /* pPolyBezier */
+    NULL,                            /* pPolylineTo */
     NULL,                            /* pRealizePalette */
     X11DRV_Rectangle,                /* pRectangle */
     NULL,                            /* pRestoreDC */
@@ -82,6 +93,7 @@ static const DC_FUNCTIONS X11DRV_Funcs =
     NULL,                            /* pSaveDC */
     NULL,                            /* pScaleViewportExt (optional) */
     NULL,                            /* pScaleWindowExt (optional) */
+    NULL,                            /* pSelectClipPath */
     NULL,                            /* pSelectClipRgn */
     X11DRV_SelectObject,             /* pSelectObject */
     NULL,                            /* pSelectPalette */
@@ -107,7 +119,10 @@ static const DC_FUNCTIONS X11DRV_Funcs =
     NULL,                            /* pStartDoc */
     NULL,                            /* pStartPage */
     X11DRV_StretchBlt,               /* pStretchBlt */
-    NULL                             /* pStretchDIBits */
+    NULL,                            /* pStretchDIBits */
+    NULL,                            /* pStrokeAndFillPath */
+    NULL,                            /* pStrokePath */
+    NULL                             /* pWidenPath */
 };
 
 GDI_DRIVER X11DRV_GDI_Driver =
diff --git a/include/enhmetafiledrv.h b/include/enhmetafiledrv.h
index 4765392fc27..9df7c6c387f 100644
--- a/include/enhmetafiledrv.h
+++ b/include/enhmetafiledrv.h
@@ -24,17 +24,21 @@ extern void EMFDRV_UpdateBBox( DC *dc, RECTL *rect );
 extern DWORD EMFDRV_CreateBrushIndirect( DC *dc, HBRUSH hBrush );
 
 /* Metafile driver functions */
+extern BOOL     EMFDRV_AbortPath( DC *dc );
 extern BOOL     EMFDRV_Arc( DC *dc, INT left, INT top, INT right,
 			    INT bottom, INT xstart, INT ystart, INT xend,
 			    INT yend );
+extern BOOL     EMFDRV_BeginPath( DC *dc );
 extern BOOL     EMFDRV_BitBlt( DC *dcDst, INT xDst, INT yDst,
 			       INT width, INT height, DC *dcSrc,
 			       INT xSrc, INT ySrc, DWORD rop );
 extern BOOL     EMFDRV_Chord( DC *dc, INT left, INT top, INT right,
 			      INT bottom, INT xstart, INT ystart, INT xend,
 			      INT yend );
+extern BOOL     EMFDRV_CloseFigure( DC *dc );
 extern BOOL     EMFDRV_Ellipse( DC *dc, INT left, INT top,
 				INT right, INT bottom );
+extern BOOL     EMFDRV_EndPath( DC *dc );
 extern INT      EMFDRV_ExcludeClipRect( DC *dc, INT left, INT top, INT right,
 					INT bottom );
 extern BOOL     EMFDRV_ExtFloodFill( DC *dc, INT x, INT y,
@@ -42,7 +46,9 @@ extern BOOL     EMFDRV_ExtFloodFill( DC *dc, INT x, INT y,
 extern BOOL     EMFDRV_ExtTextOut( DC *dc, INT x, INT y,
 				   UINT flags, const RECT *lprect, LPCSTR str,
 				   UINT count, const INT *lpDx );
+extern BOOL     EMFDRV_FillPath( DC *dc );
 extern BOOL     EMFDRV_FillRgn( DC *dc, HRGN hrgn, HBRUSH hbrush );
+extern BOOL     EMFDRV_FlattenPath( DC *dc );
 extern BOOL     EMFDRV_FrameRgn( DC *dc, HRGN hrgn, HBRUSH hbrush, INT width,
 				 INT height );
 extern INT      EMFDRV_IntersectClipRect( DC *dc, INT left, INT top, INT right,
@@ -76,6 +82,7 @@ extern BOOL     EMFDRV_ScaleViewportExt( DC *dc, INT xNum,
 					 INT xDenom, INT yNum, INT yDenom );
 extern BOOL     EMFDRV_ScaleWindowExt( DC *dc, INT xNum, INT xDenom,
 				       INT yNum, INT yDenom );
+extern BOOL     EMFDRV_SelectClipPath( DC *dc, INT iMode );
 extern HGDIOBJ  EMFDRV_SelectObject( DC *dc, HGDIOBJ handle );
 extern COLORREF EMFDRV_SetBkColor( DC *dc, COLORREF color );
 extern INT      EMFDRV_SetBkMode( DC *dc, INT mode );
@@ -105,6 +112,9 @@ extern INT      EMFDRV_StretchDIBits( DC *dc, INT xDst, INT yDst, INT widthDst,
 				      INT widthSrc, INT heightSrc,
 				      const void *bits, const BITMAPINFO *info,
 				      UINT wUsage, DWORD dwRop );
+extern BOOL     EMFDRV_StrokeAndFillPath( DC *dc );
+extern BOOL     EMFDRV_StrokePath( DC *dc );
+extern BOOL     EMFDRV_WidenPath( DC *dc );
 
 
 #endif  /* __WINE_METAFILEDRV_H */
diff --git a/include/gdi.h b/include/gdi.h
index 9234be974db..f456d5b003b 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -170,10 +170,15 @@ typedef INT (*DEVICEFONTENUMPROC)(LPENUMLOGFONTEX16,LPNEWTEXTMETRIC16,UINT16,LPA
 typedef struct tagDC_FUNCS
 {
     INT      (*pAbortDoc)(DC*);
+    BOOL     (*pAbortPath)(DC*);
+    BOOL     (*pAngleArc)(DC*,INT,INT,DWORD,FLOAT,FLOAT);
     BOOL     (*pArc)(DC*,INT,INT,INT,INT,INT,INT,INT,INT);
+    BOOL     (*pArcTo)(DC*,INT,INT,INT,INT,INT,INT,INT,INT);    
+    BOOL     (*pBeginPath)(DC*);
     BOOL     (*pBitBlt)(DC*,INT,INT,INT,INT,DC*,INT,INT,DWORD);
     LONG     (*pBitmapBits)(HBITMAP,void*,LONG,WORD);
     BOOL     (*pChord)(DC*,INT,INT,INT,INT,INT,INT,INT,INT);
+    BOOL     (*pCloseFigure)(DC*);
     BOOL     (*pCreateBitmap)(HBITMAP); 
     BOOL     (*pCreateDC)(DC*,LPCSTR,LPCSTR,LPCSTR,const DEVMODEA*);
     HBITMAP  (*pCreateDIBSection)(DC *,BITMAPINFO *,UINT,LPVOID *,HANDLE,
@@ -186,6 +191,7 @@ typedef struct tagDC_FUNCS
     BOOL     (*pEllipse)(DC*,INT,INT,INT,INT);
     INT      (*pEndDoc)(DC*);
     INT      (*pEndPage)(DC*);
+    BOOL     (*pEndPath)(DC*);
     BOOL     (*pEnumDeviceFonts)(DC*,LPLOGFONT16,DEVICEFONTENUMPROC,LPARAM);
     INT      (*pEscape)(DC*,INT,INT,SEGPTR,SEGPTR);
     INT      (*pExcludeClipRect)(DC*,INT,INT,INT,INT);
@@ -194,7 +200,9 @@ typedef struct tagDC_FUNCS
     BOOL     (*pExtFloodFill)(DC*,INT,INT,COLORREF,UINT);
     BOOL     (*pExtTextOut)(DC*,INT,INT,UINT,const RECT*,LPCSTR,UINT,
 			    const INT*);
+    BOOL     (*pFillPath)(DC*);
     BOOL     (*pFillRgn)(DC*,HRGN,HBRUSH);
+    BOOL     (*pFlattenPath)(DC*);
     BOOL     (*pFrameRgn)(DC*,HRGN,HBRUSH,INT,INT);
     BOOL     (*pGetCharWidth)(DC*,UINT,UINT,LPINT);
     COLORREF (*pGetPixel)(DC*,INT,INT);
@@ -211,11 +219,14 @@ typedef struct tagDC_FUNCS
     BOOL     (*pPaintRgn)(DC*,HRGN);
     BOOL     (*pPatBlt)(DC*,INT,INT,INT,INT,DWORD);
     BOOL     (*pPie)(DC*,INT,INT,INT,INT,INT,INT,INT,INT);
+    BOOL     (*pPolyBezier)(DC*,const POINT*,DWORD);
+    BOOL     (*pPolyBezierTo)(DC*,const POINT*,DWORD);
+    BOOL     (*pPolyDraw)(DC*,const POINT*,const BYTE *,DWORD);
     BOOL     (*pPolyPolygon)(DC*,const POINT*,const INT*,UINT);
     BOOL     (*pPolyPolyline)(DC*,const POINT*,const DWORD*,DWORD);
     BOOL     (*pPolygon)(DC*,const POINT*,INT);
     BOOL     (*pPolyline)(DC*,const POINT*,INT);
-    BOOL     (*pPolyBezier)(DC*,POINT, const POINT*,DWORD);
+    BOOL     (*pPolylineTo)(DC*,const POINT*,INT);
     UINT     (*pRealizePalette)(DC*);
     BOOL     (*pRectangle)(DC*,INT,INT,INT,INT);
     BOOL     (*pRestoreDC)(DC*,INT);
@@ -223,6 +234,7 @@ typedef struct tagDC_FUNCS
     INT      (*pSaveDC)(DC*);
     BOOL     (*pScaleViewportExt)(DC*,INT,INT,INT,INT);
     BOOL     (*pScaleWindowExt)(DC*,INT,INT,INT,INT);
+    BOOL     (*pSelectClipPath)(DC*,INT);
     INT      (*pSelectClipRgn)(DC*,HRGN);
     HANDLE   (*pSelectObject)(DC*,HANDLE);
     HPALETTE (*pSelectPalette)(DC*,HPALETTE,BOOL);
@@ -251,6 +263,9 @@ typedef struct tagDC_FUNCS
     BOOL     (*pStretchBlt)(DC*,INT,INT,INT,INT,DC*,INT,INT,INT,INT,DWORD);
     INT      (*pStretchDIBits)(DC*,INT,INT,INT,INT,INT,INT,INT,INT,
 			       const void *,const BITMAPINFO *,UINT,DWORD);
+    BOOL     (*pStrokeAndFillPath)(DC*);
+    BOOL     (*pStrokePath)(DC*);
+    BOOL     (*pWidenPath)(DC*);
 } DC_FUNCTIONS;
 
   /* LoadOEMResource types */
diff --git a/include/metafiledrv.h b/include/metafiledrv.h
index d9faf605a43..8542c72b205 100644
--- a/include/metafiledrv.h
+++ b/include/metafiledrv.h
@@ -35,16 +35,20 @@ extern INT16 MFDRV_CreateBrushIndirect( DC *dc, HBRUSH hBrush );
 
 /* Metafile driver functions */
 
+extern BOOL MFDRV_AbortPath( DC *dc );
 extern BOOL MFDRV_Arc( DC *dc, INT left, INT top, INT right, INT bottom,
 		       INT xstart, INT ystart, INT xend, INT yend );
+extern BOOL MFDRV_BeginPath( DC *dc );
 extern BOOL MFDRV_BitBlt( DC *dcDst, INT xDst, INT yDst,  INT width,
 			  INT height, DC *dcSrc, INT xSrc, INT ySrc,
 			  DWORD rop );
 extern BOOL MFDRV_Chord( DC *dc, INT left, INT top, INT right,
 			 INT bottom, INT xstart, INT ystart, INT xend,
 			 INT yend );
+extern BOOL MFDRV_CloseFigure( DC *dc );
 extern BOOL MFDRV_Ellipse( DC *dc, INT left, INT top,
 			   INT right, INT bottom );
+extern BOOL MFDRV_EndPath( DC *dc );
 extern INT MFDRV_ExcludeClipRect( DC *dc, INT left, INT top, INT right, INT
 				  bottom );
 extern BOOL MFDRV_ExtFloodFill( DC *dc, INT x, INT y,
@@ -52,7 +56,9 @@ extern BOOL MFDRV_ExtFloodFill( DC *dc, INT x, INT y,
 extern BOOL MFDRV_ExtTextOut( DC *dc, INT x, INT y,
 			      UINT flags, const RECT *lprect, LPCSTR str,
 			      UINT count, const INT *lpDx );
+extern BOOL MFDRV_FillPath( DC *dc );
 extern BOOL MFDRV_FillRgn( DC *dc, HRGN hrgn, HBRUSH hbrush );
+extern BOOL MFDRV_FlattenPath( DC *dc );
 extern BOOL MFDRV_FrameRgn( DC *dc, HRGN hrgn, HBRUSH hbrush, INT x, INT y );
 extern INT MFDRV_IntersectClipRect( DC *dc, INT left, INT top, INT right, INT
 				    bottom );
@@ -83,6 +89,7 @@ extern BOOL MFDRV_ScaleViewportExt( DC *dc, INT xNum, INT xDenom, INT yNum,
 				    INT yDenom );
 extern BOOL MFDRV_ScaleWindowExt( DC *dc, INT xNum, INT xDenom, INT yNum,
 				  INT yDenom );
+extern BOOL MFDRV_SelectClipPath( DC *dc, INT iMode );
 extern HGDIOBJ MFDRV_SelectObject( DC *dc, HGDIOBJ handle );
 extern COLORREF MFDRV_SetBkColor( DC *dc, COLORREF color );
 extern INT MFDRV_SetBkMode( DC *dc, INT mode );
@@ -114,5 +121,9 @@ extern INT MFDRV_StretchDIBits( DC *dc, INT xDst, INT yDst, INT widthDst,
 				INT widthSrc, INT heightSrc, const void *bits,
 				const BITMAPINFO *info, UINT wUsage,
 				DWORD dwRop );
+extern BOOL MFDRV_StrokeAndFillPath( DC *dc );
+extern BOOL MFDRV_StrokePath( DC *dc );
+extern BOOL MFDRV_WidenPath( DC *dc );
 
 #endif  /* __WINE_METAFILEDRV_H */
+
diff --git a/include/path.h b/include/path.h
index b1b31fb0063..9b34e718174 100644
--- a/include/path.h
+++ b/include/path.h
@@ -50,5 +50,7 @@ extern BOOL PATH_Ellipse(HDC hdc, INT x1, INT y1,
    INT x2, INT y2);
 extern BOOL PATH_Arc(HDC hdc, INT x1, INT y1, INT x2, INT y2,
    INT xStart, INT yStart, INT xEnd, INT yEnd);
-
+extern BOOL PATH_PolyBezierTo(HDC hdc, const POINT *pt, DWORD cbCount);
 #endif /* __WINE_PATH_H */
+
+
diff --git a/include/psdrv.h b/include/psdrv.h
index dac9f7654e8..a08b888cb8f 100644
--- a/include/psdrv.h
+++ b/include/psdrv.h
@@ -336,7 +336,6 @@ extern BOOL PSDRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT count,
 					LPSIZE size );
 extern BOOL PSDRV_GetTextMetrics( DC *dc, TEXTMETRICA *metrics );
 extern BOOL PSDRV_LineTo( DC *dc, INT x, INT y );
-extern BOOL PSDRV_MoveToEx( DC *dc, INT x, INT y, LPPOINT pt );
 extern BOOL PSDRV_PatBlt( DC *dc, INT x, INT y, INT width, INT height, DWORD
 			  dwRop);
 extern BOOL PSDRV_Pie( DC *dc, INT left, INT top, INT right,
diff --git a/include/ttydrv.h b/include/ttydrv.h
index 9c7a281b5d8..621220a9db7 100644
--- a/include/ttydrv.h
+++ b/include/ttydrv.h
@@ -76,11 +76,10 @@ extern BOOL TTYDRV_DC_GetTextExtentPoint(struct tagDC *dc, LPCSTR str, INT count
 extern BOOL TTYDRV_DC_GetTextMetrics(struct tagDC *dc, TEXTMETRICA *metrics);
 extern BOOL TTYDRV_DC_LineTo(struct tagDC *dc, INT x, INT y);
 extern HANDLE TTYDRV_DC_LoadOEMResource(WORD resid, WORD type);
-extern BOOL TTYDRV_DC_MoveToEx(struct tagDC *dc, INT x, INT y, LPPOINT pt);
 extern BOOL TTYDRV_DC_PaintRgn(struct tagDC *dc, HRGN hrgn);
 extern BOOL TTYDRV_DC_PatBlt(struct tagDC *dc, INT left, INT top, INT width, INT height, DWORD rop);
 extern BOOL TTYDRV_DC_Pie(struct tagDC *dc, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend);
-extern BOOL TTYDRV_DC_PolyBezier(struct tagDC *dc, POINT start, const POINT* BezierPoints, DWORD count);
+extern BOOL TTYDRV_DC_PolyBezier(struct tagDC *dc, const POINT* BezierPoints, DWORD count);
 extern BOOL TTYDRV_DC_Polygon(struct tagDC *dc, const POINT* pt, INT count);
 extern BOOL TTYDRV_DC_Polyline(struct tagDC *dc, const POINT* pt, INT count);
 extern BOOL TTYDRV_DC_PolyPolygon(struct tagDC *dc, const POINT* pt, const INT* counts, UINT polygons);
diff --git a/include/x11drv.h b/include/x11drv.h
index e8d59b509d7..a8a0f3b6f06 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -103,7 +103,6 @@ extern BOOL X11DRV_StretchBlt( struct tagDC *dcDst, INT xDst, INT yDst,
                                  INT widthDst, INT heightDst,
                                  struct tagDC *dcSrc, INT xSrc, INT ySrc,
                                  INT widthSrc, INT heightSrc, DWORD rop );
-extern BOOL X11DRV_MoveToEx( struct tagDC *dc, INT x, INT y,LPPOINT pt);
 extern BOOL X11DRV_LineTo( struct tagDC *dc, INT x, INT y);
 extern BOOL X11DRV_Arc( struct tagDC *dc, INT left, INT top, INT right,
 			  INT bottom, INT xstart, INT ystart, INT xend,
@@ -126,7 +125,10 @@ extern COLORREF X11DRV_SetPixel( struct tagDC *dc, INT x, INT y,
 extern COLORREF X11DRV_GetPixel( struct tagDC *dc, INT x, INT y);
 extern BOOL X11DRV_PaintRgn( struct tagDC *dc, HRGN hrgn );
 extern BOOL X11DRV_Polyline( struct tagDC *dc,const POINT* pt,INT count);
-extern BOOL X11DRV_PolyBezier( struct tagDC *dc, const POINT start, const POINT* lppt, DWORD cPoints);
+extern BOOL X11DRV_PolyBezier( struct tagDC *dc, const POINT* lppt,
+			       DWORD cPoints);
+extern BOOL X11DRV_PolyBezierTo( struct tagDC *dc, const POINT* lppt,
+				 DWORD cPoints);
 extern BOOL X11DRV_Polygon( struct tagDC *dc, const POINT* pt, INT count );
 extern BOOL X11DRV_PolyPolygon( struct tagDC *dc, const POINT* pt, 
 				  const INT* counts, UINT polygons);
diff --git a/windows/painting.c b/windows/painting.c
index 5a65275cec8..d356327bd75 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -12,6 +12,7 @@
 #include "heap.h"
 #include "debugtools.h"
 #include "wine/winuser16.h"
+#include "cache.h"
 
 DECLARE_DEBUG_CHANNEL(nonclient)
 DECLARE_DEBUG_CHANNEL(win)
@@ -1224,3 +1225,408 @@ INT WINAPI ExcludeUpdateRgn( HDC hdc, HWND hwnd )
 }
 
 
+
+/***********************************************************************
+ *           FillRect16    (USER.81)
+ */
+INT16 WINAPI FillRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
+{
+    HBRUSH16 prevBrush;
+
+    /* coordinates are logical so we cannot fast-check 'rect',
+     * it will be done later in the PatBlt().
+     */
+
+    if (!(prevBrush = SelectObject16( hdc, hbrush ))) return 0;
+    PatBlt( hdc, rect->left, rect->top,
+              rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
+    SelectObject16( hdc, prevBrush );
+    return 1;
+}
+
+
+/***********************************************************************
+ *           FillRect    (USER32.197)
+ */
+INT WINAPI FillRect( HDC hdc, const RECT *rect, HBRUSH hbrush )
+{
+    HBRUSH prevBrush;
+
+    if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
+    PatBlt( hdc, rect->left, rect->top,
+              rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
+    SelectObject( hdc, prevBrush );
+    return 1;
+}
+
+
+/***********************************************************************
+ *           InvertRect16    (USER.82)
+ */
+void WINAPI InvertRect16( HDC16 hdc, const RECT16 *rect )
+{
+    PatBlt( hdc, rect->left, rect->top,
+              rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
+}
+
+
+/***********************************************************************
+ *           InvertRect    (USER32.330)
+ */
+BOOL WINAPI InvertRect( HDC hdc, const RECT *rect )
+{
+    return PatBlt( hdc, rect->left, rect->top,
+		     rect->right - rect->left, rect->bottom - rect->top, 
+		     DSTINVERT );
+}
+
+
+/***********************************************************************
+ *           FrameRect    (USER32.203)
+ */
+INT WINAPI FrameRect( HDC hdc, const RECT *rect, HBRUSH hbrush )
+{
+    HBRUSH prevBrush;
+    RECT r = *rect;
+
+    LPtoDP(hdc, (POINT *)&r, 2);
+
+    if ( (r.right <= r.left) || (r.bottom <= r.top) ) return 0;
+    if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
+    
+    PatBlt( hdc, r.left, r.top, 1,
+	      r.bottom - r.top, PATCOPY );
+    PatBlt( hdc, r.right - 1, r.top, 1,
+	      r.bottom - r.top, PATCOPY );
+    PatBlt( hdc, r.left, r.top,
+	      r.right - r.left, 1, PATCOPY );
+    PatBlt( hdc, r.left, r.bottom - 1,
+	      r.right - r.left, 1, PATCOPY );
+
+    SelectObject( hdc, prevBrush );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           FrameRect16    (USER.83)
+ */
+INT16 WINAPI FrameRect16( HDC16 hdc, const RECT16 *rect16, HBRUSH16 hbrush )
+{
+    RECT rect;
+    CONV_RECT16TO32( rect16, &rect );
+    return FrameRect( hdc, &rect, hbrush );
+}
+
+
+/***********************************************************************
+ *           DrawFocusRect16    (USER.466)
+ */
+void WINAPI DrawFocusRect16( HDC16 hdc, const RECT16* rc )
+{
+    RECT rect32;
+    CONV_RECT16TO32( rc, &rect32 );
+    DrawFocusRect( hdc, &rect32 );
+}
+
+
+/***********************************************************************
+ *           DrawFocusRect    (USER32.156)
+ *
+ * FIXME: PatBlt(PATINVERT) with background brush.
+ */
+BOOL WINAPI DrawFocusRect( HDC hdc, const RECT* rc )
+{
+    HBRUSH hOldBrush;
+    HPEN hOldPen, hNewPen;
+    INT oldDrawMode, oldBkMode;
+
+    hOldBrush = SelectObject(hdc, GetStockObject(NULL_BRUSH));
+    hNewPen = CreatePen(PS_DOT, 1, GetSysColor(COLOR_WINDOWTEXT));
+    hOldPen = SelectObject(hdc, hNewPen);
+    oldDrawMode = SetROP2(hdc, R2_XORPEN);
+    oldBkMode = SetBkMode(hdc, TRANSPARENT);
+
+    Rectangle(hdc, rc->left, rc->top, rc->right, rc->bottom);
+
+    SetBkMode(hdc, oldBkMode);
+    SetROP2(hdc, oldDrawMode);
+    SelectObject(hdc, hOldPen);
+    DeleteObject(hNewPen);
+    SelectObject(hdc, hOldBrush);
+
+    return TRUE;
+}
+
+/**********************************************************************
+ *          DrawAnimatedRects16  (USER.448)
+ */
+BOOL16 WINAPI DrawAnimatedRects16( HWND16 hwnd, INT16 idAni,
+                                   const RECT16* lprcFrom,
+                                   const RECT16* lprcTo )
+{
+    RECT rcFrom32, rcTo32;
+
+    rcFrom32.left	= (INT)lprcFrom->left;
+    rcFrom32.top	= (INT)lprcFrom->top;
+    rcFrom32.right	= (INT)lprcFrom->right;
+    rcFrom32.bottom	= (INT)lprcFrom->bottom;
+
+    rcTo32.left		= (INT)lprcTo->left;
+    rcTo32.top		= (INT)lprcTo->top;
+    rcTo32.right	= (INT)lprcTo->right;
+    rcTo32.bottom	= (INT)lprcTo->bottom;
+
+    return DrawAnimatedRects((HWND)hwnd, (INT)idAni, &rcFrom32, &rcTo32);
+}
+
+
+/**********************************************************************
+ *          DrawAnimatedRects  (USER32.153)
+ */
+BOOL WINAPI DrawAnimatedRects( HWND hwnd, int idAni,
+                                   const RECT* lprcFrom,
+                                   const RECT* lprcTo )
+{
+    FIXME_(win)("(0x%x,%d,%p,%p): stub\n",hwnd,idAni,lprcFrom,lprcTo);
+    return TRUE;
+}
+
+
+/**********************************************************************
+ *          PAINTING_DrawStateJam
+ *
+ * Jams in the requested type in the dc
+ */
+static BOOL PAINTING_DrawStateJam(HDC hdc, UINT opcode,
+                                    DRAWSTATEPROC func, LPARAM lp, WPARAM wp, 
+                                    LPRECT rc, UINT dtflags,
+                                    BOOL unicode, BOOL _32bit)
+{
+    HDC memdc;
+    HBITMAP hbmsave;
+    BOOL retval;
+    INT cx = rc->right - rc->left;
+    INT cy = rc->bottom - rc->top;
+    
+    switch(opcode)
+    {
+    case DST_TEXT:
+    case DST_PREFIXTEXT:
+        if(unicode)
+            return DrawTextW(hdc, (LPWSTR)lp, (INT)wp, rc, dtflags);
+        else if(_32bit)
+            return DrawTextA(hdc, (LPSTR)lp, (INT)wp, rc, dtflags);
+        else
+            return DrawTextA(hdc, (LPSTR)PTR_SEG_TO_LIN(lp), (INT)wp, rc, dtflags);
+
+    case DST_ICON:
+        return DrawIcon(hdc, rc->left, rc->top, (HICON)lp);
+
+    case DST_BITMAP:
+        memdc = CreateCompatibleDC(hdc);
+        if(!memdc) return FALSE;
+        hbmsave = (HBITMAP)SelectObject(memdc, (HBITMAP)lp);
+        if(!hbmsave) 
+        {
+            DeleteDC(memdc);
+            return FALSE;
+        }
+        retval = BitBlt(hdc, rc->left, rc->top, cx, cy, memdc, 0, 0, SRCCOPY);
+        SelectObject(memdc, hbmsave);
+        DeleteDC(memdc);
+        return retval;
+            
+    case DST_COMPLEX:
+        if(func)
+            if(_32bit)
+                return func(hdc, lp, wp, cx, cy);
+            else
+                return (BOOL)((DRAWSTATEPROC16)func)((HDC16)hdc, (LPARAM)lp, (WPARAM16)wp, (INT16)cx, (INT16)cy);
+        else
+            return FALSE;
+    }
+    return FALSE;
+}
+
+/**********************************************************************
+ *      PAINTING_DrawState()
+ */
+static BOOL PAINTING_DrawState(HDC hdc, HBRUSH hbr, 
+                                   DRAWSTATEPROC func, LPARAM lp, WPARAM wp,
+                                   INT x, INT y, INT cx, INT cy, 
+                                   UINT flags, BOOL unicode, BOOL _32bit)
+{
+    HBITMAP hbm, hbmsave;
+    HFONT hfsave;
+    HBRUSH hbsave;
+    HDC memdc;
+    RECT rc;
+    UINT dtflags = DT_NOCLIP;
+    COLORREF fg, bg;
+    UINT opcode = flags & 0xf;
+    INT len = wp;
+    BOOL retval, tmp;
+
+    if((opcode == DST_TEXT || opcode == DST_PREFIXTEXT) && !len)    /* The string is '\0' terminated */
+    {
+        if(unicode)
+            len = lstrlenW((LPWSTR)lp);
+        else if(_32bit)
+            len = lstrlenA((LPSTR)lp);
+        else
+            len = lstrlenA((LPSTR)PTR_SEG_TO_LIN(lp));
+    }
+
+    /* Find out what size the image has if not given by caller */
+    if(!cx || !cy)
+    {
+        SIZE s;
+        CURSORICONINFO *ici;
+	BITMAP bm;
+
+        switch(opcode)
+        {
+        case DST_TEXT:
+        case DST_PREFIXTEXT:
+            if(unicode)
+                retval = GetTextExtentPoint32W(hdc, (LPWSTR)lp, len, &s);
+            else if(_32bit)
+                retval = GetTextExtentPoint32A(hdc, (LPSTR)lp, len, &s);
+            else
+                retval = GetTextExtentPoint32A(hdc, PTR_SEG_TO_LIN(lp), len, &s);
+            if(!retval) return FALSE;
+            break;
+            
+        case DST_ICON:
+            ici = (CURSORICONINFO *)GlobalLock16((HGLOBAL16)lp);
+            if(!ici) return FALSE;
+            s.cx = ici->nWidth;
+            s.cy = ici->nHeight;
+            GlobalUnlock16((HGLOBAL16)lp);
+            break;            
+
+        case DST_BITMAP:
+	    if(!GetObjectA((HBITMAP)lp, sizeof(bm), &bm))
+	        return FALSE;
+            s.cx = bm.bmWidth;
+            s.cy = bm.bmHeight;
+            break;
+            
+        case DST_COMPLEX: /* cx and cy must be set in this mode */
+            return FALSE;
+	}
+	            
+        if(!cx) cx = s.cx;
+        if(!cy) cy = s.cy;
+    }
+
+    rc.left   = x;
+    rc.top    = y;
+    rc.right  = x + cx;
+    rc.bottom = y + cy;
+
+    if(flags & DSS_RIGHT)    /* This one is not documented in the win32.hlp file */
+        dtflags |= DT_RIGHT;
+    if(opcode == DST_TEXT)
+        dtflags |= DT_NOPREFIX;
+
+    /* For DSS_NORMAL we just jam in the image and return */
+    if((flags & 0x7ff0) == DSS_NORMAL)
+    {
+        return PAINTING_DrawStateJam(hdc, opcode, func, lp, len, &rc, dtflags, unicode, _32bit);
+    }
+
+    /* For all other states we need to convert the image to B/W in a local bitmap */
+    /* before it is displayed */
+    fg = SetTextColor(hdc, RGB(0, 0, 0));
+    bg = SetBkColor(hdc, RGB(255, 255, 255));
+    hbm = (HBITMAP)NULL; hbmsave = (HBITMAP)NULL;
+    memdc = (HDC)NULL; hbsave = (HBRUSH)NULL;
+    retval = FALSE; /* assume failure */
+    
+    /* From here on we must use "goto cleanup" when something goes wrong */
+    hbm     = CreateBitmap(cx, cy, 1, 1, NULL);
+    if(!hbm) goto cleanup;
+    memdc   = CreateCompatibleDC(hdc);
+    if(!memdc) goto cleanup;
+    hbmsave = (HBITMAP)SelectObject(memdc, hbm);
+    if(!hbmsave) goto cleanup;
+    rc.left = rc.top = 0;
+    rc.right = cx;
+    rc.bottom = cy;
+    if(!FillRect(memdc, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH))) goto cleanup;
+    SetBkColor(memdc, RGB(255, 255, 255));
+    SetTextColor(memdc, RGB(0, 0, 0));
+    hfsave  = (HFONT)SelectObject(memdc, GetCurrentObject(hdc, OBJ_FONT));
+    if(!hfsave && (opcode == DST_TEXT || opcode == DST_PREFIXTEXT)) goto cleanup;
+    tmp = PAINTING_DrawStateJam(memdc, opcode, func, lp, len, &rc, dtflags, unicode, _32bit);
+    if(hfsave) SelectObject(memdc, hfsave);
+    if(!tmp) goto cleanup;
+    
+    /* These states cause the image to be dithered */
+    if(flags & (DSS_UNION|DSS_DISABLED))
+    {
+        hbsave = (HBRUSH)SelectObject(memdc, CACHE_GetPattern55AABrush());
+        if(!hbsave) goto cleanup;
+        tmp = PatBlt(memdc, 0, 0, cx, cy, 0x00FA0089);
+        if(hbsave) SelectObject(memdc, hbsave);
+        if(!tmp) goto cleanup;
+    }
+
+    hbsave = (HBRUSH)SelectObject(hdc, hbr ? hbr : GetStockObject(WHITE_BRUSH));
+    if(!hbsave) goto cleanup;
+    
+    if(!BitBlt(hdc, x, y, cx, cy, memdc, 0, 0, 0x00B8074A)) goto cleanup;
+    
+    /* DSS_DEFAULT makes the image boldface */
+    if(flags & DSS_DEFAULT)
+    {
+        if(!BitBlt(hdc, x+1, y, cx, cy, memdc, 0, 0, 0x00B8074A)) goto cleanup;
+    }
+
+    retval = TRUE; /* We succeeded */
+    
+cleanup:    
+    SetTextColor(hdc, fg);
+    SetBkColor(hdc, bg);
+
+    if(hbsave)  SelectObject(hdc, hbsave);
+    if(hbmsave) SelectObject(memdc, hbmsave);
+    if(hbm)     DeleteObject(hbm);
+    if(memdc)   DeleteDC(memdc);
+
+    return retval;
+}
+
+/**********************************************************************
+ *      DrawStateA()   (USER32.162)
+ */
+BOOL WINAPI DrawStateA(HDC hdc, HBRUSH hbr,
+                   DRAWSTATEPROC func, LPARAM ldata, WPARAM wdata,
+                   INT x, INT y, INT cx, INT cy, UINT flags)
+{
+    return PAINTING_DrawState(hdc, hbr, func, ldata, wdata, x, y, cx, cy, flags, FALSE, TRUE);
+}
+
+/**********************************************************************
+ *      DrawStateW()   (USER32.163)
+ */
+BOOL WINAPI DrawStateW(HDC hdc, HBRUSH hbr,
+                   DRAWSTATEPROC func, LPARAM ldata, WPARAM wdata,
+                   INT x, INT y, INT cx, INT cy, UINT flags)
+{
+    return PAINTING_DrawState(hdc, hbr, func, ldata, wdata, x, y, cx, cy, flags, TRUE, TRUE);
+}
+
+/**********************************************************************
+ *      DrawState16()   (USER.449)
+ */
+BOOL16 WINAPI DrawState16(HDC16 hdc, HBRUSH16 hbr,
+                   DRAWSTATEPROC16 func, LPARAM ldata, WPARAM16 wdata,
+                   INT16 x, INT16 y, INT16 cx, INT16 cy, UINT16 flags)
+{
+    return PAINTING_DrawState(hdc, hbr, (DRAWSTATEPROC)func, ldata, wdata, x, y, cx, cy, flags, FALSE, FALSE);
+}
+
+
-- 
GitLab