[Gdi32]
authorJames Tabor <james.tabor@reactos.org>
Thu, 6 Jul 2017 18:52:22 +0000 (18:52 +0000)
committerJames Tabor <james.tabor@reactos.org>
Thu, 6 Jul 2017 18:52:22 +0000 (18:52 +0000)
- Sync/Port Wine Enhanced/Metafile code. This is a fix for CORE-12888.
- Wine made this difficult to port and keep the whole file unchanged for syncing.

svn path=/trunk/; revision=75292

17 files changed:
reactos/win32ss/gdi/gdi32/include/wine/gdi_driver.h
reactos/win32ss/gdi/gdi32/misc/misc.c
reactos/win32ss/gdi/gdi32/wine/CMakeLists.txt
reactos/win32ss/gdi/gdi32/wine/enhmetafile.c
reactos/win32ss/gdi/gdi32/wine/enhmfdrv/bitblt.c
reactos/win32ss/gdi/gdi32/wine/enhmfdrv/dc.c
reactos/win32ss/gdi/gdi32/wine/enhmfdrv/enhmetafiledrv.h
reactos/win32ss/gdi/gdi32/wine/enhmfdrv/graphics.c
reactos/win32ss/gdi/gdi32/wine/enhmfdrv/init.c
reactos/win32ss/gdi/gdi32/wine/enhmfdrv/objects.c
reactos/win32ss/gdi/gdi32/wine/gdi_private.h
reactos/win32ss/gdi/gdi32/wine/metafile.c
reactos/win32ss/gdi/gdi32/wine/mfdrv/bitblt.c
reactos/win32ss/gdi/gdi32/wine/mfdrv/init.c
reactos/win32ss/gdi/gdi32/wine/mfdrv/objects.c
reactos/win32ss/gdi/gdi32/wine/path.c [new file with mode: 0644]
reactos/win32ss/gdi/gdi32/wine/rosglue.c

index f8bfe8c..fcf3de9 100644 (file)
@@ -97,7 +97,6 @@ struct gdi_dc_funcs
     BOOL     (*pFontIsLinked)(PHYSDEV);
     BOOL     (*pFrameRgn)(PHYSDEV,HRGN,HBRUSH,INT,INT);
     BOOL     (*pGdiComment)(PHYSDEV,UINT,const BYTE*);
-    BOOL     (*pGdiRealizationInfo)(PHYSDEV,void*);
     UINT     (*pGetBoundsRect)(PHYSDEV,RECT*,UINT);
     BOOL     (*pGetCharABCWidths)(PHYSDEV,UINT,UINT,LPABC);
     BOOL     (*pGetCharABCWidthsI)(PHYSDEV,UINT,UINT,WORD*,LPABC);
@@ -105,6 +104,7 @@ struct gdi_dc_funcs
     INT      (*pGetDeviceCaps)(PHYSDEV,INT);
     BOOL     (*pGetDeviceGammaRamp)(PHYSDEV,LPVOID);
     DWORD    (*pGetFontData)(PHYSDEV,DWORD,DWORD,LPVOID,DWORD);
+    BOOL     (*pGdiFontRealizationInfo)(PHYSDEV,void*);
     DWORD    (*pGetFontUnicodeRanges)(PHYSDEV,LPGLYPHSET);
     DWORD    (*pGetGlyphIndices)(PHYSDEV,LPCWSTR,INT,LPWORD,DWORD);
     DWORD    (*pGetGlyphOutline)(PHYSDEV,UINT,UINT,LPGLYPHMETRICS,DWORD,LPVOID,const MAT2*);
@@ -213,7 +213,7 @@ static inline PHYSDEV get_physdev_entry_point( PHYSDEV dev, size_t offset )
 
 #define GET_NEXT_PHYSDEV(dev,func) \
     get_physdev_entry_point( (dev)->next, FIELD_OFFSET(struct gdi_dc_funcs,func))
-
+/*
 static inline void push_dc_driver( PHYSDEV *dev, PHYSDEV physdev, const struct gdi_dc_funcs *funcs )
 {
     while ((*dev)->funcs->priority > funcs->priority) dev = &(*dev)->next;
@@ -222,7 +222,7 @@ static inline void push_dc_driver( PHYSDEV *dev, PHYSDEV physdev, const struct g
     physdev->hdc = (*dev)->hdc;
     *dev = physdev;
 }
-
+*/
 /* support for window surfaces */
 
 struct window_surface;
index 95b2bf4..50eac9c 100644 (file)
@@ -1038,8 +1038,21 @@ BOOL
 WINAPI
 GdiAddGlsBounds(HDC hdc,LPRECT prc)
 {
-    //FIXME: Lookup what 0x8000 means
-    return NtGdiSetBoundsRect(hdc, prc, 0x8000 |  DCB_ACCUMULATE ) ? TRUE : FALSE;
+    return NtGdiSetBoundsRect(hdc, prc, DCB_WINDOWMGR|DCB_ACCUMULATE ) ? TRUE : FALSE;
+}
+
+BOOL
+WINAPI
+GetBoundsRectAlt(HDC hdc,LPRECT prc,UINT flags)
+{
+    return NtGdiGetBoundsRect(hdc, prc, flags);
+}
+
+BOOL
+WINAPI
+SetBoundsRectAlt(HDC hdc,LPRECT prc,UINT flags)
+{
+    return NtGdiSetBoundsRect(hdc, prc, flags );
 }
 
 /*
index e871660..861ca57 100644 (file)
@@ -8,6 +8,7 @@ include_directories(
 list(APPEND SOURCE
     enhmetafile.c
     metafile.c
+    path.c
     enhmfdrv/bitblt.c
     enhmfdrv/dc.c
     enhmfdrv/graphics.c
index b78b51e..fde60bb 100644 (file)
@@ -547,7 +547,6 @@ static void EMF_Update_MF_Xform(HDC hdc, const enum_emh_data *info)
     if (!SetWorldTransform(hdc, &final_trans))
     {
         __debugbreak();
-        SetWorldTransform(hdc, &final_trans);
         ERR("World transform failed!\n");
     }
 }
@@ -1140,9 +1139,9 @@ BOOL WINAPI PlayEnhMetaFileRecord(
        rc.top = pExtTextOutA->emrtext.rcl.top;
        rc.right = pExtTextOutA->emrtext.rcl.right;
        rc.bottom = pExtTextOutA->emrtext.rcl.bottom;
-        TRACE("EMR_EXTTEXTOUTA: x,y = %d, %d. rect = %d, %d - %d, %d. flags %08x\n",
+        TRACE("EMR_EXTTEXTOUTA: x,y = %d, %d. rect = %s. flags %08x\n",
               pExtTextOutA->emrtext.ptlReference.x, pExtTextOutA->emrtext.ptlReference.y,
-              rc.left, rc.top, rc.right, rc.bottom, pExtTextOutA->emrtext.fOptions);
+              wine_dbgstr_rect(&rc), pExtTextOutA->emrtext.fOptions);
 
         old_mode = SetGraphicsMode(hdc, pExtTextOutA->iGraphicsMode);
         /* Reselect the font back into the dc so that the transformation
@@ -1176,9 +1175,9 @@ BOOL WINAPI PlayEnhMetaFileRecord(
        rc.top = pExtTextOutW->emrtext.rcl.top;
        rc.right = pExtTextOutW->emrtext.rcl.right;
        rc.bottom = pExtTextOutW->emrtext.rcl.bottom;
-        TRACE("EMR_EXTTEXTOUTW: x,y = %d, %d.  rect = %d, %d - %d, %d. flags %08x\n",
+        TRACE("EMR_EXTTEXTOUTW: x,y = %d, %d.  rect = %s. flags %08x\n",
               pExtTextOutW->emrtext.ptlReference.x, pExtTextOutW->emrtext.ptlReference.y,
-              rc.left, rc.top, rc.right, rc.bottom, pExtTextOutW->emrtext.fOptions);
+              wine_dbgstr_rect(&rc), pExtTextOutW->emrtext.fOptions);
 
         old_mode = SetGraphicsMode(hdc, pExtTextOutW->iGraphicsMode);
         /* Reselect the font back into the dc so that the transformation
@@ -1232,13 +1231,18 @@ BOOL WINAPI PlayEnhMetaFileRecord(
     case EMR_EXTSELECTCLIPRGN:
       {
        const EMREXTSELECTCLIPRGN *lpRgn = (const EMREXTSELECTCLIPRGN *)mr;
+#ifdef __REACTOS__
        const RGNDATA *pRgnData = (const RGNDATA *)lpRgn->RgnData;
        DWORD dwSize = sizeof(RGNDATAHEADER) + pRgnData->rdh.nCount * sizeof(RECT);
+#endif
        HRGN hRgn = 0;
 
         if (mr->nSize >= sizeof(*lpRgn) + sizeof(RGNDATAHEADER))
+#ifdef __REACTOS__
             hRgn = ExtCreateRegion( &info->init_transform, dwSize, pRgnData );
-
+#else
+            hRgn = ExtCreateRegion( &info->init_transform, 0, (const RGNDATA *)lpRgn->RgnData );
+#endif
        ExtSelectClipRgn(hdc, hRgn, (INT)(lpRgn->iMode));
        /* ExtSelectClipRgn created a copy of the region */
        DeleteObject(hRgn);
@@ -1824,6 +1828,7 @@ BOOL WINAPI PlayEnhMetaFileRecord(
             HBITMAP hBmp = 0, hBmpOld = 0;
             const BITMAPINFO *pbi = (const BITMAPINFO *)((const BYTE *)mr + pBitBlt->offBmiSrc);
 
+            SetGraphicsMode(hdcSrc, GM_ADVANCED);
             SetWorldTransform(hdcSrc, &pBitBlt->xformSrc);
 
             hBrush = CreateSolidBrush(pBitBlt->crBkColorSrc);
@@ -1866,6 +1871,7 @@ BOOL WINAPI PlayEnhMetaFileRecord(
             HBITMAP hBmp = 0, hBmpOld = 0;
             const BITMAPINFO *pbi = (const BITMAPINFO *)((const BYTE *)mr + pStretchBlt->offBmiSrc);
 
+            SetGraphicsMode(hdcSrc, GM_ADVANCED);
             SetWorldTransform(hdcSrc, &pStretchBlt->xformSrc);
 
             hBrush = CreateSolidBrush(pStretchBlt->crBkColorSrc);
@@ -1908,6 +1914,7 @@ BOOL WINAPI PlayEnhMetaFileRecord(
             const BITMAPINFO *pbi = (const BITMAPINFO *)((const BYTE *)mr + pAlphaBlend->offBmiSrc);
             void *bits;
 
+            SetGraphicsMode(hdcSrc, GM_ADVANCED);
             SetWorldTransform(hdcSrc, &pAlphaBlend->xformSrc);
 
             hBmp = CreateDIBSection(hdc, pbi, pAlphaBlend->iUsageSrc, &bits, NULL, 0);
@@ -1933,6 +1940,7 @@ BOOL WINAPI PlayEnhMetaFileRecord(
        HBITMAP hBmp, hBmpOld, hBmpMask;
        const BITMAPINFO *pbi;
 
+        SetGraphicsMode(hdcSrc, GM_ADVANCED);
        SetWorldTransform(hdcSrc, &pMaskBlt->xformSrc);
 
        hBrush = CreateSolidBrush(pMaskBlt->crBkColorSrc);
@@ -1981,6 +1989,7 @@ BOOL WINAPI PlayEnhMetaFileRecord(
        const BITMAPINFO *pbi;
        POINT pts[3];
 
+        SetGraphicsMode(hdcSrc, GM_ADVANCED);
        SetWorldTransform(hdcSrc, &pPlgBlt->xformSrc);
 
        pts[0].x = pPlgBlt->aptlDest[0].x; pts[0].y = pPlgBlt->aptlDest[0].y;
@@ -2179,6 +2188,14 @@ BOOL WINAPI PlayEnhMetaFileRecord(
        break;
     }
 
+    case EMR_GRADIENTFILL:
+    {
+        EMRGRADIENTFILL *grad = (EMRGRADIENTFILL *)mr;
+        GdiGradientFill( hdc, grad->Ver, grad->nVer, grad->Ver + grad->nVer,
+                         grad->nTri, grad->ulMode );
+        break;
+    }
+
     case EMR_POLYDRAW16:
     case EMR_GLSRECORD:
     case EMR_GLSBOUNDEDRECORD:
@@ -2192,7 +2209,6 @@ BOOL WINAPI PlayEnhMetaFileRecord(
     case EMR_SETICMPROFILEA:
     case EMR_SETICMPROFILEW:
     case EMR_TRANSPARENTBLT:
-    case EMR_GRADIENTFILL:
     case EMR_SETLINKEDUFI:
     case EMR_COLORMATCHTOTARGETW:
     case EMR_CREATECOLORSPACEW:
@@ -2206,8 +2222,7 @@ BOOL WINAPI PlayEnhMetaFileRecord(
   tmprc.left = tmprc.top = 0;
   tmprc.right = tmprc.bottom = 1000;
   LPtoDP(hdc, (POINT*)&tmprc, 2);
-  TRACE("L:0,0 - 1000,1000 -> D:%d,%d - %d,%d\n", tmprc.left,
-       tmprc.top, tmprc.right, tmprc.bottom);
+  TRACE("L:0,0 - 1000,1000 -> D:%s\n", wine_dbgstr_rect(&tmprc));
 
   return TRUE;
 }
@@ -2375,8 +2390,7 @@ BOOL WINAPI EnumEnhMetaFile(
             double xSrcPixSize, ySrcPixSize, xscale, yscale;
             XFORM xform;
 
-            TRACE("rect: %d,%d - %d,%d. rclFrame: %d,%d - %d,%d\n",
-               lpRect->left, lpRect->top, lpRect->right, lpRect->bottom,
+            TRACE("rect: %s. rclFrame: (%d,%d)-(%d,%d)\n", wine_dbgstr_rect(lpRect),
                emh->rclFrame.left, emh->rclFrame.top, emh->rclFrame.right,
                emh->rclFrame.bottom);
 
index db0274d..9e87413 100644 (file)
@@ -122,7 +122,11 @@ BOOL EMFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst,
     pEMR->dwRop = rop;
     pEMR->xSrc = src->log_x;
     pEMR->ySrc = src->log_y;
-    GetWorldTransform(devSrc->hdc, &pEMR->xformSrc);
+#ifdef __REACTOS__
+    NtGdiGetTransform(devSrc->hdc, GdiWorldSpaceToDeviceSpace, &pEMR->xformSrc);
+#else
+    GetTransform(devSrc->hdc, 0x204, &pEMR->xformSrc);
+#endif
     pEMR->crBkColorSrc = GetBkColor(devSrc->hdc);
     pEMR->iUsageSrc = DIB_RGB_COLORS;
     pEMR->offBmiSrc = emrSize;
index cbf3f5c..b5b472e 100644 (file)
@@ -2,6 +2,7 @@
  * Enhanced MetaFile driver dc value functions
  *
  * Copyright 1999 Huw D M Davies
+ * Copyright 2016 Alexandre Julliard
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include <assert.h>
 #include "enhmfdrv/enhmetafiledrv.h"
-#include "wine/debug.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
+/* get the emf physdev from the path physdev */
+static inline PHYSDEV get_emfdev( PHYSDEV path )
+{
+    return &CONTAINING_RECORD( path, EMFDRV_PDEVICE, pathdev )->dev;
+}
+
+static const struct gdi_dc_funcs emfpath_driver;
 
 INT EMFDRV_SaveDC( PHYSDEV dev )
 {
@@ -41,8 +48,8 @@ INT EMFDRV_SaveDC( PHYSDEV dev )
 BOOL EMFDRV_RestoreDC( PHYSDEV dev, INT level )
 {
     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRestoreDC );
-    EMFDRV_PDEVICE* physDev = (EMFDRV_PDEVICE*)dev;
-    DC *dc = get_dc_ptr( dev->hdc );
+    EMFDRV_PDEVICE* physDev = get_emf_physdev( dev );
+    DC *dc = get_physdev_dc( dev );
     EMRRESTOREDC emr;
     BOOL ret;
 
@@ -53,7 +60,6 @@ BOOL EMFDRV_RestoreDC( PHYSDEV dev, INT level )
         emr.iRelative = level;
     else
         emr.iRelative = level - dc->saveLevel - 1;
-    release_dc_ptr( dc );
 
     physDev->restoring++;
     ret = next->funcs->pRestoreDC( next, level );
@@ -94,7 +100,7 @@ INT EMFDRV_SetBkMode( PHYSDEV dev, INT mode )
 COLORREF EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
 {
     EMRSETBKCOLOR emr;
-    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
 
     if (physDev->restoring) return color;  /* don't output records during RestoreDC */
 
@@ -108,7 +114,7 @@ COLORREF EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
 COLORREF EMFDRV_SetTextColor( PHYSDEV dev, COLORREF color )
 {
     EMRSETTEXTCOLOR emr;
-    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
 
     if (physDev->restoring) return color;  /* don't output records during RestoreDC */
 
@@ -420,12 +426,21 @@ BOOL EMFDRV_AbortPath( PHYSDEV dev )
 
 BOOL EMFDRV_BeginPath( PHYSDEV dev )
 {
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pBeginPath );
     EMRBEGINPATH emr;
+    DC *dc = get_physdev_dc( dev );
 
     emr.emr.iType = EMR_BEGINPATH;
     emr.emr.nSize = sizeof(emr);
 
-    return EMFDRV_WriteRecord( dev, &emr.emr );
+    if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
+    if (physDev->path) return TRUE;  /* already open */
+
+    if (!next->funcs->pBeginPath( next )) return FALSE;
+    push_dc_driver( &dc->physDev, &physDev->pathdev, &emfpath_driver );
+    physDev->path = TRUE;
+    return TRUE;
 }
 
 BOOL EMFDRV_CloseFigure( PHYSDEV dev )
@@ -435,7 +450,8 @@ BOOL EMFDRV_CloseFigure( PHYSDEV dev )
     emr.emr.iType = EMR_CLOSEFIGURE;
     emr.emr.nSize = sizeof(emr);
 
-    return EMFDRV_WriteRecord( dev, &emr.emr );
+    EMFDRV_WriteRecord( dev, &emr.emr );
+    return FALSE;  /* always fails without a path */
 }
 
 BOOL EMFDRV_EndPath( PHYSDEV dev )
@@ -445,21 +461,8 @@ BOOL EMFDRV_EndPath( PHYSDEV dev )
     emr.emr.iType = EMR_ENDPATH;
     emr.emr.nSize = sizeof(emr);
 
-    return EMFDRV_WriteRecord( dev, &emr.emr );
-}
-
-BOOL EMFDRV_FillPath( PHYSDEV dev )
-{
-    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( dev, &emr.emr );
+    EMFDRV_WriteRecord( dev, &emr.emr );
+    return FALSE;  /* always fails without a path */
 }
 
 BOOL EMFDRV_FlattenPath( PHYSDEV dev )
@@ -474,58 +477,480 @@ BOOL EMFDRV_FlattenPath( PHYSDEV dev )
 
 BOOL EMFDRV_SelectClipPath( PHYSDEV dev, INT iMode )
 {
-    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectClipPath );
+ //   PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectClipPath ); This HACK breaks test_emf_clipping
     EMRSELECTCLIPPATH emr;
+ //   BOOL ret = FALSE;
+ //   HRGN hrgn;
 
     emr.emr.iType = EMR_SELECTCLIPPATH;
     emr.emr.nSize = sizeof(emr);
     emr.iMode = iMode;
 
     if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
-    return next->funcs->pSelectClipPath( next, iMode );
+/*    hrgn = PathToRegion( dev->hdc );
+    if (hrgn)
+    {
+        ret = next->funcs->pExtSelectClipRgn( next, hrgn, iMode );
+        DeleteObject( hrgn );
+    } ERR("EMFDRV_SelectClipPath ret %d\n",ret);
+    return ret;*/
+    return TRUE;
 }
 
-BOOL EMFDRV_StrokeAndFillPath( PHYSDEV dev )
+BOOL EMFDRV_WidenPath( PHYSDEV dev )
 {
-    EMRSTROKEANDFILLPATH emr;
+    EMRWIDENPATH emr;
 
-    emr.emr.iType = EMR_STROKEANDFILLPATH;
+    emr.emr.iType = EMR_WIDENPATH;
     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( dev, &emr.emr );
 }
 
-BOOL EMFDRV_StrokePath( PHYSDEV dev )
+INT EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap)
 {
-    EMRSTROKEPATH emr;
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
 
-    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( dev, &emr.emr );
+    return GetDeviceCaps( physDev->ref_dc, cap );
 }
 
-BOOL EMFDRV_WidenPath( PHYSDEV dev )
+
+/***********************************************************************
+ *           emfpathdrv_AbortPath
+ */
+static BOOL emfpathdrv_AbortPath( PHYSDEV dev )
 {
-    EMRWIDENPATH emr;
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pAbortPath );
+    DC *dc = get_physdev_dc( dev );
 
-    emr.emr.iType = EMR_WIDENPATH;
-    emr.emr.nSize = sizeof(emr);
+    emfpath_driver.pDeleteDC( pop_dc_driver( dc, &emfpath_driver ));
+    emfdev->funcs->pAbortPath( emfdev );
+    return next->funcs->pAbortPath( next );
+}
 
-    return EMFDRV_WriteRecord( dev, &emr.emr );
+/***********************************************************************
+ *           emfpathdrv_AngleArc
+ */
+static BOOL emfpathdrv_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pAngleArc );
+
+    return (emfdev->funcs->pAngleArc( emfdev, x, y, radius, start, sweep ) &&
+            next->funcs->pAngleArc( next, x, y, radius, start, sweep ));
 }
 
-INT EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap)
+/***********************************************************************
+ *           emfpathdrv_Arc
+ */
+static BOOL emfpathdrv_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
+                            INT xstart, INT ystart, INT xend, INT yend )
 {
-    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pArc );
 
-    return GetDeviceCaps( physDev->ref_dc, cap );
+    return (emfdev->funcs->pArc( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) &&
+            next->funcs->pArc( next, left, top, right, bottom, xstart, ystart, xend, yend ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_ArcTo
+ */
+static BOOL emfpathdrv_ArcTo( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
+                              INT xstart, INT ystart, INT xend, INT yend )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pArcTo );
+
+    return (emfdev->funcs->pArcTo( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) &&
+            next->funcs->pArcTo( next, left, top, right, bottom, xstart, ystart, xend, yend ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_BeginPath
+ */
+static BOOL emfpathdrv_BeginPath( PHYSDEV dev )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pBeginPath );
+
+    return (emfdev->funcs->pBeginPath( emfdev ) && next->funcs->pBeginPath( next ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_Chord
+ */
+static BOOL emfpathdrv_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
+                              INT xstart, INT ystart, INT xend, INT yend )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pChord );
+
+    return (emfdev->funcs->pChord( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) &&
+            next->funcs->pChord( next, left, top, right, bottom, xstart, ystart, xend, yend ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_CloseFigure
+ */
+static BOOL emfpathdrv_CloseFigure( PHYSDEV dev )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pCloseFigure );
+
+    emfdev->funcs->pCloseFigure( emfdev );
+    return next->funcs->pCloseFigure( next );
+}
+
+/***********************************************************************
+ *           emfpathdrv_CreateDC
+ */
+static BOOL emfpathdrv_CreateDC( PHYSDEV *dev, LPCWSTR driver, LPCWSTR device,
+                                 LPCWSTR output, const DEVMODEW *devmode )
+{
+    assert( 0 );  /* should never be called */
+    return TRUE;
+}
+
+/*************************************************************
+ *           emfpathdrv_DeleteDC
+ */
+static BOOL emfpathdrv_DeleteDC( PHYSDEV dev )
+{
+    EMFDRV_PDEVICE *physdev = (EMFDRV_PDEVICE *)get_emfdev( dev );
+
+    physdev->path = FALSE;
+    return TRUE;
 }
+
+/***********************************************************************
+ *           emfpathdrv_Ellipse
+ */
+static BOOL emfpathdrv_Ellipse( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2 )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pEllipse );
+
+    return (emfdev->funcs->pEllipse( emfdev, x1, y1, x2, y2 ) &&
+            next->funcs->pEllipse( next, x1, y1, x2, y2 ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_EndPath
+ */
+static BOOL emfpathdrv_EndPath( PHYSDEV dev )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pEndPath );
+    DC *dc = get_physdev_dc( dev );
+
+    emfpath_driver.pDeleteDC( pop_dc_driver( dc, &emfpath_driver ));
+    emfdev->funcs->pEndPath( emfdev );
+    return next->funcs->pEndPath( next );
+}
+
+/***********************************************************************
+ *           emfpathdrv_ExtTextOut
+ */
+static BOOL emfpathdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *rect,
+                                   LPCWSTR str, UINT count, const INT *dx )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExtTextOut );
+
+    return (emfdev->funcs->pExtTextOut( emfdev, x, y, flags, rect, str, count, dx ) &&
+            next->funcs->pExtTextOut( next, x, y, flags, rect, str, count, dx ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_LineTo
+ */
+static BOOL emfpathdrv_LineTo( PHYSDEV dev, INT x, INT y )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pLineTo );
+
+    return (emfdev->funcs->pLineTo( emfdev, x, y ) && next->funcs->pLineTo( next, x, y ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_MoveTo
+ */
+static BOOL emfpathdrv_MoveTo( PHYSDEV dev, INT x, INT y )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pMoveTo );
+
+    return (emfdev->funcs->pMoveTo( emfdev, x, y ) && next->funcs->pMoveTo( next, x, y ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_Pie
+ */
+static BOOL emfpathdrv_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
+                            INT xstart, INT ystart, INT xend, INT yend )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPie );
+
+    return (emfdev->funcs->pPie( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) &&
+            next->funcs->pPie( next, left, top, right, bottom, xstart, ystart, xend, yend ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_PolyBezier
+ */
+static BOOL emfpathdrv_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyBezier );
+
+    return (emfdev->funcs->pPolyBezier( emfdev, pts, count ) &&
+            next->funcs->pPolyBezier( next, pts, count ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_PolyBezierTo
+ */
+static BOOL emfpathdrv_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyBezierTo );
+
+    return (emfdev->funcs->pPolyBezierTo( emfdev, pts, count ) &&
+            next->funcs->pPolyBezierTo( next, pts, count ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_PolyDraw
+ */
+static BOOL emfpathdrv_PolyDraw( PHYSDEV dev, const POINT *pts, const BYTE *types, DWORD count )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyDraw );
+
+    return (emfdev->funcs->pPolyDraw( emfdev, pts, types, count ) &&
+            next->funcs->pPolyDraw( next, pts, types, count ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_PolyPolygon
+ */
+static BOOL emfpathdrv_PolyPolygon( PHYSDEV dev, const POINT *pts, const INT *counts, UINT polygons )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyPolygon );
+
+    return (emfdev->funcs->pPolyPolygon( emfdev, pts, counts, polygons ) &&
+            next->funcs->pPolyPolygon( next, pts, counts, polygons ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_PolyPolyline
+ */
+static BOOL emfpathdrv_PolyPolyline( PHYSDEV dev, const POINT *pts, const DWORD *counts, DWORD polylines )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyPolyline );
+
+    return (emfdev->funcs->pPolyPolyline( emfdev, pts, counts, polylines ) &&
+            next->funcs->pPolyPolyline( next, pts, counts, polylines ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_Polygon
+ */
+static BOOL emfpathdrv_Polygon( PHYSDEV dev, const POINT *pts, INT count )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolygon );
+
+    return (emfdev->funcs->pPolygon( emfdev, pts, count ) &&
+            next->funcs->pPolygon( next, pts, count ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_Polyline
+ */
+static BOOL emfpathdrv_Polyline( PHYSDEV dev, const POINT *pts, INT count )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyline );
+
+    return (emfdev->funcs->pPolyline( emfdev, pts, count ) &&
+            next->funcs->pPolyline( next, pts, count ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_PolylineTo
+ */
+static BOOL emfpathdrv_PolylineTo( PHYSDEV dev, const POINT *pts, INT count )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolylineTo );
+
+    return (emfdev->funcs->pPolylineTo( emfdev, pts, count ) &&
+            next->funcs->pPolylineTo( next, pts, count ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_Rectangle
+ */
+static BOOL emfpathdrv_Rectangle( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2 )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRectangle );
+
+    return (emfdev->funcs->pRectangle( emfdev, x1, y1, x2, y2 ) &&
+            next->funcs->pRectangle( next, x1, y1, x2, y2 ));
+}
+
+/***********************************************************************
+ *           emfpathdrv_RoundRect
+ */
+static BOOL emfpathdrv_RoundRect( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2,
+                                  INT ell_width, INT ell_height )
+{
+    PHYSDEV emfdev = get_emfdev( dev );
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRoundRect );
+
+    return (emfdev->funcs->pRoundRect( emfdev, x1, y1, x2, y2, ell_width, ell_height ) &&
+            next->funcs->pRoundRect( next, x1, y1, x2, y2, ell_width, ell_height ));
+}
+
+static const struct gdi_dc_funcs emfpath_driver =
+{
+    NULL,                               /* pAbortDoc */
+    emfpathdrv_AbortPath,               /* pAbortPath */
+    NULL,                               /* pAlphaBlend */
+    emfpathdrv_AngleArc,                /* pAngleArc */
+    emfpathdrv_Arc,                     /* pArc */
+    emfpathdrv_ArcTo,                   /* pArcTo */
+    emfpathdrv_BeginPath,               /* pBeginPath */
+    NULL,                               /* pBlendImage */
+    emfpathdrv_Chord,                   /* pChord */
+    emfpathdrv_CloseFigure,             /* pCloseFigure */
+    NULL,                               /* pCreateCompatibleDC */
+    emfpathdrv_CreateDC,                /* pCreateDC */
+    emfpathdrv_DeleteDC,                /* pDeleteDC */
+    NULL,                               /* pDeleteObject */
+    NULL,                               /* pDeviceCapabilities */
+    emfpathdrv_Ellipse,                 /* pEllipse */
+    NULL,                               /* pEndDoc */
+    NULL,                               /* pEndPage */
+    emfpathdrv_EndPath,                 /* pEndPath */
+    NULL,                               /* pEnumFonts */
+    NULL,                               /* pEnumICMProfiles */
+    NULL,                               /* pExcludeClipRect */
+    NULL,                               /* pExtDeviceMode */
+    NULL,                               /* pExtEscape */
+    NULL,                               /* pExtFloodFill */
+    NULL,                               /* pExtSelectClipRgn */
+    emfpathdrv_ExtTextOut,              /* pExtTextOut */
+    NULL,                               /* pFillPath */
+    NULL,                               /* pFillRgn */
+    NULL,                               /* pFlattenPath */
+    NULL,                               /* pFontIsLinked */
+    NULL,                               /* pFrameRgn */
+    NULL,                               /* pGdiComment */
+    NULL,                               /* pGetBoundsRect */
+    NULL,                               /* pGetCharABCWidths */
+    NULL,                               /* pGetCharABCWidthsI */
+    NULL,                               /* pGetCharWidth */
+#ifdef __REACTOS__
+    EMFDRV_GetDeviceCaps, //// Work around HACK.
+#else
+    NULL,                               /* pGetDeviceCaps */
+#endif
+    NULL,                               /* pGetDeviceGammaRamp */
+    NULL,                               /* pGetFontData */
+    NULL,                               /* pGetFontRealizationInfo */
+    NULL,                               /* pGetFontUnicodeRanges */
+    NULL,                               /* pGetGlyphIndices */
+    NULL,                               /* pGetGlyphOutline */
+    NULL,                               /* pGetICMProfile */
+    NULL,                               /* pGetImage */
+    NULL,                               /* pGetKerningPairs */
+    NULL,                               /* pGetNearestColor */
+    NULL,                               /* pGetOutlineTextMetrics */
+    NULL,                               /* pGetPixel */
+    NULL,                               /* pGetSystemPaletteEntries */
+    NULL,                               /* pGetTextCharsetInfo */
+    NULL,                               /* pGetTextExtentExPoint */
+    NULL,                               /* pGetTextExtentExPointI */
+    NULL,                               /* pGetTextFace */
+    NULL,                               /* pGetTextMetrics */
+    NULL,                               /* pGradientFill */
+    NULL,                               /* pIntersectClipRect */
+    NULL,                               /* pInvertRgn */
+    emfpathdrv_LineTo,                  /* pLineTo */
+    NULL,                               /* pModifyWorldTransform */
+    emfpathdrv_MoveTo,                  /* pMoveTo */
+    NULL,                               /* pOffsetClipRgn */
+    NULL,                               /* pOffsetViewportOrg */
+    NULL,                               /* pOffsetWindowOrg */
+    NULL,                               /* pPaintRgn */
+    NULL,                               /* pPatBlt */
+    emfpathdrv_Pie,                     /* pPie */
+    emfpathdrv_PolyBezier,              /* pPolyBezier */
+    emfpathdrv_PolyBezierTo,            /* pPolyBezierTo */
+    emfpathdrv_PolyDraw,                /* pPolyDraw */
+    emfpathdrv_PolyPolygon,             /* pPolyPolygon */
+    emfpathdrv_PolyPolyline,            /* pPolyPolyline */
+    emfpathdrv_Polygon,                 /* pPolygon */
+    emfpathdrv_Polyline,                /* pPolyline */
+    emfpathdrv_PolylineTo,              /* pPolylineTo */
+    NULL,                               /* pPutImage */
+    NULL,                               /* pRealizeDefaultPalette */
+    NULL,                               /* pRealizePalette */
+    emfpathdrv_Rectangle,               /* pRectangle */
+    NULL,                               /* pResetDC */
+    NULL,                               /* pRestoreDC */
+    emfpathdrv_RoundRect,               /* pRoundRect */
+    NULL,                               /* pSaveDC */
+    NULL,                               /* pScaleViewportExt */
+    NULL,                               /* pScaleWindowExt */
+    NULL,                               /* pSelectBitmap */
+    NULL,                               /* pSelectBrush */
+    NULL,                               /* pSelectClipPath */
+    NULL,                               /* pSelectFont */
+    NULL,                               /* pSelectPalette */
+    NULL,                               /* pSelectPen */
+    NULL,                               /* pSetArcDirection */
+    NULL,                               /* pSetBkColor */
+    NULL,                               /* pSetBkMode */
+    NULL,                               /* pSetDCBrushColor */
+    NULL,                               /* pSetDCPenColor */
+    NULL,                               /* pSetDIBColorTable */
+    NULL,                               /* pSetDIBitsToDevice */
+    NULL,                               /* pSetDeviceClipping */
+    NULL,                               /* pSetDeviceGammaRamp */
+    NULL,                               /* pSetLayout */
+    NULL,                               /* pSetMapMode */
+    NULL,                               /* pSetMapperFlags */
+    NULL,                               /* pSetPixel */
+    NULL,                               /* pSetPolyFillMode */
+    NULL,                               /* pSetROP2 */
+    NULL,                               /* pSetRelAbs */
+    NULL,                               /* pSetStretchBltMode */
+    NULL,                               /* pSetTextAlign */
+    NULL,                               /* pSetTextCharacterExtra */
+    NULL,                               /* pSetTextColor */
+    NULL,                               /* pSetTextJustification */
+    NULL,                               /* pSetViewportExt */
+    NULL,                               /* pSetViewportOrg */
+    NULL,                               /* pSetWindowExt */
+    NULL,                               /* pSetWindowOrg */
+    NULL,                               /* pSetWorldTransform */
+    NULL,                               /* pStartDoc */
+    NULL,                               /* pStartPage */
+    NULL,                               /* pStretchBlt */
+    NULL,                               /* pStretchDIBits */
+    NULL,                               /* pStrokeAndFillPath */
+    NULL,                               /* pStrokePath */
+    NULL,                               /* pUnrealizePalette */
+    NULL,                               /* pWidenPath */
+    NULL,                               /* wine_get_wgl_driver */
+    GDI_PRIORITY_PATH_DRV + 1           /* priority */
+};
index 7c1e54c..547c411 100644 (file)
@@ -33,6 +33,7 @@
 typedef struct
 {
     struct gdi_physdev dev;
+    struct gdi_physdev pathdev;
     ENHMETAHEADER  *emh;           /* Pointer to enhanced metafile header */
     UINT       handles_size, cur_handles;
     HGDIOBJ   *handles;
@@ -58,8 +59,11 @@ extern DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush ) DECLSPEC_H
 
 /* Metafile driver functions */
 extern BOOL     EMFDRV_AbortPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
+extern BOOL     EMFDRV_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep ) DECLSPEC_HIDDEN;
 extern BOOL     EMFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right,
                             INT bottom, INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
+extern BOOL     EMFDRV_ArcTo( PHYSDEV dev, INT left, INT top, INT right,
+                              INT bottom, INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
 extern BOOL     EMFDRV_BeginPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
 extern BOOL     EMFDRV_BitBlt( PHYSDEV devDst, INT xDst, INT yDst, INT width, INT height,
                                PHYSDEV devSrc, INT xSrc, INT ySrc, DWORD rop ) DECLSPEC_HIDDEN;
@@ -80,6 +84,8 @@ extern BOOL     EMFDRV_FlattenPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
 extern BOOL     EMFDRV_FrameRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT width, INT height ) DECLSPEC_HIDDEN;
 extern BOOL     EMFDRV_GdiComment( PHYSDEV dev, UINT bytes, const BYTE *buffer ) DECLSPEC_HIDDEN;
 extern INT      EMFDRV_GetDeviceCaps( PHYSDEV dev, INT cap ) DECLSPEC_HIDDEN;
+extern BOOL     EMFDRV_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert,
+                                     void *grad_array, ULONG ngrad, ULONG mode ) DECLSPEC_HIDDEN;
 extern INT      EMFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN;
 extern BOOL     EMFDRV_InvertRgn( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN;
 extern BOOL     EMFDRV_LineTo( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
@@ -94,10 +100,12 @@ extern BOOL     EMFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right, INT botto
                             INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
 extern BOOL     EMFDRV_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count ) DECLSPEC_HIDDEN;
 extern BOOL     EMFDRV_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count ) DECLSPEC_HIDDEN;
+extern BOOL     EMFDRV_PolyDraw( PHYSDEV dev, const POINT *pts, const BYTE *types, DWORD count ) DECLSPEC_HIDDEN;
 extern BOOL     EMFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polys) DECLSPEC_HIDDEN;
 extern BOOL     EMFDRV_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWORD polys) DECLSPEC_HIDDEN;
 extern BOOL     EMFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count ) DECLSPEC_HIDDEN;
 extern BOOL     EMFDRV_Polyline( PHYSDEV dev, const POINT* pt,INT count) DECLSPEC_HIDDEN;
+extern BOOL     EMFDRV_PolylineTo( PHYSDEV dev, const POINT* pt,INT count) DECLSPEC_HIDDEN;
 extern BOOL     EMFDRV_Rectangle( PHYSDEV dev, INT left, INT top, INT right, INT bottom) DECLSPEC_HIDDEN;
 extern BOOL     EMFDRV_RestoreDC( PHYSDEV dev, INT level ) DECLSPEC_HIDDEN;
 extern BOOL     EMFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
index 009f69f..7e0f4e0 100644 (file)
@@ -69,10 +69,14 @@ static void *store_points( POINTL *dest, const POINT *pts, UINT count, BOOL shor
 }
 
 /* compute the bounds of an array of points, optionally including the current position */
+#ifdef __REACTOS__
 static void get_points_bounds( RECTL *bounds, const POINT *pts, UINT count, HDC hdc )
+#else
+static void get_points_bounds( RECTL *bounds, const POINT *pts, UINT count, DC *dc )
+#endif
 {
     UINT i;
-
+#ifdef __REACTOS__
     if (hdc)
     {
         POINT cur_pt;
@@ -80,6 +84,13 @@ static void get_points_bounds( RECTL *bounds, const POINT *pts, UINT count, HDC
         bounds->left = bounds->right = cur_pt.x;
         bounds->top = bounds->bottom = cur_pt.y;
     }
+#else
+    if (dc)
+    {
+        bounds->left = bounds->right = dc->cur_pos.x;
+        bounds->top = bounds->bottom = dc->cur_pos.y;
+    }
+#endif
     else if (count)
     {
         bounds->left = bounds->right = pts[0].x;
@@ -96,6 +107,66 @@ static void get_points_bounds( RECTL *bounds, const POINT *pts, UINT count, HDC
     }
 }
 
+/* helper for path stroke and fill functions */
+#ifdef __REACTOS__
+static BOOL emfdrv_stroke_and_fill_path( PHYSDEV dev, INT type )
+{
+    EMRSTROKEANDFILLPATH emr;
+    LPPOINT Points;
+    LPBYTE Types;
+    INT nSize;
+
+    emr.emr.iType = type;
+    emr.emr.nSize = sizeof(emr);
+
+    nSize = GetPath(dev->hdc, NULL, NULL, 0);
+    if (nSize != -1)
+    {
+       Points = HeapAlloc( GetProcessHeap(), 0, nSize*sizeof(POINT) );
+       Types  = HeapAlloc( GetProcessHeap(), 0, nSize*sizeof(BYTE) );
+
+       GetPath(dev->hdc, Points, Types, nSize);
+       get_points_bounds( &emr.rclBounds, Points, nSize, 0 );
+
+       HeapFree( GetProcessHeap(), 0, Points );
+       HeapFree( GetProcessHeap(), 0, Types );
+
+       TRACE("GetBounds l %d t %d r %d b %d\n",emr.rclBounds.left, emr.rclBounds.top, emr.rclBounds.right, emr.rclBounds.bottom);
+    }
+    else emr.rclBounds = empty_bounds;
+
+    if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
+    if (nSize == -1 ) return FALSE;
+    EMFDRV_UpdateBBox( dev, &emr.rclBounds );
+    return TRUE;
+}
+#else
+static BOOL emfdrv_stroke_and_fill_path( PHYSDEV dev, INT type )
+{
+    DC *dc = get_physdev_dc( dev );
+    EMRSTROKEANDFILLPATH emr;
+    struct gdi_path *path;
+    POINT *points;
+    BYTE *flags;
+
+    emr.emr.iType = type;
+    emr.emr.nSize = sizeof(emr);
+
+    if ((path = get_gdi_flat_path( dc, NULL )))
+    {
+        int count = get_gdi_path_data( path, &points, &flags );
+        get_points_bounds( &emr.rclBounds, points, count, 0 );
+        free_gdi_path( path );
+    }
+    else emr.rclBounds = empty_bounds;
+
+    if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
+    if (!path) return FALSE;
+    EMFDRV_UpdateBBox( dev, &emr.rclBounds );
+    return TRUE;
+}
+#endif
+
 /**********************************************************************
  *          EMFDRV_MoveTo
  */
@@ -116,6 +187,10 @@ BOOL EMFDRV_MoveTo(PHYSDEV dev, INT x, INT y)
  */
 BOOL EMFDRV_LineTo( PHYSDEV dev, INT x, INT y )
 {
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
+#ifndef __REACTOS__
+    DC *dc = get_physdev_dc( dev );
+#endif
     POINT pt;
     EMRLINETO emr;
     RECTL bounds;
@@ -127,15 +202,18 @@ BOOL EMFDRV_LineTo( PHYSDEV dev, INT x, INT y )
 
     if(!EMFDRV_WriteRecord( dev, &emr.emr ))
        return FALSE;
-
+#ifdef __REACTOS__
     GetCurrentPositionEx( dev->hdc, &pt );
-
+#else
+    pt = dc->cur_pos;
+#endif
     bounds.left   = min(x, pt.x);
     bounds.top    = min(y, pt.y);
     bounds.right  = max(x, pt.x);
     bounds.bottom = max(y, pt.y);
 
-    EMFDRV_UpdateBBox( dev, &bounds );
+    if(!physDev->path)
+        EMFDRV_UpdateBBox( dev, &bounds );
 
     return TRUE;
 }
@@ -148,6 +226,10 @@ static BOOL
 EMFDRV_ArcChordPie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
                    INT xstart, INT ystart, INT xend, INT yend, DWORD iType )
 {
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
+#ifndef __REACTOS__
+    DC *dc = get_physdev_dc( dev );
+#endif
     INT temp, xCentre, yCentre, i;
     double angleStart, angleEnd;
     double xinterStart, yinterStart, xinterEnd, yinterEnd;
@@ -158,8 +240,11 @@ EMFDRV_ArcChordPie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
 
     if(left > right) {temp = left; left = right; right = temp;}
     if(top > bottom) {temp = top; top = bottom; bottom = temp;}
-
+#ifdef __REACTOS__
     if(GetGraphicsMode(dev->hdc) == GM_COMPATIBLE) {
+#else
+    if(dc->GraphicsMode == GM_COMPATIBLE) {
+#endif
         right--;
        bottom--;
     }
@@ -237,9 +322,23 @@ EMFDRV_ArcChordPie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
        if(bounds.top > yCentre) bounds.top = yCentre;
        else if(bounds.bottom < yCentre) bounds.bottom = yCentre;
     }
+    if (iType == EMR_ARCTO)
+    {
+        POINT pt;
+#ifdef __REACTOS__
+        GetCurrentPositionEx( dev->hdc, &pt );
+#else
+        pt = dc->cur_pos;
+#endif
+        bounds.left   = min( bounds.left, pt.x );
+        bounds.top    = min( bounds.top, pt.y );
+        bounds.right  = max( bounds.right, pt.x );
+        bounds.bottom = max( bounds.bottom, pt.y );
+    }
     if(!EMFDRV_WriteRecord( dev, &emr.emr ))
         return FALSE;
-    EMFDRV_UpdateBBox( dev, &bounds );
+    if(!physDev->path)
+        EMFDRV_UpdateBBox( dev, &bounds );
     return TRUE;
 }
 
@@ -254,6 +353,16 @@ BOOL EMFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
                               xend, yend, EMR_ARC );
 }
 
+/***********************************************************************
+ *           EMFDRV_ArcTo
+ */
+BOOL EMFDRV_ArcTo( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
+                   INT xstart, INT ystart, INT xend, INT yend )
+{
+    return EMFDRV_ArcChordPie( dev, left, top, right, bottom, xstart, ystart,
+                              xend, yend, EMR_ARCTO );
+}
+
 /***********************************************************************
  *           EMFDRV_Pie
  */
@@ -275,11 +384,33 @@ BOOL EMFDRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
                               xend, yend, EMR_CHORD );
 }
 
+/***********************************************************************
+ *           EMFDRV_AngleArc
+ */
+BOOL EMFDRV_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep )
+{
+    EMRANGLEARC emr;
+
+    emr.emr.iType   = EMR_ANGLEARC;
+    emr.emr.nSize   = sizeof( emr );
+    emr.ptlCenter.x = x;
+    emr.ptlCenter.y = y;
+    emr.nRadius     = radius;
+    emr.eStartAngle = start;
+    emr.eSweepAngle = sweep;
+
+    return EMFDRV_WriteRecord( dev, &emr.emr );
+}
+
 /***********************************************************************
  *           EMFDRV_Ellipse
  */
 BOOL EMFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
 {
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
+#ifndef __REACTOS__
+    DC *dc = get_physdev_dc( dev );
+#endif
     EMRELLIPSE emr;
     INT temp;
 
@@ -289,8 +420,11 @@ BOOL EMFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
 
     if(left > right) {temp = left; left = right; right = temp;}
     if(top > bottom) {temp = top; top = bottom; bottom = temp;}
-
-    if(GetGraphicsMode( dev->hdc ) == GM_COMPATIBLE) {
+#ifdef __REACTOS__
+    if(GetGraphicsMode(dev->hdc) == GM_COMPATIBLE) {
+#else
+    if(dc->GraphicsMode == GM_COMPATIBLE) {
+#endif
         right--;
        bottom--;
     }
@@ -302,7 +436,8 @@ BOOL EMFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
     emr.rclBox.right  = right;
     emr.rclBox.bottom = bottom;
 
-    EMFDRV_UpdateBBox( dev, &emr.rclBox );
+    if(!physDev->path)
+        EMFDRV_UpdateBBox( dev, &emr.rclBox );
     return EMFDRV_WriteRecord( dev, &emr.emr );
 }
 
@@ -311,6 +446,10 @@ BOOL EMFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
  */
 BOOL EMFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
 {
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
+#ifndef __REACTOS__
+    DC *dc = get_physdev_dc( dev );
+#endif
     EMRRECTANGLE emr;
     INT temp;
 
@@ -320,8 +459,11 @@ BOOL EMFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
 
     if(left > right) {temp = left; left = right; right = temp;}
     if(top > bottom) {temp = top; top = bottom; bottom = temp;}
-
-    if(GetGraphicsMode( dev->hdc ) == GM_COMPATIBLE) {
+#ifdef __REACTOS__
+    if(GetGraphicsMode(dev->hdc) == GM_COMPATIBLE) {
+#else   
+    if(dc->GraphicsMode == GM_COMPATIBLE) {
+#endif
         right--;
        bottom--;
     }
@@ -333,7 +475,8 @@ BOOL EMFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
     emr.rclBox.right  = right;
     emr.rclBox.bottom = bottom;
 
-    EMFDRV_UpdateBBox( dev, &emr.rclBox );
+    if(!physDev->path)
+        EMFDRV_UpdateBBox( dev, &emr.rclBox );
     return EMFDRV_WriteRecord( dev, &emr.emr );
 }
 
@@ -343,6 +486,10 @@ BOOL EMFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
 BOOL EMFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right,
                  INT bottom, INT ell_width, INT ell_height )
 {
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
+#ifndef __REACTOS__
+    DC *dc = get_physdev_dc( dev );
+#endif
     EMRROUNDRECT emr;
     INT temp;
 
@@ -350,8 +497,11 @@ BOOL EMFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right,
 
     if(left > right) {temp = left; left = right; right = temp;}
     if(top > bottom) {temp = top; top = bottom; bottom = temp;}
-
-    if(GetGraphicsMode( dev->hdc ) == GM_COMPATIBLE) {
+#ifdef __REACTOS__
+    if(GetGraphicsMode(dev->hdc) == GM_COMPATIBLE) {
+#else
+    if(dc->GraphicsMode == GM_COMPATIBLE) {
+#endif
         right--;
        bottom--;
     }
@@ -365,7 +515,8 @@ BOOL EMFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right,
     emr.szlCorner.cx  = ell_width;
     emr.szlCorner.cy  = ell_height;
 
-    EMFDRV_UpdateBBox( dev, &emr.rclBox );
+    if(!physDev->path)
+        EMFDRV_UpdateBBox( dev, &emr.rclBox );
     return EMFDRV_WriteRecord( dev, &emr.emr );
 }
 
@@ -400,36 +551,35 @@ COLORREF EMFDRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color )
 static BOOL
 EMFDRV_Polylinegon( PHYSDEV dev, const POINT* pt, INT count, DWORD iType )
 {
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
+#ifndef __REACTOS__
+    DC *dc = get_physdev_dc( dev );
+#endif
     EMRPOLYLINE *emr;
     DWORD size;
-    INT i;
-    BOOL ret;
+    BOOL ret, use_small_emr = can_use_short_points( pt, count );
 
-    size = sizeof(EMRPOLYLINE) + sizeof(POINTL) * (count - 1);
+    size = use_small_emr ? offsetof( EMRPOLYLINE16, apts[count] ) : offsetof( EMRPOLYLINE, aptl[count] );
 
     emr = HeapAlloc( GetProcessHeap(), 0, size );
-    emr->emr.iType = iType;
+    emr->emr.iType = use_small_emr ? iType + EMR_POLYLINE16 - EMR_POLYLINE : iType;
     emr->emr.nSize = size;
+    emr->cptl = count;
 
-    emr->rclBounds.left = emr->rclBounds.right = pt[0].x;
-    emr->rclBounds.top = emr->rclBounds.bottom = pt[0].y;
-
-    for(i = 1; i < count; i++) {
-        if(pt[i].x < emr->rclBounds.left)
-           emr->rclBounds.left = pt[i].x;
-       else if(pt[i].x > emr->rclBounds.right)
-           emr->rclBounds.right = pt[i].x;
-       if(pt[i].y < emr->rclBounds.top)
-           emr->rclBounds.top = pt[i].y;
-       else if(pt[i].y > emr->rclBounds.bottom)
-           emr->rclBounds.bottom = pt[i].y;
-    }
+    store_points( emr->aptl, pt, count, use_small_emr );
 
-    emr->cptl = count;
-    memcpy(emr->aptl, pt, count * sizeof(POINTL));
+    if (!physDev->path)
+        get_points_bounds( &emr->rclBounds, pt, count,
+#ifdef __REACTOS__
+                           (iType == EMR_POLYBEZIERTO || iType == EMR_POLYLINETO) ? dev->hdc : 0 );
+#else
+                           (iType == EMR_POLYBEZIERTO || iType == EMR_POLYLINETO) ? dc : 0 );
+#endif
+    else
+        emr->rclBounds = empty_bounds;
 
     ret = EMFDRV_WriteRecord( dev, &emr->emr );
-    if(ret)
+    if (ret && !physDev->path)
         EMFDRV_UpdateBBox( dev, &emr->rclBounds );
     HeapFree( GetProcessHeap(), 0, emr );
     return ret;
@@ -437,70 +587,19 @@ EMFDRV_Polylinegon( PHYSDEV dev, const POINT* pt, INT count, DWORD iType )
 
 
 /**********************************************************************
- *          EMFDRV_Polylinegon16
- *
- * Helper for EMFDRV_Poly{line|gon}
- *
- *  This is not a legacy function!
- *  We are using SHORT integers to save space.
+ *          EMFDRV_Polyline
  */
-static BOOL
-EMFDRV_Polylinegon16( PHYSDEV dev, const POINT* pt, INT count, DWORD iType )
+BOOL EMFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count )
 {
-    EMRPOLYLINE16 *emr;
-    DWORD size;
-    INT i;
-    BOOL ret;
-
-    /* check whether all points fit in the SHORT int POINT structure */
-    for(i = 0; i < count; i++) {
-        if( ((pt[i].x+0x8000) & ~0xffff ) || 
-            ((pt[i].y+0x8000) & ~0xffff ) )
-            return FALSE;
-    }
-
-    size = sizeof(EMRPOLYLINE16) + sizeof(POINTS) * (count - 1);
-
-    emr = HeapAlloc( GetProcessHeap(), 0, size );
-    emr->emr.iType = iType;
-    emr->emr.nSize = size;
-
-    emr->rclBounds.left = emr->rclBounds.right = pt[0].x;
-    emr->rclBounds.top = emr->rclBounds.bottom = pt[0].y;
-
-    for(i = 1; i < count; i++) {
-        if(pt[i].x < emr->rclBounds.left)
-           emr->rclBounds.left = pt[i].x;
-       else if(pt[i].x > emr->rclBounds.right)
-           emr->rclBounds.right = pt[i].x;
-       if(pt[i].y < emr->rclBounds.top)
-           emr->rclBounds.top = pt[i].y;
-       else if(pt[i].y > emr->rclBounds.bottom)
-           emr->rclBounds.bottom = pt[i].y;
-    }
-
-    emr->cpts = count;
-    for(i = 0; i < count; i++ ) {
-        emr->apts[i].x = pt[i].x;
-        emr->apts[i].y = pt[i].y;
-    }
-
-    ret = EMFDRV_WriteRecord( dev, &emr->emr );
-    if(ret)
-        EMFDRV_UpdateBBox( dev, &emr->rclBounds );
-    HeapFree( GetProcessHeap(), 0, emr );
-    return ret;
+    return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYLINE );
 }
 
-
 /**********************************************************************
- *          EMFDRV_Polyline
+ *          EMFDRV_PolylineTo
  */
-BOOL EMFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count )
+BOOL EMFDRV_PolylineTo( PHYSDEV dev, const POINT* pt, INT count )
 {
-    if( EMFDRV_Polylinegon16( dev, pt, count, EMR_POLYLINE16 ) )
-        return TRUE;
-    return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYLINE );
+    return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYLINETO );
 }
 
 /**********************************************************************
@@ -509,8 +608,6 @@ BOOL EMFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count )
 BOOL EMFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count )
 {
     if(count < 2) return FALSE;
-    if( EMFDRV_Polylinegon16( dev, pt, count, EMR_POLYGON16 ) )
-        return TRUE;
     return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYGON );
 }
 
@@ -519,8 +616,6 @@ BOOL EMFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count )
  */
 BOOL EMFDRV_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count )
 {
-    if(EMFDRV_Polylinegon16( dev, pts, count, EMR_POLYBEZIER16 ))
-        return TRUE;
     return EMFDRV_Polylinegon( dev, pts, count, EMR_POLYBEZIER );
 }
 
@@ -529,8 +624,6 @@ BOOL EMFDRV_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count )
  */
 BOOL EMFDRV_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count )
 {
-    if(EMFDRV_Polylinegon16( dev, pts, count, EMR_POLYBEZIERTO16 ))
-        return TRUE;
     return EMFDRV_Polylinegon( dev, pts, count, EMR_POLYBEZIERTO );
 }
 
@@ -611,6 +704,43 @@ BOOL EMFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT p
 }
 
 
+/**********************************************************************
+ *          EMFDRV_PolyDraw
+ */
+BOOL EMFDRV_PolyDraw( PHYSDEV dev, const POINT *pts, const BYTE *types, DWORD count )
+{
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
+    EMRPOLYDRAW *emr;
+    BOOL ret;
+    BYTE *types_dest;
+    BOOL use_small_emr = can_use_short_points( pts, count );
+    DWORD size;
+
+    size = use_small_emr ? offsetof( EMRPOLYDRAW16, apts[count] ) : offsetof( EMRPOLYDRAW, aptl[count] );
+    size += (count + 3) & ~3;
+
+    if (!(emr = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
+
+    emr->emr.iType = use_small_emr ? EMR_POLYDRAW16 : EMR_POLYDRAW;
+    emr->emr.nSize = size;
+    emr->cptl = count;
+
+    types_dest = store_points( emr->aptl, pts, count, use_small_emr );
+    memcpy( types_dest, types, count );
+    if (count & 3) memset( types_dest + count, 0, 4 - (count & 3) );
+
+    if (!physDev->path)
+        get_points_bounds( &emr->rclBounds, pts, count, 0 );
+    else
+        emr->rclBounds = empty_bounds;
+
+    ret = EMFDRV_WriteRecord( dev, &emr->emr );
+    if (ret && !physDev->path) EMFDRV_UpdateBBox( dev, &emr->rclBounds );
+    HeapFree( GetProcessHeap(), 0, emr );
+    return ret;
+}
+
+
 /**********************************************************************
  *          EMFDRV_ExtFloodFill
  */
@@ -753,13 +883,22 @@ BOOL EMFDRV_InvertRgn( PHYSDEV dev, HRGN hrgn )
 BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *lprect,
                         LPCWSTR str, UINT count, const INT *lpDx )
 {
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
+#ifndef __REACTOS__
+    DC *dc = get_physdev_dc( dev );
+#endif
     EMREXTTEXTOUTW *pemr;
     DWORD nSize;
     BOOL ret;
     int textHeight = 0;
     int textWidth = 0;
+#ifdef __REACTOS__
     const UINT textAlign = GetTextAlign( dev->hdc );
     const INT graphicsMode = GetGraphicsMode( dev->hdc );
+#else
+    const UINT textAlign = dc->textAlign;
+    const INT graphicsMode = dc->GraphicsMode;
+#endif
     FLOAT exScale, eyScale;
 
     nSize = sizeof(*pemr) + ((count+1) & ~1) * sizeof(WCHAR) + count * sizeof(INT);
@@ -834,13 +973,14 @@ BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *lprec
         }
     }
 
-    if (!lprect)
+    if (physDev->path)
     {
         pemr->rclBounds.left = pemr->rclBounds.top = 0;
         pemr->rclBounds.right = pemr->rclBounds.bottom = -1;
         goto no_bounds;
     }
 
+    /* FIXME: handle font escapement */
     switch (textAlign & (TA_LEFT | TA_RIGHT | TA_CENTER)) {
     case TA_CENTER: {
         pemr->rclBounds.left  = x - (textWidth / 2) - 1;
@@ -886,3 +1026,81 @@ no_bounds:
     HeapFree( GetProcessHeap(), 0, pemr );
     return ret;
 }
+
+/**********************************************************************
+ *          EMFDRV_GradientFill
+ */
+BOOL EMFDRV_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert,
+                          void *grad_array, ULONG ngrad, ULONG mode )
+{
+    EMRGRADIENTFILL *emr;
+    ULONG i, pt, size, num_pts = ngrad * (mode == GRADIENT_FILL_TRIANGLE ? 3 : 2);
+    const ULONG *pts = (const ULONG *)grad_array;
+    BOOL ret;
+
+    size = FIELD_OFFSET(EMRGRADIENTFILL, Ver[nvert]) + num_pts * sizeof(pts[0]);
+
+    emr = HeapAlloc( GetProcessHeap(), 0, size );
+    if (!emr) return FALSE;
+
+    for (i = 0; i < num_pts; i++)
+    {
+        pt = pts[i];
+
+        if (i == 0)
+        {
+            emr->rclBounds.left = emr->rclBounds.right = vert_array[pt].x;
+            emr->rclBounds.top = emr->rclBounds.bottom = vert_array[pt].y;
+        }
+        else
+        {
+            if (vert_array[pt].x < emr->rclBounds.left)
+                emr->rclBounds.left = vert_array[pt].x;
+            else if (vert_array[pt].x > emr->rclBounds.right)
+                emr->rclBounds.right = vert_array[pt].x;
+            if (vert_array[pt].y < emr->rclBounds.top)
+                emr->rclBounds.top = vert_array[pt].y;
+            else if (vert_array[pt].y > emr->rclBounds.bottom)
+                emr->rclBounds.bottom = vert_array[pt].y;
+        }
+    }
+    emr->rclBounds.right--;
+    emr->rclBounds.bottom--;
+
+    emr->emr.iType = EMR_GRADIENTFILL;
+    emr->emr.nSize = size;
+    emr->nVer = nvert;
+    emr->nTri = ngrad;
+    emr->ulMode = mode;
+    memcpy( emr->Ver, vert_array, nvert * sizeof(vert_array[0]) );
+    memcpy( emr->Ver + nvert, pts, num_pts * sizeof(pts[0]) );
+
+    EMFDRV_UpdateBBox( dev, &emr->rclBounds );
+    ret = EMFDRV_WriteRecord( dev, &emr->emr );
+    HeapFree( GetProcessHeap(), 0, emr );
+    return ret;
+}
+
+/**********************************************************************
+ *          EMFDRV_FillPath
+ */
+BOOL EMFDRV_FillPath( PHYSDEV dev )
+{
+    return emfdrv_stroke_and_fill_path( dev, EMR_FILLPATH );
+}
+
+/**********************************************************************
+ *          EMFDRV_StrokeAndFillPath
+ */
+BOOL EMFDRV_StrokeAndFillPath( PHYSDEV dev )
+{
+    return emfdrv_stroke_and_fill_path( dev, EMR_STROKEANDFILLPATH );
+}
+
+/**********************************************************************
+ *           EMFDRV_StrokePath
+ */
+BOOL EMFDRV_StrokePath( PHYSDEV dev )
+{
+    return emfdrv_stroke_and_fill_path( dev, EMR_STROKEPATH );
+}
index 682f412..ce9d9fb 100644 (file)
@@ -34,14 +34,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
 
 static BOOL EMFDRV_DeleteDC( PHYSDEV dev );
 
-static const struct gdi_dc_funcs EMFDRV_Funcs =
+static const struct gdi_dc_funcs emfdrv_driver =
 {
     NULL,                            /* pAbortDoc */
     EMFDRV_AbortPath,                /* pAbortPath */
     NULL,                            /* pAlphaBlend */
-    NULL,                            /* pAngleArc */
+    EMFDRV_AngleArc,                 /* pAngleArc */
     EMFDRV_Arc,                      /* pArc */
-    NULL,                            /* pArcTo */
+    EMFDRV_ArcTo,                    /* pArcTo */
     EMFDRV_BeginPath,                /* pBeginPath */
     NULL,                            /* pBlendImage */
     EMFDRV_Chord,                    /* pChord */
@@ -69,7 +69,6 @@ static const struct gdi_dc_funcs EMFDRV_Funcs =
     NULL,                            /* pFontIsLinked */
     EMFDRV_FrameRgn,                 /* pFrameRgn */
     EMFDRV_GdiComment,               /* pGdiComment */
-    NULL,                            /* pGdiRealizationInfo */
     NULL,                            /* pGetBoundsRect */
     NULL,                            /* pGetCharABCWidths */
     NULL,                            /* pGetCharABCWidthsI */
@@ -77,6 +76,7 @@ static const struct gdi_dc_funcs EMFDRV_Funcs =
     EMFDRV_GetDeviceCaps,            /* pGetDeviceCaps */
     NULL,                            /* pGetDeviceGammaRamp */
     NULL,                            /* pGetFontData */
+    NULL,                            /* pGetFontRealizationInfo */
     NULL,                            /* pGetFontUnicodeRanges */
     NULL,                            /* pGetGlyphIndices */
     NULL,                            /* pGetGlyphOutline */
@@ -92,7 +92,7 @@ static const struct gdi_dc_funcs EMFDRV_Funcs =
     NULL,                            /* pGetTextExtentExPointI */
     NULL,                            /* pGetTextFace */
     NULL,                            /* pGetTextMetrics */
-    NULL,                            /* pGradientFill */
+    EMFDRV_GradientFill,             /* pGradientFill */
     EMFDRV_IntersectClipRect,        /* pIntersectClipRect */
     EMFDRV_InvertRgn,                /* pInvertRgn */
     EMFDRV_LineTo,                   /* pLineTo */
@@ -106,12 +106,12 @@ static const struct gdi_dc_funcs EMFDRV_Funcs =
     EMFDRV_Pie,                      /* pPie */
     EMFDRV_PolyBezier,               /* pPolyBezier */
     EMFDRV_PolyBezierTo,             /* pPolyBezierTo */
-    NULL,                            /* pPolyDraw */
+    EMFDRV_PolyDraw,                 /* pPolyDraw */
     EMFDRV_PolyPolygon,              /* pPolyPolygon */
     EMFDRV_PolyPolyline,             /* pPolyPolyline */
     EMFDRV_Polygon,                  /* pPolygon */
     EMFDRV_Polyline,                 /* pPolyline */
-    NULL,                            /* pPolylineTo */
+    EMFDRV_PolylineTo,               /* pPolylineTo */
     NULL,                            /* pPutImage */
     NULL,                            /* pRealizeDefaultPalette */
     NULL,                            /* pRealizePalette */
@@ -172,10 +172,10 @@ static const struct gdi_dc_funcs EMFDRV_Funcs =
  */
 static BOOL EMFDRV_DeleteDC( PHYSDEV dev )
 {
-    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
     UINT index;
 
-    if (physDev->emh) HeapFree( GetProcessHeap(), 0, physDev->emh );
+    HeapFree( GetProcessHeap(), 0, physDev->emh );
     for(index = 0; index < physDev->handles_size; index++)
         if(physDev->handles[index])
            GDI_hdc_not_using_object(physDev->handles[index], dev->hdc);
@@ -195,7 +195,7 @@ BOOL EMFDRV_WriteRecord( PHYSDEV dev, EMR *emr )
     DWORD len;
     DWORD bytes_written;
     ENHMETAHEADER *emh;
-    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
 
     TRACE("record %d, size %d %s\n",
           emr->iType, emr->nSize, physDev->hFile ? "(to disk)" : "");
@@ -229,7 +229,7 @@ BOOL EMFDRV_WriteRecord( PHYSDEV dev, EMR *emr )
  */
 void EMFDRV_UpdateBBox( PHYSDEV dev, RECTL *rect )
 {
-    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
     RECTL *bounds = &physDev->emh->rclBounds;
     RECTL vportRect = *rect;
 
@@ -319,11 +319,11 @@ HDC WINAPI CreateEnhMetaFileW(
     DWORD size = 0, length = 0;
     DWORD bytes_written;
 
-    TRACE("%s\n", debugstr_w(filename) );
+    TRACE("(%p %s %s %s)\n", hdc, debugstr_w(filename), wine_dbgstr_rect(rect), debugstr_w(description) );
 
     if (!(dc = alloc_dc_ptr( OBJ_ENHMETADC ))) return 0;
 
-    physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
+    physDev = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*physDev));
     if (!physDev) {
         free_dc_ptr( dc );
         return 0;
@@ -342,7 +342,7 @@ HDC WINAPI CreateEnhMetaFileW(
         return 0;
     }
 
-    push_dc_driver( &dc->physDev, &physDev->dev, &EMFDRV_Funcs );
+    push_dc_driver( &dc->physDev, &physDev->dev, &emfdrv_driver );
 
     physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0]));
     physDev->handles_size = HANDLE_LIST_INC;
@@ -352,6 +352,7 @@ HDC WINAPI CreateEnhMetaFileW(
     physDev->dc_pen = 0;
     physDev->screen_dc = 0;
     physDev->restoring = 0;
+    physDev->path = FALSE;
     if (hdc)  /* if no ref, use current display */
         physDev->ref_dc = hdc;
     else
@@ -449,7 +450,7 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
         release_dc_ptr( dc );
         return NULL;
     }
-    physDev = (EMFDRV_PDEVICE *)dc->physDev;
+    physDev = get_emf_physdev( find_dc_driver( dc, &emfdrv_driver ));
 
     if(dc->saveLevel)
         RestoreDC(hdc, 1);
@@ -463,7 +464,7 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
     emr.nPalEntries = 0;
     emr.offPalEntries = FIELD_OFFSET(EMREOF, nSizeLast);
     emr.nSizeLast = emr.emr.nSize;
-    EMFDRV_WriteRecord( dc->physDev, &emr.emr );
+    EMFDRV_WriteRecord( &physDev->dev, &emr.emr );
 
     /* Update rclFrame if not initialized in CreateEnhMetaFile */
     if(physDev->emh->rclFrame.left > physDev->emh->rclFrame.right) {
index ee156a2..af234a4 100644 (file)
@@ -34,7 +34,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
  */
 static UINT EMFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj )
 {
-    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
     UINT index;
 
     for(index = 0; index < physDev->handles_size; index++)
@@ -59,7 +59,7 @@ static UINT EMFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj )
  */
 static UINT EMFDRV_FindObject( PHYSDEV dev, HGDIOBJ obj )
 {
-    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
     UINT index;
 
     for(index = 0; index < physDev->handles_size; index++)
@@ -77,7 +77,7 @@ static UINT EMFDRV_FindObject( PHYSDEV dev, HGDIOBJ obj )
 BOOL EMFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj )
 {
     EMRDELETEOBJECT emr;
-    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev;
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
     UINT index;
     BOOL ret = TRUE;
 
@@ -136,8 +136,11 @@ DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
     case BS_DIBPATTERN:
       {
         EMRCREATEDIBPATTERNBRUSHPT *emr;
-        char buffer[sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD)]; // ros!
-        //char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
+#ifdef __REACTOS__
+        char buffer[sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD)]; // ros
+#else
+        char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
+#endif
         BITMAPINFO *info = (BITMAPINFO *)buffer;
         DWORD info_size;
         void *bits;
@@ -162,7 +165,7 @@ DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
             emr->emr.iType = EMR_CREATEMONOBRUSH;
             usage = DIB_PAL_MONO;
             /* FIXME: There is an extra DWORD written by native before the BMI.
-             *        Not sure what its meant to contain.
+             *        Not sure what it's meant to contain.
              */
             emr->offBmi = sizeof( EMRCREATEDIBPATTERNBRUSHPT ) + sizeof(DWORD);
             emr->cbBmi = sizeof( BITMAPINFOHEADER );
@@ -201,7 +204,7 @@ DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
  */
 HBRUSH EMFDRV_SelectBrush( PHYSDEV dev, HBRUSH hBrush, const struct brush_pattern *pattern )
 {
-    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
     EMRSELECTOBJECT emr;
     DWORD index;
     int i;
@@ -280,7 +283,7 @@ static BOOL EMFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont )
  */
 HFONT EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont, UINT *aa_flags )
 {
-    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
     EMRSELECTOBJECT emr;
     DWORD index;
     int i;
@@ -365,7 +368,7 @@ static DWORD EMFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen)
  */
 HPEN EMFDRV_SelectPen(PHYSDEV dev, HPEN hPen, const struct brush_pattern *pattern )
 {
-    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
     EMRSELECTOBJECT emr;
     DWORD index;
     int i;
@@ -433,7 +436,7 @@ static DWORD EMFDRV_CreatePalette(PHYSDEV dev, HPALETTE hPal)
  */
 HPALETTE EMFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPal, BOOL force )
 {
-    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
     EMRSELECTPALETTE emr;
     DWORD index;
 
@@ -463,12 +466,17 @@ found:
  */
 COLORREF EMFDRV_SetDCBrushColor( PHYSDEV dev, COLORREF color )
 {
-    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
+#ifndef __REACTOS__
+    DC *dc = get_physdev_dc( dev );
+#endif
     EMRSELECTOBJECT emr;
     DWORD index;
-
+#ifdef __REACTOS__
     if (GetCurrentObject( dev->hdc, OBJ_BRUSH ) != GetStockObject( DC_BRUSH )) return color;
-
+#else
+    if (dc->hBrush != GetStockObject( DC_BRUSH )) return color;
+#endif
     if (physDev->dc_brush) DeleteObject( physDev->dc_brush );
     if (!(physDev->dc_brush = CreateSolidBrush( color ))) return CLR_INVALID;
     if (!(index = EMFDRV_CreateBrushIndirect(dev, physDev->dc_brush ))) return CLR_INVALID;
@@ -484,13 +492,18 @@ COLORREF EMFDRV_SetDCBrushColor( PHYSDEV dev, COLORREF color )
  */
 COLORREF EMFDRV_SetDCPenColor( PHYSDEV dev, COLORREF color )
 {
-    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*)dev;
+    EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
+#ifndef __REACTOS__
+    DC *dc = get_physdev_dc( dev );
+#endif
     EMRSELECTOBJECT emr;
     DWORD index;
     LOGPEN logpen = { PS_SOLID, { 0, 0 }, color };
-
+#ifdef __REACTOS__
     if (GetCurrentObject( dev->hdc, OBJ_PEN ) != GetStockObject( DC_PEN )) return color;
-
+#else
+    if (dc->hPen != GetStockObject( DC_PEN )) return color;
+#endif
     if (physDev->dc_pen) DeleteObject( physDev->dc_pen );
     if (!(physDev->dc_pen = CreatePenIndirect( &logpen ))) return CLR_INVALID;
     if (!(index = EMFDRV_CreatePenIndirect(dev, physDev->dc_pen))) return CLR_INVALID;
index bfda6a0..2857095 100644 (file)
@@ -55,16 +55,18 @@ struct gdi_obj_funcs
 typedef struct tagWINEDC
 {
     HDC          hdc;
+    struct gdi_physdev NullPhysDev;
     PHYSDEV      physDev;          /* current top of the physdev stack */
     LONG         refcount;         /* thread refcount */
     INT          saveLevel;
-    struct gdi_physdev NullPhysDev;
     HFONT hFont;
     HBRUSH hBrush;
     HPEN hPen;
     HPALETTE hPalette;
 } WINEDC, DC;
 
+WINEDC* get_physdev_dc( PHYSDEV dev );
+
 /* brush.c */
 extern BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *usage ) DECLSPEC_HIDDEN;
 
@@ -119,6 +121,27 @@ extern UINT WINAPI GDIRealizePalette( HDC hdc ) DECLSPEC_HIDDEN;
 
 #define EMR_SETLINKEDUFI        119
 
+#define GET_DC_PHYSDEV(dc,func) \
+    get_physdev_entry_point( (dc)->physDev, FIELD_OFFSET(struct gdi_dc_funcs,func))
+
+static inline PHYSDEV pop_dc_driver( DC *dc, const struct gdi_dc_funcs *funcs )
+{
+    PHYSDEV dev, *pdev = &dc->physDev;
+    while (*pdev && (*pdev)->funcs != funcs) pdev = &(*pdev)->next;
+    if (!*pdev) return NULL;
+    dev = *pdev;
+    *pdev = dev->next;
+    return dev;
+}
+
+static inline PHYSDEV find_dc_driver( DC *dc, const struct gdi_dc_funcs *funcs )
+{
+    PHYSDEV dev;
+
+    for (dev = dc->physDev; dev; dev = dev->next) if (dev->funcs == funcs) return dev;
+    return NULL;
+}
+
 /* Undocumented value for DIB's iUsage: Indicates a mono DIB w/o pal entries */
 #define DIB_PAL_MONO 2
 
@@ -145,6 +168,9 @@ static inline int get_dib_info_size( const BITMAPINFO *info, UINT coloruse )
     return FIELD_OFFSET( BITMAPINFO, bmiColors[info->bmiHeader.biClrUsed] );
 }
 
+#define GdiWorldSpaceToDeviceSpace  0x204
+BOOL APIENTRY NtGdiGetTransform( _In_ HDC hdc, _In_ DWORD iXform, _Out_ LPXFORM pxf);
+
 /* Special sauce for reactos */
 #define GDIRealizePalette RealizePalette
 #define GDISelectPalette SelectPalette
index 7d05768..dbd5521 100644 (file)
 #include "wingdi.h"
 #include "winreg.h"
 #include "winnls.h"
-
+#ifdef __REACTOS__
 #include "wine/winternl.h"
+#else
+#include "winternl.h"
+#endif
 #include "gdi_private.h"
 #include "wine/debug.h"
 
index fd6c68f..9bf7ab5 100644 (file)
@@ -161,7 +161,7 @@ INT MFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
 
 
 /***********************************************************************
- *           MFDRV_SetDIBitsToDeivce
+ *           MFDRV_SetDIBitsToDevice
  */
 INT MFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD cx,
                              DWORD cy, INT xSrc, INT ySrc, UINT startscan,
index 7b53244..50f8ba3 100644 (file)
@@ -132,7 +132,6 @@ static const struct gdi_dc_funcs MFDRV_Funcs =
     NULL,                            /* pFontIsLinked */
     MFDRV_FrameRgn,                  /* pFrameRgn */
     NULL,                            /* pGdiComment */
-    NULL,                            /* pGdiRealizationInfo */
     MFDRV_GetBoundsRect,             /* pGetBoundsRect */
     NULL,                            /* pGetCharABCWidths */
     NULL,                            /* pGetCharABCWidthsI */
@@ -140,6 +139,7 @@ static const struct gdi_dc_funcs MFDRV_Funcs =
     MFDRV_GetDeviceCaps,             /* pGetDeviceCaps */
     NULL,                            /* pGetDeviceGammaRamp */
     NULL,                            /* pGetFontData */
+    NULL,                            /* pGetFontRealizationInfo */
     NULL,                            /* pGetFontUnicodeRanges */
     NULL,                            /* pGetGlyphIndices */
     NULL,                            /* pGetGlyphOutline */
index 59fe08a..bfaa23b 100644 (file)
@@ -176,8 +176,11 @@ INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
     case BS_PATTERN:
     case BS_DIBPATTERN:
         {
+#ifdef __REACTOS__
             char buffer[sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD)]; // ros
-            //char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
+#else
+            char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
+#endif
             BITMAPINFO *dst_info, *src_info = (BITMAPINFO *)buffer;
             DWORD info_size;
             char *dst_ptr;
diff --git a/reactos/win32ss/gdi/gdi32/wine/path.c b/reactos/win32ss/gdi/gdi32/wine/path.c
new file mode 100644 (file)
index 0000000..5cf9d3a
--- /dev/null
@@ -0,0 +1,570 @@
+//
+//
+// Do not remove this file, "Justin Case" future maintenance issues with Path arises.......
+//
+//
+
+#include <precomp.h>
+#include "gdi_private.h"
+
+#define NDEBUG
+#include <debug.h>
+
+WINEDC *get_nulldrv_dc( PHYSDEV dev );
+const struct gdi_dc_funcs path_driver DECLSPEC_HIDDEN;
+
+struct path_physdev
+{
+    struct gdi_physdev dev;
+    //struct gdi_path   *path;
+    BOOL HasPathHook;
+};
+
+static inline struct path_physdev *get_path_physdev( PHYSDEV dev )
+{
+    return CONTAINING_RECORD( dev, struct path_physdev, dev );
+}
+
+/***********************************************************************
+ *           pathdrv_BeginPath
+ */
+static BOOL pathdrv_BeginPath( PHYSDEV dev )
+{
+    DPRINT("pathdrv_BeginPath dev %p\n",dev);
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           pathdrv_AbortPath
+ */
+static BOOL pathdrv_AbortPath( PHYSDEV dev )
+{
+    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_AbortPath dev %p\n",dev);
+    path_driver.pDeleteDC( pop_dc_driver( dc, &path_driver ));
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           pathdrv_EndPath
+ */
+static BOOL pathdrv_EndPath( PHYSDEV dev )
+{
+    struct path_physdev *physdev = get_path_physdev( dev );
+    DC *dc = get_physdev_dc( dev );
+
+    DPRINT("pathdrv_EndPath dev %p\n",dev);
+
+    pop_dc_driver( dc, &path_driver );
+    HeapFree( GetProcessHeap(), 0, physdev );
+
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           pathdrv_CreateDC
+ */
+static BOOL pathdrv_CreateDC( PHYSDEV *dev, LPCWSTR driver, LPCWSTR device,
+                              LPCWSTR output, const DEVMODEW *devmode )
+{
+    struct path_physdev *physdev = HeapAlloc( GetProcessHeap(), 0, sizeof(*physdev) );
+    DPRINT("pathdrv_CreateDC dev %p\n",dev);
+    if (!physdev) return FALSE;
+    push_dc_driver( dev, &physdev->dev, &path_driver );
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_DeleteDC
+ */
+static BOOL pathdrv_DeleteDC( PHYSDEV dev )
+{
+    struct path_physdev *physdev = get_path_physdev( dev );
+    DPRINT("pathdrv_DeleteDC dev %p\n",dev);
+    HeapFree( GetProcessHeap(), 0, physdev );
+    return TRUE;
+}
+
+/*************************************************************
+ *           pathdrv_MoveTo
+ */
+static BOOL pathdrv_MoveTo( PHYSDEV dev, INT x, INT y )
+{
+//    struct path_physdev *physdev = get_path_physdev( dev );
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_MoveTo dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_LineTo
+ */
+static BOOL pathdrv_LineTo( PHYSDEV dev, INT x, INT y )
+{
+//    struct path_physdev *physdev = get_path_physdev( dev );
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_LineTo dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_Rectangle
+ */
+static BOOL pathdrv_Rectangle( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2 )
+{
+//    struct path_physdev *physdev = get_path_physdev( dev );
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_Rectangle dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_RoundRect
+ */
+static BOOL pathdrv_RoundRect( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2, INT ell_width, INT ell_height )
+{
+//    struct path_physdev *physdev = get_path_physdev( dev );
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_RoundRect dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_Ellipse
+ */
+static BOOL pathdrv_Ellipse( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2 )
+{
+//    struct path_physdev *physdev = get_path_physdev( dev );
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_Ellipse dev %p\n",dev);
+    return TRUE;
+}
+
+/*************************************************************
+ *           pathdrv_AngleArc
+ */
+static BOOL pathdrv_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT eStartAngle, FLOAT eSweepAngle)
+{
+    DPRINT("pathdrv_AngleArc dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_Arc
+ */
+static BOOL pathdrv_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
+                         INT xstart, INT ystart, INT xend, INT yend )
+{
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_Arc dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_ArcTo
+ */
+static BOOL pathdrv_ArcTo( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
+                           INT xstart, INT ystart, INT xend, INT yend )
+{
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_ArcTo dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_Chord
+ */
+static BOOL pathdrv_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
+                           INT xstart, INT ystart, INT xend, INT yend )
+{
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_Chord dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_Pie
+ */
+static BOOL pathdrv_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
+                         INT xstart, INT ystart, INT xend, INT yend )
+{
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_Pie dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_PolyBezierTo
+ */
+static BOOL pathdrv_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD cbPoints )
+{
+//    struct path_physdev *physdev = get_path_physdev( dev );
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_PolyBezierTo dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_PolyBezier
+ */
+static BOOL pathdrv_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD cbPoints )
+{
+//    struct path_physdev *physdev = get_path_physdev( dev );
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_PolyBezier dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_PolyDraw
+ */
+static BOOL pathdrv_PolyDraw( PHYSDEV dev, const POINT *pts, const BYTE *types, DWORD cbPoints )
+{
+//    struct path_physdev *physdev = get_path_physdev( dev );
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_PolyDraw dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_Polyline
+ */
+static BOOL pathdrv_Polyline( PHYSDEV dev, const POINT *pts, INT count )
+{
+//    struct path_physdev *physdev = get_path_physdev( dev );
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_PolyLine dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_PolylineTo
+ */
+static BOOL pathdrv_PolylineTo( PHYSDEV dev, const POINT *pts, INT count )
+{
+//    struct path_physdev *physdev = get_path_physdev( dev );
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_PolyLineTo dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_Polygon
+ */
+static BOOL pathdrv_Polygon( PHYSDEV dev, const POINT *pts, INT count )
+{
+//    struct path_physdev *physdev = get_path_physdev( dev );
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_Polygon dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_PolyPolygon
+ */
+static BOOL pathdrv_PolyPolygon( PHYSDEV dev, const POINT* pts, const INT* counts, UINT polygons )
+{
+//    struct path_physdev *physdev = get_path_physdev( dev );
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_PolyPolygon dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_PolyPolyline
+ */
+static BOOL pathdrv_PolyPolyline( PHYSDEV dev, const POINT* pts, const DWORD* counts, DWORD polylines )
+{
+//    struct path_physdev *physdev = get_path_physdev( dev );
+//    DC *dc = get_physdev_dc( dev );
+    DPRINT("pathdrv_PolyPolyline dev %p\n",dev);
+    return TRUE;
+}
+
+
+/*************************************************************
+ *           pathdrv_ExtTextOut
+ */
+static BOOL pathdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *lprc,
+                                LPCWSTR str, UINT count, const INT *dx )
+{
+//    struct path_physdev *physdev = get_path_physdev( dev );
+    DPRINT("pathdrv_ExtTextOut dev %p\n",dev);
+    return TRUE;
+}
+
+/*************************************************************
+ *           pathdrv_CloseFigure
+ */
+static BOOL pathdrv_CloseFigure( PHYSDEV dev )
+{
+//    struct path_physdev *physdev = get_path_physdev( dev );
+    DPRINT("pathdrv_CloseFigure dev %p\n",dev);
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           null driver fallback implementations
+ */
+
+BOOL nulldrv_BeginPath( PHYSDEV dev )
+{
+    DC *dc = get_nulldrv_dc( dev );
+    struct path_physdev *physdev;
+
+    if (!path_driver.pCreateDC( &dc->physDev, NULL, NULL, NULL, NULL ))
+    {
+        return FALSE;
+    }
+    physdev = get_path_physdev( find_dc_driver( dc, &path_driver ));
+    physdev->HasPathHook = TRUE;
+    DPRINT("nulldrv_BeginPath dev %p\n",dev);
+    DPRINT("nulldrv_BeginPath pd %p\n",physdev);
+    return TRUE;
+}
+
+BOOL nulldrv_EndPath( PHYSDEV dev )
+{
+    DPRINT("nulldrv_EndPath dev %p\n",dev);
+    SetLastError( ERROR_CAN_NOT_COMPLETE );
+    return FALSE;
+}
+
+BOOL nulldrv_AbortPath( PHYSDEV dev )
+{
+    //DC *dc = get_nulldrv_dc( dev );
+    DPRINT("nulldrv_AbortPath dev %p\n",dev);
+    //if (dc->path) free_gdi_path( dc->path );
+    //dc->path = NULL;
+    return TRUE;
+}
+
+BOOL nulldrv_CloseFigure( PHYSDEV dev )
+{
+    DPRINT("nulldrv_CloseFigure dev %p\n",dev);
+    SetLastError( ERROR_CAN_NOT_COMPLETE );
+    return FALSE;
+}
+
+BOOL nulldrv_SelectClipPath( PHYSDEV dev, INT mode )
+{
+    BOOL ret = FALSE;
+    HRGN hrgn = PathToRegion( dev->hdc );
+    DPRINT("nulldrv_SelectClipPath dev %p\n",dev);
+    if (hrgn)
+    {
+        ret = ExtSelectClipRgn( dev->hdc, hrgn, mode ) != ERROR;
+        DeleteObject( hrgn );
+    }
+    return ret;
+//    return TRUE;
+}
+
+BOOL nulldrv_FillPath( PHYSDEV dev )
+{
+    DPRINT("nulldrv_FillPath dev %p\n",dev);
+    //if (GetPath( dev->hdc, NULL, NULL, 0 ) == -1) return FALSE;
+    //AbortPath( dev->hdc );
+    return TRUE;
+}
+
+BOOL nulldrv_StrokeAndFillPath( PHYSDEV dev )
+{
+    DPRINT("nulldrv_StrokeAndFillPath dev %p\n",dev);
+    //if (GetPath( dev->hdc, NULL, NULL, 0 ) == -1) return FALSE;
+    //AbortPath( dev->hdc );
+    return TRUE;
+}
+
+BOOL nulldrv_StrokePath( PHYSDEV dev )
+{
+    DPRINT("nulldrv_StrokePath dev %p\n",dev);
+    //if (GetPath( dev->hdc, NULL, NULL, 0 ) == -1) return FALSE;
+    //AbortPath( dev->hdc );
+    return TRUE;
+}
+
+BOOL nulldrv_FlattenPath( PHYSDEV dev )
+{
+/*    DC *dc = get_nulldrv_dc( dev );
+    struct gdi_path *path; */
+    DPRINT("nulldrv_FlattenPath dev %p\n",dev);
+/*    if (!dc->path)
+    {
+        SetLastError( ERROR_CAN_NOT_COMPLETE );
+        return FALSE;
+    }
+    if (!(path = PATH_FlattenPath( dc->path ))) return FALSE;
+    free_gdi_path( dc->path );
+    dc->path = path;*/
+    return TRUE;
+}
+
+BOOL nulldrv_WidenPath( PHYSDEV dev )
+{
+/*    DC *dc = get_nulldrv_dc( dev );
+    struct gdi_path *path;*/
+    DPRINT("nulldrv_WidenPath dev %p\n",dev);
+/*    if (!dc->path)
+    {
+        SetLastError( ERROR_CAN_NOT_COMPLETE );
+        return FALSE;
+    }
+    if (!(path = PATH_WidenPath( dc ))) return FALSE;
+    free_gdi_path( dc->path );
+    dc->path = path;*/
+    return TRUE;
+}
+
+const struct gdi_dc_funcs path_driver =
+{
+    NULL,                               /* pAbortDoc */
+    pathdrv_AbortPath,                  /* pAbortPath */
+    NULL,                               /* pAlphaBlend */
+    pathdrv_AngleArc,                   /* pAngleArc */
+    pathdrv_Arc,                        /* pArc */
+    pathdrv_ArcTo,                      /* pArcTo */
+    pathdrv_BeginPath,                  /* pBeginPath */
+    NULL,                               /* pBlendImage */
+    pathdrv_Chord,                      /* pChord */
+    pathdrv_CloseFigure,                /* pCloseFigure */
+    NULL,                               /* pCreateCompatibleDC */
+    pathdrv_CreateDC,                   /* pCreateDC */
+    pathdrv_DeleteDC,                   /* pDeleteDC */
+    NULL,                               /* pDeleteObject */
+    NULL,                               /* pDeviceCapabilities */
+    pathdrv_Ellipse,                    /* pEllipse */
+    NULL,                               /* pEndDoc */
+    NULL,                               /* pEndPage */
+    pathdrv_EndPath,                    /* pEndPath */
+    NULL,                               /* pEnumFonts */
+    NULL,                               /* pEnumICMProfiles */
+    NULL,                               /* pExcludeClipRect */
+    NULL,                               /* pExtDeviceMode */
+    NULL,                               /* pExtEscape */
+    NULL,                               /* pExtFloodFill */
+    NULL,                               /* pExtSelectClipRgn */
+    pathdrv_ExtTextOut,                 /* pExtTextOut */
+    NULL,                               /* pFillPath */
+    NULL,                               /* pFillRgn */
+    NULL,                               /* pFlattenPath */
+    NULL,                               /* pFontIsLinked */
+    NULL,                               /* pFrameRgn */
+    NULL,                               /* pGdiComment */
+    NULL,                               /* pGetBoundsRect */
+    NULL,                               /* pGetCharABCWidths */
+    NULL,                               /* pGetCharABCWidthsI */
+    NULL,                               /* pGetCharWidth */
+    NULL,                               /* pGetDeviceCaps */
+    NULL,                               /* pGetDeviceGammaRamp */
+    NULL,                               /* pGetFontData */
+    NULL,                               /* pGetFontRealizationInfo */
+    NULL,                               /* pGetFontUnicodeRanges */
+    NULL,                               /* pGetGlyphIndices */
+    NULL,                               /* pGetGlyphOutline */
+    NULL,                               /* pGetICMProfile */
+    NULL,                               /* pGetImage */
+    NULL,                               /* pGetKerningPairs */
+    NULL,                               /* pGetNearestColor */
+    NULL,                               /* pGetOutlineTextMetrics */
+    NULL,                               /* pGetPixel */
+    NULL,                               /* pGetSystemPaletteEntries */
+    NULL,                               /* pGetTextCharsetInfo */
+    NULL,                               /* pGetTextExtentExPoint */
+    NULL,                               /* pGetTextExtentExPointI */
+    NULL,                               /* pGetTextFace */
+    NULL,                               /* pGetTextMetrics */
+    NULL,                               /* pGradientFill */
+    NULL,                               /* pIntersectClipRect */
+    NULL,                               /* pInvertRgn */
+    pathdrv_LineTo,                     /* pLineTo */
+    NULL,                               /* pModifyWorldTransform */
+    pathdrv_MoveTo,                     /* pMoveTo */
+    NULL,                               /* pOffsetClipRgn */
+    NULL,                               /* pOffsetViewportOrg */
+    NULL,                               /* pOffsetWindowOrg */
+    NULL,                               /* pPaintRgn */
+    NULL,                               /* pPatBlt */
+    pathdrv_Pie,                        /* pPie */
+    pathdrv_PolyBezier,                 /* pPolyBezier */
+    pathdrv_PolyBezierTo,               /* pPolyBezierTo */
+    pathdrv_PolyDraw,                   /* pPolyDraw */
+    pathdrv_PolyPolygon,                /* pPolyPolygon */
+    pathdrv_PolyPolyline,               /* pPolyPolyline */
+    pathdrv_Polygon,                    /* pPolygon */
+    pathdrv_Polyline,                   /* pPolyline */
+    pathdrv_PolylineTo,                 /* pPolylineTo */
+    NULL,                               /* pPutImage */
+    NULL,                               /* pRealizeDefaultPalette */
+    NULL,                               /* pRealizePalette */
+    pathdrv_Rectangle,                  /* pRectangle */
+    NULL,                               /* pResetDC */
+    NULL,                               /* pRestoreDC */
+    pathdrv_RoundRect,                  /* pRoundRect */
+    NULL,                               /* pSaveDC */
+    NULL,                               /* pScaleViewportExt */
+    NULL,                               /* pScaleWindowExt */
+    NULL,                               /* pSelectBitmap */
+    NULL,                               /* pSelectBrush */
+    NULL,                               /* pSelectClipPath */
+    NULL,                               /* pSelectFont */
+    NULL,                               /* pSelectPalette */
+    NULL,                               /* pSelectPen */
+    NULL,                               /* pSetArcDirection */
+    NULL,                               /* pSetBkColor */
+    NULL,                               /* pSetBkMode */
+    NULL,                               /* pSetDCBrushColor */
+    NULL,                               /* pSetDCPenColor */
+    NULL,                               /* pSetDIBColorTable */
+    NULL,                               /* pSetDIBitsToDevice */
+    NULL,                               /* pSetDeviceClipping */
+    NULL,                               /* pSetDeviceGammaRamp */
+    NULL,                               /* pSetLayout */
+    NULL,                               /* pSetMapMode */
+    NULL,                               /* pSetMapperFlags */
+    NULL,                               /* pSetPixel */
+    NULL,                               /* pSetPolyFillMode */
+    NULL,                               /* pSetROP2 */
+    NULL,                               /* pSetRelAbs */
+    NULL,                               /* pSetStretchBltMode */
+    NULL,                               /* pSetTextAlign */
+    NULL,                               /* pSetTextCharacterExtra */
+    NULL,                               /* pSetTextColor */
+    NULL,                               /* pSetTextJustification */
+    NULL,                               /* pSetViewportExt */
+    NULL,                               /* pSetViewportOrg */
+    NULL,                               /* pSetWindowExt */
+    NULL,                               /* pSetWindowOrg */
+    NULL,                               /* pSetWorldTransform */
+    NULL,                               /* pStartDoc */
+    NULL,                               /* pStartPage */
+    NULL,                               /* pStretchBlt */
+    NULL,                               /* pStretchDIBits */
+    NULL,                               /* pStrokeAndFillPath */
+    NULL,                               /* pStrokePath */
+    NULL,                               /* pUnrealizePalette */
+    NULL,                               /* pWidenPath */
+    NULL,                               /* wine_get_wgl_driver */
+    GDI_PRIORITY_PATH_DRV               /* priority */
+};
index bc8278e..fbf26fe 100644 (file)
@@ -6,11 +6,26 @@
 #define NDEBUG
 #include <debug.h>
 
+WINEDC *get_nulldrv_dc( PHYSDEV dev );
+
+BOOL nulldrv_BeginPath( PHYSDEV dev );
+BOOL nulldrv_EndPath( PHYSDEV dev );
+BOOL nulldrv_AbortPath( PHYSDEV dev );
+BOOL nulldrv_CloseFigure( PHYSDEV dev );
+BOOL nulldrv_SelectClipPath( PHYSDEV dev, INT mode );
+BOOL nulldrv_FillPath( PHYSDEV dev );
+BOOL nulldrv_StrokeAndFillPath( PHYSDEV dev );
+BOOL nulldrv_StrokePath( PHYSDEV dev );
+BOOL nulldrv_FlattenPath( PHYSDEV dev );
+BOOL nulldrv_WidenPath( PHYSDEV dev );
+
+static INT i = 0;
+
 static
 INT_PTR
 NULL_Unused()
 {
-    DPRINT1("NULL_Unused\n");
+    DPRINT1("NULL_Unused %d\n",i);
     // __debugbreak();
     return 0;
 }
@@ -31,15 +46,16 @@ static INT   NULL_ExcludeClipRect(PHYSDEV dev, INT left, INT top, INT right, INT
 static const struct gdi_dc_funcs DummyPhysDevFuncs =
 {
     (PVOID)NULL_Unused, //INT      (*pAbortDoc)(PHYSDEV);
-    (PVOID)NULL_Unused, //BOOL     (*pAbortPath)(PHYSDEV);
+    nulldrv_AbortPath,  //BOOL     (*pAbortPath)(PHYSDEV);
     (PVOID)NULL_Unused, //BOOL     (*pAlphaBlend)(PHYSDEV,struct bitblt_coords*,PHYSDEV,struct bitblt_coords*,BLENDFUNCTION);
     (PVOID)NULL_Unused, //BOOL     (*pAngleArc)(PHYSDEV,INT,INT,DWORD,FLOAT,FLOAT);
     (PVOID)NULL_Unused, //BOOL     (*pArc)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
     (PVOID)NULL_Unused, //BOOL     (*pArcTo)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
-    (PVOID)NULL_Unused, //BOOL     (*pBeginPath)(PHYSDEV);
+    nulldrv_BeginPath,  //BOOL     (*pBeginPath)(PHYSDEV);
     (PVOID)NULL_Unused, //DWORD    (*pBlendImage)(PHYSDEV,BITMAPINFO*,const struct gdi_image_bits*,struct bitblt_coords*,struct bitblt_coords*,BLENDFUNCTION);
     (PVOID)NULL_Unused, //BOOL     (*pChord)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
-    (PVOID)NULL_Unused, //BOOL     (*pCloseFigure)(PHYSDEV);
+    nulldrv_CloseFigure, //BOOL     (*pCloseFigure)(PHYSDEV);
+
     (PVOID)NULL_Unused, //BOOL     (*pCreateCompatibleDC)(PHYSDEV,PHYSDEV*);
     (PVOID)NULL_Unused, //BOOL     (*pCreateDC)(PHYSDEV*,LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODEW*);
     (PVOID)NULL_Unused, //BOOL     (*pDeleteDC)(PHYSDEV);
@@ -48,8 +64,9 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
     (PVOID)NULL_Unused, //BOOL     (*pEllipse)(PHYSDEV,INT,INT,INT,INT);
     (PVOID)NULL_Unused, //INT      (*pEndDoc)(PHYSDEV);
     (PVOID)NULL_Unused, //INT      (*pEndPage)(PHYSDEV);
-    (PVOID)NULL_Unused, //BOOL     (*pEndPath)(PHYSDEV);
+    nulldrv_EndPath,    //BOOL     (*pEndPath)(PHYSDEV);
     (PVOID)NULL_Unused, //BOOL     (*pEnumFonts)(PHYSDEV,LPLOGFONTW,FONTENUMPROCW,LPARAM);
+
     (PVOID)NULL_Unused, //INT      (*pEnumICMProfiles)(PHYSDEV,ICMENUMPROCW,LPARAM);
     NULL_ExcludeClipRect, //INT      (*pExcludeClipRect)(PHYSDEV,INT,INT,INT,INT);
     (PVOID)NULL_Unused, //INT      (*pExtDeviceMode)(LPSTR,HWND,LPDEVMODEA,LPSTR,LPSTR,LPDEVMODEA,LPSTR,DWORD);
@@ -57,13 +74,13 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
     (PVOID)NULL_Unused, //BOOL     (*pExtFloodFill)(PHYSDEV,INT,INT,COLORREF,UINT);
     NULL_ExtSelectClipRgn, //INT      (*pExtSelectClipRgn)(PHYSDEV,HRGN,INT);
     (PVOID)NULL_Unused, //BOOL     (*pExtTextOut)(PHYSDEV,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
-    (PVOID)NULL_Unused, //BOOL     (*pFillPath)(PHYSDEV);
+    nulldrv_FillPath,   //BOOL     (*pFillPath)(PHYSDEV);
     (PVOID)NULL_Unused, //BOOL     (*pFillRgn)(PHYSDEV,HRGN,HBRUSH);
-    (PVOID)NULL_Unused, //BOOL     (*pFlattenPath)(PHYSDEV);
+    nulldrv_FlattenPath, //BOOL     (*pFlattenPath)(PHYSDEV);
+
     (PVOID)NULL_Unused, //BOOL     (*pFontIsLinked)(PHYSDEV);
     (PVOID)NULL_Unused, //BOOL     (*pFrameRgn)(PHYSDEV,HRGN,HBRUSH,INT,INT);
     (PVOID)NULL_Unused, //BOOL     (*pGdiComment)(PHYSDEV,UINT,const BYTE*);
-    (PVOID)NULL_Unused, //BOOL     (*pGdiRealizationInfo)(PHYSDEV,void*);
     (PVOID)NULL_Unused, //UINT     (*pGetBoundsRect)(PHYSDEV,RECT*,UINT);
     (PVOID)NULL_Unused, //BOOL     (*pGetCharABCWidths)(PHYSDEV,UINT,UINT,LPABC);
     (PVOID)NULL_Unused, //BOOL     (*pGetCharABCWidthsI)(PHYSDEV,UINT,UINT,WORD*,LPABC);
@@ -71,6 +88,7 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
     (PVOID)NULL_Unused, //INT      (*pGetDeviceCaps)(PHYSDEV,INT);
     (PVOID)NULL_Unused, //BOOL     (*pGetDeviceGammaRamp)(PHYSDEV,LPVOID);
     (PVOID)NULL_Unused, //DWORD    (*pGetFontData)(PHYSDEV,DWORD,DWORD,LPVOID,DWORD);
+    (PVOID)NULL_Unused, //BOOL     (*pGetFontRealizationInfo)(PHYSDEV,void*);
     (PVOID)NULL_Unused, //DWORD    (*pGetFontUnicodeRanges)(PHYSDEV,LPGLYPHSET);
     (PVOID)NULL_Unused, //DWORD    (*pGetGlyphIndices)(PHYSDEV,LPCWSTR,INT,LPWORD,DWORD);
     (PVOID)NULL_Unused, //DWORD    (*pGetGlyphOutline)(PHYSDEV,UINT,UINT,LPGLYPHMETRICS,DWORD,LPVOID,const MAT2*);
@@ -111,15 +129,15 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
     (PVOID)NULL_Unused, //UINT     (*pRealizePalette)(PHYSDEV,HPALETTE,BOOL);
     (PVOID)NULL_Unused, //BOOL     (*pRectangle)(PHYSDEV,INT,INT,INT,INT);
     (PVOID)NULL_Unused, //HDC      (*pResetDC)(PHYSDEV,const DEVMODEW*);
-    NULL_RestoreDC, //BOOL     (*pRestoreDC)(PHYSDEV,INT);
+    NULL_RestoreDC,     //BOOL     (*pRestoreDC)(PHYSDEV,INT);
     (PVOID)NULL_Unused, //BOOL     (*pRoundRect)(PHYSDEV,INT,INT,INT,INT,INT,INT);
-    NULL_SaveDC, //INT      (*pSaveDC)(PHYSDEV);
+    NULL_SaveDC,        //INT      (*pSaveDC)(PHYSDEV);
     (PVOID)NULL_Unused, //BOOL     (*pScaleViewportExtEx)(PHYSDEV,INT,INT,INT,INT,SIZE*);
     (PVOID)NULL_Unused, //BOOL     (*pScaleWindowExtEx)(PHYSDEV,INT,INT,INT,INT,SIZE*);
     (PVOID)NULL_Unused, //HBITMAP  (*pSelectBitmap)(PHYSDEV,HBITMAP);
     (PVOID)NULL_Unused, //HBRUSH   (*pSelectBrush)(PHYSDEV,HBRUSH,const struct brush_pattern*);
-    (PVOID)NULL_Unused, //BOOL     (*pSelectClipPath)(PHYSDEV,INT);
-    NULL_SelectFont, //HFONT    (*pSelectFont)(PHYSDEV,HFONT,UINT*);
+    nulldrv_SelectClipPath, //BOOL     (*pSelectClipPath)(PHYSDEV,INT);
+    NULL_SelectFont,    //HFONT    (*pSelectFont)(PHYSDEV,HFONT,UINT*);
     (PVOID)NULL_Unused, //HPALETTE (*pSelectPalette)(PHYSDEV,HPALETTE,BOOL);
     (PVOID)NULL_Unused, //HPEN     (*pSelectPen)(PHYSDEV,HPEN,const struct brush_pattern*);
     (PVOID)NULL_Unused, //INT      (*pSetArcDirection)(PHYSDEV,INT);
@@ -132,7 +150,7 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
     (PVOID)NULL_Unused, //VOID     (*pSetDeviceClipping)(PHYSDEV,HRGN);
     (PVOID)NULL_Unused, //BOOL     (*pSetDeviceGammaRamp)(PHYSDEV,LPVOID);
     (PVOID)NULL_Unused, //DWORD    (*pSetLayout)(PHYSDEV,DWORD);
-    NULL_SetMapMode, //INT      (*pSetMapMode)(PHYSDEV,INT);
+    NULL_SetMapMode,    //INT      (*pSetMapMode)(PHYSDEV,INT);
     (PVOID)NULL_Unused, //DWORD    (*pSetMapperFlags)(PHYSDEV,DWORD);
     (PVOID)NULL_Unused, //COLORREF (*pSetPixel)(PHYSDEV,INT,INT,COLORREF);
     (PVOID)NULL_Unused, //INT      (*pSetPolyFillMode)(PHYSDEV,INT);
@@ -152,14 +170,26 @@ static const struct gdi_dc_funcs DummyPhysDevFuncs =
     (PVOID)NULL_Unused, //INT      (*pStartPage)(PHYSDEV);
     (PVOID)NULL_Unused, //BOOL     (*pStretchBlt)(PHYSDEV,struct bitblt_coords*,PHYSDEV,struct bitblt_coords*,DWORD);
     (PVOID)NULL_Unused, //INT      (*pStretchDIBits)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT,const void*,BITMAPINFO*,UINT,DWORD);
-    (PVOID)NULL_Unused, //BOOL     (*pStrokeAndFillPath)(PHYSDEV);
-    (PVOID)NULL_Unused, //BOOL     (*pStrokePath)(PHYSDEV);
+    nulldrv_StrokeAndFillPath, //BOOL     (*pStrokeAndFillPath)(PHYSDEV);
+    nulldrv_StrokePath, //BOOL     (*pStrokePath)(PHYSDEV);
     (PVOID)NULL_Unused, //BOOL     (*pUnrealizePalette)(HPALETTE);
-    (PVOID)NULL_Unused, //BOOL     (*pWidenPath)(PHYSDEV);
+    nulldrv_WidenPath,  //BOOL     (*pWidenPath)(PHYSDEV);
     (PVOID)NULL_Unused, //struct opengl_funcs * (*wine_get_wgl_driver)(PHYSDEV,UINT);
     0 // UINT       priority;
 };
 
+WINEDC *get_nulldrv_dc( PHYSDEV dev )
+{
+    return CONTAINING_RECORD( dev, WINEDC, NullPhysDev );
+}
+
+WINEDC* get_physdev_dc( PHYSDEV dev )
+{
+    while (dev->funcs != &DummyPhysDevFuncs)
+        dev = dev->next;
+    return get_nulldrv_dc( dev );
+}
+
 static
 GDILOOBJTYPE
 ConvertObjectType(
@@ -368,6 +398,7 @@ push_dc_driver_ros(
     PHYSDEV physdev,
     const struct gdi_dc_funcs *funcs)
 {
+    while ((*dev)->funcs->priority > funcs->priority) dev = &(*dev)->next;
     physdev->funcs = funcs;
     physdev->next = *dev;
     physdev->hdc = CONTAINING_RECORD(dev, WINEDC, physDev)->hdc;
@@ -691,6 +722,15 @@ DRIVER_SelectBrush(PHYSDEV physdev, HBRUSH hbrush, const struct brush_pattern *p
     return hOldBrush;
 }
 
+static
+HRGN
+DRIVER_PathToRegion(PHYSDEV physdev)
+{
+    DPRINT1("DRIVER_PathToRegion\n");
+    return (HRGN)physdev->funcs->pAbortPath( physdev );
+}
+
+
 static
 DWORD_PTR
 DRIVER_Dispatch(
@@ -858,10 +898,8 @@ DRIVER_Dispatch(
                                                  _va_arg_n(argptr, const POINT*, 0),
                                                  _va_arg_n(argptr, DWORD, 1));
         case DCFUNC_PolyDraw:
-            DPRINT1("DCFUNC_PolyDraw not implemented\n");
-            return FALSE;
-            return physdev->funcs->pPolyDraw(physdev,
-                                             _va_arg_n(argptr, const POINT*, 1),
+           return physdev->funcs->pPolyDraw(physdev,
+                                             _va_arg_n(argptr, const POINT*, 0),
                                              _va_arg_n(argptr, const BYTE*, 1),
                                              _va_arg_n(argptr, DWORD, 2));
         case DCFUNC_Polygon:
@@ -873,8 +911,6 @@ DRIVER_Dispatch(
                                              _va_arg_n(argptr, const POINT*, 0),
                                              _va_arg_n(argptr, INT, 1));
         case DCFUNC_PolylineTo:
-            DPRINT1("DCFUNC_PolylineTo not implemented\n");
-            return FALSE;
             return physdev->funcs->pPolylineTo(physdev,
                                                _va_arg_n(argptr, const POINT*, 0),
                                                _va_arg_n(argptr, INT, 1));
@@ -1027,15 +1063,36 @@ DRIVER_Dispatch(
             return physdev->funcs->pStrokePath(physdev);
         case DCFUNC_WidenPath:
             return physdev->funcs->pWidenPath(physdev);
-
-
-        /* These are not implemented in wine */
-        case DCFUNC_AlphaBlend:
         case DCFUNC_AngleArc:
+            return physdev->funcs->pAngleArc(physdev,
+                                             _va_arg_n(argptr, INT, 0),
+                                             _va_arg_n(argptr, INT, 1),
+                                             _va_arg_n(argptr, DWORD, 2),
+                                             _va_arg_n(argptr, FLOAT, 3),
+                                             _va_arg_n(argptr, FLOAT, 4 ));
         case DCFUNC_ArcTo:
+            return physdev->funcs->pArcTo(physdev,
+                                          _va_arg_n(argptr, INT, 0),
+                                          _va_arg_n(argptr, INT, 1),
+                                          _va_arg_n(argptr, INT, 2),
+                                          _va_arg_n(argptr, INT, 3),
+                                          _va_arg_n(argptr, INT, 4),
+                                          _va_arg_n(argptr, INT, 5),
+                                          _va_arg_n(argptr, INT, 6),
+                                          _va_arg_n(argptr, INT, 7));
         case DCFUNC_GradientFill:
-        case DCFUNC_MaskBlt:
+            return physdev->funcs->pGradientFill(physdev,
+                                                 _va_arg_n(argptr, TRIVERTEX *, 0), 
+                                                 _va_arg_n(argptr, ULONG, 1),
+                                                 _va_arg_n(argptr, void *, 2),
+                                                 _va_arg_n(argptr, ULONG , 3),
+                                                 _va_arg_n(argptr, ULONG , 4));
         case DCFUNC_PathToRegion:
+            return (DWORD_PTR)DRIVER_PathToRegion(physdev);
+
+        /* These are not implemented in wine */
+        case DCFUNC_AlphaBlend:
+        case DCFUNC_MaskBlt:
         case DCFUNC_PlgBlt:
         case DCFUNC_TransparentBlt:
             UNIMPLEMENTED;
@@ -1074,9 +1131,11 @@ METADC_Dispatch(
         return TRUE;
     }
 
+    i = eFunction;
     va_start(argptr, hdc);
     *pdwResult = DRIVER_Dispatch(physdev, eFunction, argptr);
     va_end(argptr);
+    i = 0;
 
     /* Return TRUE to indicate that we want to return from the parent  */
     return ((GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) ||