[CMAKE]
[reactos.git] / subsystems / win32 / win32k / objects / path.c
index 7c9ac01..82ccf43 100644 (file)
@@ -1,24 +1,40 @@
 /*
- *  ReactOS W32 Subsystem
- *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
+ * Graphics paths (BeginPath, EndPath etc.)
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
+ * Copyright 1997, 1998 Martin Boehme
+ *                 1999 Huw D M Davies
+ * Copyright 2005 Dmitry Timoshkov
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+/*
+ *
+ * Addaped for the use in ReactOS.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * PROJECT:         ReactOS win32 kernel mode subsystem
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            subsystems/win32/win32k/objects/path.c
+ * PURPOSE:         Path support
+ * PROGRAMMER:
  */
 
-#include <w32k.h>
-#include "math.h"
+#include <win32k.h>
+#define _USE_MATH_DEFINES
+#include <math.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -49,12 +65,12 @@ BOOL
 FASTCALL
 PATH_Delete(HPATH hPath)
 {
+  PPATH pPath;
   if (!hPath) return FALSE;
-  PPATH pPath = PATH_LockPath( hPath );
+  pPath = PATH_LockPath( hPath );
   if (!pPath) return FALSE;
   PATH_DestroyGdiPath( pPath );
-  PATH_UnlockPath( pPath );
-  PATH_FreeExtPathByHandle(hPath);
+  GDIOBJ_vDeleteObject(&pPath->BaseObject);
   return TRUE;
 }
 
@@ -82,22 +98,20 @@ BOOL
 FASTCALL
 PATH_FillPath( PDC dc, PPATH pPath )
 {
-  INT   mapMode, graphicsMode;
-  SIZE  ptViewportExt, ptWindowExt;
-  POINTL ptViewportOrg, ptWindowOrg;
+  //INT   mapMode, graphicsMode;
+  //SIZE  ptViewportExt, ptWindowExt;
+  //POINTL ptViewportOrg, ptWindowOrg;
   XFORM xform;
   HRGN  hrgn;
-  PDC_ATTR Dc_Attr = dc->pDc_Attr;
-
-  if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
+  PDC_ATTR pdcattr = dc->pdcattr;
 
   if( pPath->state != PATH_Closed )
   {
-    SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+    EngSetLastError(ERROR_CAN_NOT_COMPLETE);
     return FALSE;
   }
 
-  if( PATH_PathToRegion( pPath, Dc_Attr->jFillMode, &hrgn ))
+  if( PATH_PathToRegion( pPath, pdcattr->jFillMode, &hrgn ))
   {
     /* Since PaintRgn interprets the region as being in logical coordinates
      * but the points we store for the path are already in device
@@ -108,11 +122,11 @@ PATH_FillPath( PDC dc, PPATH pPath )
      */
 
     /* Save the information about the old mapping mode */
-    mapMode = Dc_Attr->iMapMode;
-    ptViewportExt = Dc_Attr->szlViewportExt;
-    ptViewportOrg = Dc_Attr->ptlViewportOrg;
-    ptWindowExt   = Dc_Attr->szlWindowExt;
-    ptWindowOrg   = Dc_Attr->ptlWindowOrg;
+    //mapMode = pdcattr->iMapMode;
+    //ptViewportExt = pdcattr->szlViewportExt;
+    //ptViewportOrg = pdcattr->ptlViewportOrg;
+    //ptWindowExt   = pdcattr->szlWindowExt;
+    //ptWindowOrg   = pdcattr->ptlWindowOrg;
 
     /* Save world transform
      * NB: The Windows documentation on world transforms would lead one to
@@ -120,35 +134,35 @@ PATH_FillPath( PDC dc, PPATH pPath )
      * tests show that resetting the graphics mode to GM_COMPATIBLE does
      * not reset the world transform.
      */
-    MatrixS2XForm(&xform, &dc->DcLevel.mxWorldToPage);
+    MatrixS2XForm(&xform, &dc->dclevel.mxWorldToPage);
 
     /* Set MM_TEXT */
 //    IntGdiSetMapMode( dc, MM_TEXT );
-//    Dc_Attr->ptlViewportOrg.x = 0;
-//    Dc_Attr->ptlViewportOrg.y = 0;
-//    Dc_Attr->ptlWindowOrg.x = 0;
-//    Dc_Attr->ptlWindowOrg.y = 0;
+//    pdcattr->ptlViewportOrg.x = 0;
+//    pdcattr->ptlViewportOrg.y = 0;
+//    pdcattr->ptlWindowOrg.x = 0;
+//    pdcattr->ptlWindowOrg.y = 0;
 
-    graphicsMode = Dc_Attr->iGraphicsMode;
-//    Dc_Attr->iGraphicsMode = GM_ADVANCED;
+   // graphicsMode = pdcattr->iGraphicsMode;
+//    pdcattr->iGraphicsMode = GM_ADVANCED;
 //    IntGdiModifyWorldTransform( dc, &xform, MWT_IDENTITY );
-//    Dc_Attr->iGraphicsMode =  graphicsMode;
+//    pdcattr->iGraphicsMode =  graphicsMode;
 
     /* Paint the region */
     IntGdiPaintRgn( dc, hrgn );
-    NtGdiDeleteObject( hrgn );
+    GreDeleteObject( hrgn );
     /* Restore the old mapping mode */
 //    IntGdiSetMapMode( dc, mapMode );
-//    Dc_Attr->szlViewportExt = ptViewportExt;
-//   Dc_Attr->ptlViewportOrg = ptViewportOrg;
-//    Dc_Attr->szlWindowExt   = ptWindowExt;
-//    Dc_Attr->ptlWindowOrg   = ptWindowOrg;
+//    pdcattr->szlViewportExt = ptViewportExt;
+//    pdcattr->ptlViewportOrg = ptViewportOrg;
+//    pdcattr->szlWindowExt   = ptWindowExt;
+//    pdcattr->ptlWindowOrg   = ptWindowOrg;
 
     /* Go to GM_ADVANCED temporarily to restore the world transform */
-    graphicsMode = Dc_Attr->iGraphicsMode;
-//    Dc_Attr->iGraphicsMode = GM_ADVANCED;
+    //graphicsMode = pdcattr->iGraphicsMode;
+//    pdcattr->iGraphicsMode = GM_ADVANCED;
 //    IntGdiModifyWorldTransform( dc, &xform, MWT_MAX+1 );
-//    Dc_Attr->iGraphicsMode = graphicsMode;
+//    pdcattr->iGraphicsMode = graphicsMode;
     return TRUE;
   }
   return FALSE;
@@ -181,8 +195,8 @@ PATH_DestroyGdiPath ( PPATH pPath )
 {
   ASSERT(pPath!=NULL);
 
-  if (pPath->pPoints) ExFreePool(pPath->pPoints);
-  if (pPath->pFlags) ExFreePool(pPath->pFlags);
+  if (pPath->pPoints) ExFreePoolWithTag(pPath->pPoints, TAG_PATH);
+  if (pPath->pFlags) ExFreePoolWithTag(pPath->pFlags, TAG_PATH);
 }
 
 /* PATH_AssignGdiPath
@@ -227,7 +241,7 @@ BOOL
 FASTCALL
 PATH_MoveTo ( PDC dc )
 {
-  PPATH pPath = PATH_LockPath( dc->DcLevel.hPath );
+  PPATH pPath = PATH_LockPath( dc->dclevel.hPath );
   if (!pPath) return FALSE;
 
   /* Check that path is open */
@@ -258,7 +272,7 @@ PATH_LineTo ( PDC dc, INT x, INT y )
   PPATH pPath;
   POINT point, pointCurPos;
 
-  pPath = PATH_LockPath( dc->DcLevel.hPath );
+  pPath = PATH_LockPath( dc->dclevel.hPath );
   if (!pPath) return FALSE;
 
   /* Check that path is open */
@@ -305,7 +319,7 @@ PATH_Rectangle ( PDC dc, INT x1, INT y1, INT x2, INT y2 )
   POINT corners[2], pointTemp;
   INT   temp;
 
-  pPath = PATH_LockPath( dc->DcLevel.hPath );
+  pPath = PATH_LockPath( dc->dclevel.hPath );
   if (!pPath) return FALSE;
 
   /* Check that path is open */
@@ -337,7 +351,7 @@ PATH_Rectangle ( PDC dc, INT x1, INT y1, INT x2, INT y2 )
   }
 
   /* In GM_COMPATIBLE, don't include bottom and right edges */
-  if ( IntGetGraphicsMode(dc) == GM_COMPATIBLE )
+  if (dc->pdcattr->iGraphicsMode == GM_COMPATIBLE)
   {
     corners[1].x--;
     corners[1].y--;
@@ -393,8 +407,8 @@ BOOL FASTCALL PATH_RoundRect(DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_wid
    POINT corners[2], pointTemp;
    FLOAT_POINT ellCorners[2];
 
-   pPath = PATH_LockPath( dc->DcLevel.hPath );
-   if (!pPath) return FALSE;   
+   pPath = PATH_LockPath( dc->dclevel.hPath );
+   if (!pPath) return FALSE;
 
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
@@ -483,7 +497,7 @@ PATH_Ellipse ( PDC dc, INT x1, INT y1, INT x2, INT y2 )
   BOOL Ret = PATH_Arc ( dc, x1, y1, x2, y2, x1, (y1+y2)/2, x1, (y1+y2)/2, GdiTypeArc );
   if (Ret)
   {
-     pPath = PATH_LockPath( dc->DcLevel.hPath );
+     pPath = PATH_LockPath( dc->dclevel.hPath );
      if (!pPath) return FALSE;
      IntGdiCloseFigure(pPath);
      PATH_UnlockPath( pPath );
@@ -521,16 +535,16 @@ PATH_Arc ( PDC dc, INT x1, INT y1, INT x2, INT y2,
 
   ASSERT ( dc );
 
-  pPath = PATH_LockPath( dc->DcLevel.hPath );
+  pPath = PATH_LockPath( dc->dclevel.hPath );
   if (!pPath) return FALSE;
 
-  clockwise = ((dc->DcLevel.flPath & DCPATH_CLOCKWISE) != 0);
+  clockwise = ((dc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
 
   /* Check that path is open */
   if ( pPath->state != PATH_Open )
   {
     Ret = FALSE;
-    goto ArcExit;    
+    goto ArcExit;
   }
 
   /* Check for zero height / width */
@@ -593,7 +607,7 @@ PATH_Arc ( PDC dc, INT x1, INT y1, INT x2, INT y2,
   }
 
   /* In GM_COMPATIBLE, don't include bottom and right edges */
-  if ( IntGetGraphicsMode(dc) == GM_COMPATIBLE )
+  if (dc->pdcattr->iGraphicsMode == GM_COMPATIBLE )
   {
     corners[1].x--;
     corners[1].y--;
@@ -681,9 +695,9 @@ PATH_PolyBezierTo ( PDC dc, const POINT *pts, DWORD cbPoints )
   ASSERT ( pts );
   ASSERT ( cbPoints );
 
-   pPath = PATH_LockPath( dc->DcLevel.hPath );
+   pPath = PATH_LockPath( dc->dclevel.hPath );
    if (!pPath) return FALSE;
-   
+
   /* Check that path is open */
   if ( pPath->state != PATH_Open )
   {
@@ -726,7 +740,7 @@ PATH_PolyBezier ( PDC dc, const POINT *pts, DWORD cbPoints )
   ASSERT ( pts );
   ASSERT ( cbPoints );
 
-  pPath = PATH_LockPath( dc->DcLevel.hPath );
+  pPath = PATH_LockPath( dc->dclevel.hPath );
   if (!pPath) return FALSE;
 
    /* Check that path is open */
@@ -758,7 +772,7 @@ PATH_Polyline ( PDC dc, const POINT *pts, DWORD cbPoints )
   ASSERT ( pts );
   ASSERT ( cbPoints );
 
-  pPath = PATH_LockPath( dc->DcLevel.hPath );
+  pPath = PATH_LockPath( dc->dclevel.hPath );
   if (!pPath) return FALSE;
 
   /* Check that path is open */
@@ -789,9 +803,9 @@ PATH_PolylineTo ( PDC dc, const POINT *pts, DWORD cbPoints )
   ASSERT ( pts );
   ASSERT ( cbPoints );
 
-  pPath = PATH_LockPath( dc->DcLevel.hPath );
+  pPath = PATH_LockPath( dc->dclevel.hPath );
   if (!pPath) return FALSE;
-   
+
   /* Check that path is open */
   if ( pPath->state != PATH_Open )
   {
@@ -834,7 +848,7 @@ PATH_Polygon ( PDC dc, const POINT *pts, DWORD cbPoints )
   ASSERT ( dc );
   ASSERT ( pts );
 
-  pPath = PATH_LockPath( dc->DcLevel.hPath );
+  pPath = PATH_LockPath( dc->dclevel.hPath );
   if (!pPath) return FALSE;
 
   /* Check that path is open */
@@ -869,7 +883,7 @@ PATH_PolyPolygon ( PDC dc, const POINT* pts, const INT* counts, UINT polygons )
   ASSERT ( counts );
   ASSERT ( polygons );
 
-  pPath = PATH_LockPath( dc->DcLevel.hPath );
+  pPath = PATH_LockPath( dc->dclevel.hPath );
   if (!pPath) return FALSE;
 
   /* Check that path is open */
@@ -908,7 +922,7 @@ PATH_PolyPolyline ( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylin
   ASSERT ( counts );
   ASSERT ( polylines );
 
-  pPath = PATH_LockPath( dc->DcLevel.hPath );
+  pPath = PATH_LockPath( dc->dclevel.hPath );
   if (!pPath) return FALSE;
 
   /* Check that path is open */
@@ -939,8 +953,7 @@ PATH_PolyPolyline ( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylin
 BOOL PATH_CheckCorners(DC *dc, POINT corners[], INT x1, INT y1, INT x2, INT y2)
 {
    INT temp;
-   PDC_ATTR Dc_Attr = dc->pDc_Attr;
-   if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
+   PDC_ATTR pdcattr = dc->pdcattr;
 
    /* Convert points to device coordinates */
    corners[0].x=x1;
@@ -965,7 +978,7 @@ BOOL PATH_CheckCorners(DC *dc, POINT corners[], INT x1, INT y1, INT x2, INT y2)
    }
 
    /* In GM_COMPATIBLE, don't include bottom and right edges */
-   if(Dc_Attr->iGraphicsMode==GM_COMPATIBLE)
+   if(pdcattr->iGraphicsMode==GM_COMPATIBLE)
    {
       corners[1].x--;
       corners[1].y--;
@@ -991,7 +1004,7 @@ PATH_AddFlatBezier ( PPATH pPath, POINT *pt, BOOL closed )
   for(i = 1; i < no; i++)
     PATH_AddEntry(pPath, &pts[i],  (i == no-1 && closed) ? PT_LINETO | PT_CLOSEFIGURE : PT_LINETO);
 
-  ExFreePool(pts);
+  ExFreePoolWithTag(pts, TAG_BEZIER);
   return TRUE;
 }
 
@@ -1049,8 +1062,6 @@ PATH_PathToRegion ( PPATH pPath, INT nPolyFillMode, HRGN *pHrgn )
 
   PATH_FlattenPath ( pPath );
 
-  /* FIXME: What happens when number of points is zero? */
-
   /* First pass: Find out how many strokes there are in the path */
   /* FIXME: We could eliminate this with some bookkeeping in GdiPath */
   numStrokes=0;
@@ -1058,11 +1069,16 @@ PATH_PathToRegion ( PPATH pPath, INT nPolyFillMode, HRGN *pHrgn )
     if((pPath->pFlags[i] & ~PT_CLOSEFIGURE) == PT_MOVETO)
       numStrokes++;
 
+  if(numStrokes == 0)
+  {
+      return FALSE;
+  }
+
   /* Allocate memory for number-of-points-in-stroke array */
   pNumPointsInStroke = ExAllocatePoolWithTag(PagedPool, sizeof(ULONG) * numStrokes, TAG_PATH);
   if(!pNumPointsInStroke)
   {
-    SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+    EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
     return FALSE;
   }
 
@@ -1087,12 +1103,12 @@ PATH_PathToRegion ( PPATH pPath, INT nPolyFillMode, HRGN *pHrgn )
                                    nPolyFillMode);
   if(hrgn==(HRGN)0)
   {
-    SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+    EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
     return FALSE;
   }
 
   /* Free memory for number-of-points-in-stroke array */
-  ExFreePool(pNumPointsInStroke);
+  ExFreePoolWithTag(pNumPointsInStroke, TAG_PATH);
 
   /* Success! */
   *pHrgn=hrgn;
@@ -1189,7 +1205,7 @@ PATH_ReserveEntries ( PPATH pPath, INT numEntries )
     pFlagsNew=(BYTE *)ExAllocatePoolWithTag(PagedPool, numEntriesToAllocate * sizeof(BYTE), TAG_PATH);
     if(!pFlagsNew)
     {
-      ExFreePool(pPointsNew);
+      ExFreePoolWithTag(pPointsNew, TAG_PATH);
       return FALSE;
     }
 
@@ -1201,8 +1217,8 @@ PATH_ReserveEntries ( PPATH pPath, INT numEntries )
       memcpy(pPointsNew, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed);
       memcpy(pFlagsNew, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed);
 
-      ExFreePool(pPath->pPoints);
-      ExFreePool(pPath->pFlags);
+      ExFreePoolWithTag(pPath->pPoints, TAG_PATH);
+      ExFreePoolWithTag(pPath->pFlags, TAG_PATH);
     }
     pPath->pPoints=pPointsNew;
     pPath->pFlags=pFlagsNew;
@@ -1322,33 +1338,34 @@ BOOL FASTCALL PATH_StrokePath(DC *dc, PPATH pPath)
     SIZE szViewportExt, szWindowExt;
     DWORD mapMode, graphicsMode;
     XFORM xform;
-    PDC_ATTR Dc_Attr = dc->pDc_Attr;
+    PDC_ATTR pdcattr = dc->pdcattr;
 
     DPRINT("Enter %s\n", __FUNCTION__);
 
     if (pPath->state != PATH_Closed)
         return FALSE;
 
-    if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
     /* Save the mapping mode info */
-    mapMode = Dc_Attr->iMapMode;
-    IntGetViewportExtEx(dc, &szViewportExt);
-    IntGetViewportOrgEx(dc, &ptViewportOrg);
-    IntGetWindowExtEx(dc, &szWindowExt);
-    IntGetWindowOrgEx(dc, &ptWindowOrg);
-    
-    MatrixS2XForm(&xform, &dc->DcLevel.mxWorldToPage);
+    mapMode = pdcattr->iMapMode;
+
+    DC_vUpdateViewportExt(dc);
+    szViewportExt = dc->pdcattr->szlViewportExt;
+    ptViewportOrg = dc->pdcattr->ptlViewportOrg;
+    szWindowExt = dc->pdcattr->szlWindowExt;
+    ptWindowOrg = dc->pdcattr->ptlWindowOrg;
+
+    MatrixS2XForm(&xform, &dc->dclevel.mxWorldToPage);
 
     /* Set MM_TEXT */
-    Dc_Attr->iMapMode = MM_TEXT;
-    Dc_Attr->ptlViewportOrg.x = 0;
-    Dc_Attr->ptlViewportOrg.y = 0;
-    Dc_Attr->ptlWindowOrg.x = 0;
-    Dc_Attr->ptlWindowOrg.y = 0;
-    graphicsMode = Dc_Attr->iGraphicsMode;
-    Dc_Attr->iGraphicsMode = GM_ADVANCED;
+    pdcattr->iMapMode = MM_TEXT;
+    pdcattr->ptlViewportOrg.x = 0;
+    pdcattr->ptlViewportOrg.y = 0;
+    pdcattr->ptlWindowOrg.x = 0;
+    pdcattr->ptlWindowOrg.y = 0;
+    graphicsMode = pdcattr->iGraphicsMode;
+    pdcattr->iGraphicsMode = GM_ADVANCED;
     IntGdiModifyWorldTransform(dc, &xform, MWT_IDENTITY);
-    Dc_Attr->iGraphicsMode = graphicsMode;
+    pdcattr->iGraphicsMode = graphicsMode;
 
     /* Allocate enough memory for the worst case without beziers (one PT_MOVETO
      * and the rest PT_LINETO with PT_CLOSEFIGURE at the end) plus some buffer
@@ -1358,7 +1375,7 @@ BOOL FASTCALL PATH_StrokePath(DC *dc, PPATH pPath)
     if(!pLinePts)
     {
         DPRINT1("Can't allocate pool!\n");
-        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         goto end;
     }
     nLinePts = 0;
@@ -1424,12 +1441,12 @@ BOOL FASTCALL PATH_StrokePath(DC *dc, PPATH pPath)
                     }
 
                     memcpy(Realloc, pLinePts, nLinePts*sizeof(POINT));
-                    ExFreePool(pLinePts);
+                    ExFreePoolWithTag(pLinePts, TAG_PATH);
                     pLinePts = Realloc;
                 }
                 memcpy(&pLinePts[nLinePts], &pBzrPts[1], (nBzrPts - 1) * sizeof(POINT));
                 nLinePts += nBzrPts - 1;
-                ExFreePool(pBzrPts);
+                ExFreePoolWithTag(pBzrPts, TAG_BEZIER);
                 i += 2;
             }
             break;
@@ -1449,22 +1466,22 @@ BOOL FASTCALL PATH_StrokePath(DC *dc, PPATH pPath)
     ret = TRUE;
 
 end:
-    if(pLinePts)ExFreePool(pLinePts);
+    if(pLinePts) ExFreePoolWithTag(pLinePts, TAG_PATH);
 
     /* Restore the old mapping mode */
-    Dc_Attr->iMapMode =  mapMode;
-    Dc_Attr->szlWindowExt.cx = szWindowExt.cx;
-    Dc_Attr->szlWindowExt.cy = szWindowExt.cy;
-    Dc_Attr->ptlWindowOrg.x = ptWindowOrg.x;
-    Dc_Attr->ptlWindowOrg.y = ptWindowOrg.y;
+    pdcattr->iMapMode =  mapMode;
+    pdcattr->szlWindowExt.cx = szWindowExt.cx;
+    pdcattr->szlWindowExt.cy = szWindowExt.cy;
+    pdcattr->ptlWindowOrg.x = ptWindowOrg.x;
+    pdcattr->ptlWindowOrg.y = ptWindowOrg.y;
 
-    Dc_Attr->szlViewportExt.cx = szViewportExt.cx;
-    Dc_Attr->szlViewportExt.cy = szViewportExt.cy;
-    Dc_Attr->ptlViewportOrg.x = ptViewportOrg.x;
-    Dc_Attr->ptlViewportOrg.y = ptViewportOrg.y;
+    pdcattr->szlViewportExt.cx = szViewportExt.cx;
+    pdcattr->szlViewportExt.cy = szViewportExt.cy;
+    pdcattr->ptlViewportOrg.x = ptViewportOrg.x;
+    pdcattr->ptlViewportOrg.y = ptViewportOrg.y;
 
     /* Restore the world transform */
-    XForm2MatrixS(&dc->DcLevel.mxWorldToPage, &xform);
+    XForm2MatrixS(&dc->dclevel.mxWorldToPage, &xform);
 
     /* If we've moved the current point then get its new position
        which will be in device (MM_TEXT) co-ords, convert it to
@@ -1477,7 +1494,7 @@ end:
         POINT pt;
         IntGetCurrentPositionEx(dc, &pt);
         IntDPtoLP(dc, &pt, 1);
-        IntGdiMoveToEx(dc, pt.x, pt.y, NULL);
+        IntGdiMoveToEx(dc, pt.x, pt.y, NULL, FALSE);
     }
     DPRINT("Leave %s, ret=%d\n", __FUNCTION__, ret);
     return ret;
@@ -1492,37 +1509,35 @@ PATH_WidenPath(DC *dc)
 {
     INT i, j, numStrokes, penWidth, penWidthIn, penWidthOut, size, penStyle;
     BOOL ret = FALSE;
-    PPATH pPath, pNewPath, *pStrokes, pUpPath, pDownPath;
+    PPATH pPath, pNewPath, *pStrokes = NULL, *pOldStrokes, pUpPath, pDownPath;
     EXTLOGPEN *elp;
     DWORD obj_type, joint, endcap, penType;
-    PDC_ATTR Dc_Attr = dc->pDc_Attr;
+    PDC_ATTR pdcattr = dc->pdcattr;
 
-    pPath = PATH_LockPath( dc->DcLevel.hPath );
+    pPath = PATH_LockPath( dc->dclevel.hPath );
     if (!pPath) return FALSE;
 
     if(pPath->state == PATH_Open)
     {
        PATH_UnlockPath( pPath );
-       SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+       EngSetLastError(ERROR_CAN_NOT_COMPLETE);
        return FALSE;
     }
 
-    if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
-
     PATH_FlattenPath(pPath);
 
-    size = IntGdiGetObject( Dc_Attr->hpen, 0, NULL);
+    size = GreGetObject( pdcattr->hpen, 0, NULL);
     if (!size)
     {
         PATH_UnlockPath( pPath );
-        SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+        EngSetLastError(ERROR_CAN_NOT_COMPLETE);
         return FALSE;
     }
 
     elp = ExAllocatePoolWithTag(PagedPool, size, TAG_PATH);
-    (VOID) IntGdiGetObject( Dc_Attr->hpen, size, elp);
+    GreGetObject(pdcattr->hpen, size, elp);
 
-    obj_type = GDIOBJ_GetObjectType(Dc_Attr->hpen);
+    obj_type = GDI_HANDLE_GET_TYPE(pdcattr->hpen);
     if(obj_type == GDI_OBJECT_TYPE_PEN)
     {
         penStyle = ((LOGPEN*)elp)->lopnStyle;
@@ -1533,14 +1548,14 @@ PATH_WidenPath(DC *dc)
     }
     else
     {
-        SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
-        ExFreePool(elp);
+        EngSetLastError(ERROR_CAN_NOT_COMPLETE);
+        ExFreePoolWithTag(elp, TAG_PATH);
         PATH_UnlockPath( pPath );
         return FALSE;
     }
 
     penWidth = elp->elpWidth;
-    ExFreePool(elp);
+    ExFreePoolWithTag(elp, TAG_PATH);
 
     endcap = (PS_ENDCAP_MASK & penStyle);
     joint = (PS_JOIN_MASK & penStyle);
@@ -1550,7 +1565,7 @@ PATH_WidenPath(DC *dc)
     if(obj_type == GDI_OBJECT_TYPE_EXTPEN && penType == PS_COSMETIC)
     {
         PATH_UnlockPath( pPath );
-        SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+        EngSetLastError(ERROR_CAN_NOT_COMPLETE);
         return FALSE;
     }
 
@@ -1561,13 +1576,6 @@ PATH_WidenPath(DC *dc)
 
     numStrokes = 0;
 
-    pStrokes    = ExAllocatePoolWithTag(PagedPool, sizeof(PPATH), TAG_PATH);
-    pStrokes[0] = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH);
-    PATH_InitGdiPath(pStrokes[0]);
-    pStrokes[0]->pFlags =   ExAllocatePoolWithTag(PagedPool, pPath->numEntriesUsed * sizeof(INT), TAG_PATH);
-    pStrokes[0]->pPoints =  ExAllocatePoolWithTag(PagedPool, pPath->numEntriesUsed * sizeof(POINT), TAG_PATH);
-    pStrokes[0]->numEntriesUsed = 0;
-
     for(i = 0, j = 0; i < pPath->numEntriesUsed; i++, j++)
     {
         POINT point;
@@ -1588,8 +1596,17 @@ PATH_WidenPath(DC *dc)
                 }
                 numStrokes++;
                 j = 0;
-                ExFreePool(pStrokes);
-                pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH);
+                if (numStrokes == 1)
+                   pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH);
+                else
+                {
+                   pOldStrokes = pStrokes; // Save old pointer.
+                   pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH);
+                   if (!pStrokes) return FALSE;
+                   RtlCopyMemory(pStrokes, pOldStrokes, numStrokes * sizeof(PPATH));
+                   ExFreePoolWithTag(pOldStrokes, TAG_PATH); // Free old pointer.
+                }
+                if (!pStrokes) return FALSE;
                 pStrokes[numStrokes - 1] = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH);
 
                 PATH_InitGdiPath(pStrokes[numStrokes - 1]);
@@ -1610,7 +1627,7 @@ PATH_WidenPath(DC *dc)
         }
     }
 
-    pNewPath = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH);  
+    pNewPath = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH);
     PATH_InitGdiPath(pNewPath);
     pNewPath->state = PATH_Open;
 
@@ -1713,7 +1730,7 @@ PATH_WidenPath(DC *dc)
                 alpha = atan2( yb - yo, xb - xo ) - theta;
                 if (alpha > 0) alpha -= M_PI;
                 else alpha += M_PI;
-                if(_joint == PS_JOIN_MITER && dc->DcLevel.laPath.eMiterLimit < fabs(1 / sin(alpha/2)))
+                if(_joint == PS_JOIN_MITER && dc->dclevel.laPath.eMiterLimit < fabs(1 / sin(alpha/2)))
                 {
                     _joint = PS_JOIN_BEVEL;
                 }
@@ -1834,22 +1851,256 @@ PATH_WidenPath(DC *dc)
         }
 
         PATH_DestroyGdiPath(pStrokes[i]);
-        ExFreePool(pStrokes[i]);
+        ExFreePoolWithTag(pStrokes[i], TAG_PATH);
         PATH_DestroyGdiPath(pUpPath);
-        ExFreePool(pUpPath);
+        ExFreePoolWithTag(pUpPath, TAG_PATH);
         PATH_DestroyGdiPath(pDownPath);
-        ExFreePool(pDownPath);
+        ExFreePoolWithTag(pDownPath, TAG_PATH);
     }
-    ExFreePool(pStrokes);
+    if (pStrokes) ExFreePoolWithTag(pStrokes, TAG_PATH);
 
     pNewPath->state = PATH_Closed;
     if (!(ret = PATH_AssignGdiPath(pPath, pNewPath)))
         DPRINT1("Assign path failed\n");
     PATH_DestroyGdiPath(pNewPath);
-    ExFreePool(pNewPath);
+    ExFreePoolWithTag(pNewPath, TAG_PATH);
+    PATH_UnlockPath(pPath);
     return ret;
 }
 
+static inline INT int_from_fixed(FIXED f)
+{
+    return (f.fract >= 0x8000) ? (f.value + 1) : f.value;
+}
+
+/**********************************************************************
+ *      PATH_BezierTo
+ *
+ * internally used by PATH_add_outline
+ */
+static
+VOID
+FASTCALL
+PATH_BezierTo(PPATH pPath, POINT *lppt, INT n)
+{
+    if (n < 2) return;
+
+    if (n == 2)
+    {
+        PATH_AddEntry(pPath, &lppt[1], PT_LINETO);
+    }
+    else if (n == 3)
+    {
+        PATH_AddEntry(pPath, &lppt[0], PT_BEZIERTO);
+        PATH_AddEntry(pPath, &lppt[1], PT_BEZIERTO);
+        PATH_AddEntry(pPath, &lppt[2], PT_BEZIERTO);
+    }
+    else
+    {
+        POINT pt[3];
+        INT i = 0;
+
+        pt[2] = lppt[0];
+        n--;
+
+        while (n > 2)
+        {
+            pt[0] = pt[2];
+            pt[1] = lppt[i+1];
+            pt[2].x = (lppt[i+2].x + lppt[i+1].x) / 2;
+            pt[2].y = (lppt[i+2].y + lppt[i+1].y) / 2;
+            PATH_BezierTo(pPath, pt, 3);
+            n--;
+            i++;
+        }
+
+        pt[0] = pt[2];
+        pt[1] = lppt[i+1];
+        pt[2] = lppt[i+2];
+        PATH_BezierTo(pPath, pt, 3);
+    }
+}
+
+static
+BOOL
+FASTCALL
+PATH_add_outline(PDC dc, INT x, INT y, TTPOLYGONHEADER *header, DWORD size)
+{
+  PPATH pPath;
+  TTPOLYGONHEADER *start;
+  POINT pt;
+
+  start = header;
+
+  pPath = PATH_LockPath(dc->dclevel.hPath);
+  {
+     return FALSE;
+  }
+
+  while ((char *)header < (char *)start + size)
+  {
+     TTPOLYCURVE *curve;
+
+     if (header->dwType != TT_POLYGON_TYPE)
+     {
+        DPRINT1("Unknown header type %d\n", header->dwType);
+        return FALSE;
+     }
+
+     pt.x = x + int_from_fixed(header->pfxStart.x);
+     pt.y = y - int_from_fixed(header->pfxStart.y);
+     IntLPtoDP(dc, &pt, 1);
+     PATH_AddEntry(pPath, &pt, PT_MOVETO);
+
+     curve = (TTPOLYCURVE *)(header + 1);
+
+     while ((char *)curve < (char *)header + header->cb)
+     {
+        /*DPRINT1("curve->wType %d\n", curve->wType);*/
+
+        switch(curve->wType)
+        {
+           case TT_PRIM_LINE:
+           {
+              WORD i;
+
+              for (i = 0; i < curve->cpfx; i++)
+              {
+                 pt.x = x + int_from_fixed(curve->apfx[i].x);
+                 pt.y = y - int_from_fixed(curve->apfx[i].y);
+                 IntLPtoDP(dc, &pt, 1);
+                 PATH_AddEntry(pPath, &pt, PT_LINETO);
+              }
+              break;
+           }
+
+           case TT_PRIM_QSPLINE:
+           case TT_PRIM_CSPLINE:
+           {
+              WORD i;
+              POINTFX ptfx;
+              POINT *pts = ExAllocatePoolWithTag(PagedPool, (curve->cpfx + 1) * sizeof(POINT), TAG_PATH);
+
+              if (!pts) return FALSE;
+
+              ptfx = *(POINTFX *)((char *)curve - sizeof(POINTFX));
+
+              pts[0].x = x + int_from_fixed(ptfx.x);
+              pts[0].y = y - int_from_fixed(ptfx.y);
+              IntLPtoDP(dc, &pts[0], 1);
+
+              for (i = 0; i < curve->cpfx; i++)
+              {
+                  pts[i + 1].x = x + int_from_fixed(curve->apfx[i].x);
+                  pts[i + 1].y = y - int_from_fixed(curve->apfx[i].y);
+                  IntLPtoDP(dc, &pts[i + 1], 1);
+              }
+
+              PATH_BezierTo(pPath, pts, curve->cpfx + 1);
+
+              ExFreePoolWithTag(pts, TAG_PATH);
+              break;
+           }
+
+           default:
+              DPRINT1("Unknown curve type %04x\n", curve->wType);
+              return FALSE;
+        }
+
+        curve = (TTPOLYCURVE *)&curve->apfx[curve->cpfx];
+     }
+     header = (TTPOLYGONHEADER *)((char *)header + header->cb);
+  }
+
+  IntGdiCloseFigure( pPath );
+  PATH_UnlockPath( pPath );
+  return TRUE;
+}
+
+/**********************************************************************
+ *      PATH_ExtTextOut
+ */
+BOOL
+FASTCALL
+PATH_ExtTextOut(PDC dc, INT x, INT y, UINT flags, const RECTL *lprc,
+                     LPCWSTR str, UINT count, const INT *dx)
+{
+    unsigned int idx;
+    double cosEsc, sinEsc;
+    PDC_ATTR pdcattr;
+    PTEXTOBJ TextObj;
+    LOGFONTW lf;
+    POINTL org;
+    INT offset = 0, xoff = 0, yoff = 0;
+
+    if (!count) return TRUE;
+
+    pdcattr = dc->pdcattr;
+
+    TextObj = RealizeFontInit( pdcattr->hlfntNew);
+    if ( !TextObj ) return FALSE;
+
+    FontGetObject( TextObj, sizeof(lf), &lf);
+    TEXTOBJ_UnlockText(TextObj);
+
+    if (lf.lfEscapement != 0)
+    {
+        cosEsc = cos(lf.lfEscapement * M_PI / 1800);
+        sinEsc = sin(lf.lfEscapement * M_PI / 1800);
+    } else
+    {
+        cosEsc = 1;
+        sinEsc = 0;
+    }
+
+    org = dc->ptlDCOrig;
+
+    for (idx = 0; idx < count; idx++)
+    {
+        GLYPHMETRICS gm;
+        DWORD dwSize;
+        void *outline;
+
+        dwSize = ftGdiGetGlyphOutline( dc,
+                                       str[idx],
+                                       GGO_GLYPH_INDEX | GGO_NATIVE,
+                                       &gm,
+                                       0,
+                                       NULL,
+                                       NULL,
+                                       TRUE);
+        if (!dwSize) return FALSE;
+
+        outline = ExAllocatePoolWithTag(PagedPool, dwSize, TAG_PATH);
+        if (!outline) return FALSE;
+
+        ftGdiGetGlyphOutline( dc,
+                              str[idx],
+                              GGO_GLYPH_INDEX | GGO_NATIVE,
+                              &gm,
+                              dwSize,
+                              outline,
+                              NULL,
+                              TRUE);
+
+        PATH_add_outline(dc, org.x + x + xoff, org.x + y + yoff, outline, dwSize);
+
+        ExFreePoolWithTag(outline, TAG_PATH);
+
+        if (dx)
+        {
+            offset += dx[idx];
+            xoff = offset * cosEsc;
+            yoff = offset * -sinEsc;
+        }
+        else
+        {
+            xoff += gm.gmCellIncX;
+            yoff += gm.gmCellIncY;
+        }
+    }
+    return TRUE;
+}
 
 
 /***********************************************************************
@@ -1857,18 +2108,19 @@ PATH_WidenPath(DC *dc)
  */
 
 BOOL
-STDCALL
+APIENTRY
 NtGdiAbortPath(HDC  hDC)
 {
   PPATH pPath;
   PDC dc = DC_LockDc ( hDC );
   if ( !dc )
   {
-     SetLastWin32Error(ERROR_INVALID_HANDLE);
+     EngSetLastError(ERROR_INVALID_HANDLE);
      return FALSE;
   }
 
-  pPath = PATH_LockPath(dc->DcLevel.hPath);
+  pPath = PATH_LockPath(dc->dclevel.hPath);
+  if (!pPath)
   {
       DC_UnlockDc(dc);
       return FALSE;
@@ -1877,12 +2129,14 @@ NtGdiAbortPath(HDC  hDC)
   PATH_EmptyPath(pPath);
 
   PATH_UnlockPath(pPath);
+  dc->dclevel.flPath &= ~DCPATH_ACTIVE;
+
   DC_UnlockDc ( dc );
   return TRUE;
 }
 
 BOOL
-STDCALL
+APIENTRY
 NtGdiBeginPath( HDC  hDC )
 {
   PPATH pPath;
@@ -1891,23 +2145,23 @@ NtGdiBeginPath( HDC  hDC )
   dc = DC_LockDc ( hDC );
   if ( !dc )
   {
-     SetLastWin32Error(ERROR_INVALID_HANDLE);
+     EngSetLastError(ERROR_INVALID_HANDLE);
      return FALSE;
   }
 
   /* If path is already open, do nothing. Check if not Save DC state */
-    if ((dc->DcLevel.flPath & DCPATH_ACTIVE) && !(dc->DcLevel.flPath & DCPATH_SAVE))
+    if ((dc->dclevel.flPath & DCPATH_ACTIVE) && !(dc->dclevel.flPath & DCPATH_SAVE))
   {
      DC_UnlockDc ( dc );
      return TRUE;
   }
 
-  if ( dc->DcLevel.hPath )
+  if ( dc->dclevel.hPath )
   {
-     DPRINT1("BeginPath 1 0x%x\n", dc->DcLevel.hPath);
-     if ( !(dc->DcLevel.flPath & DCPATH_SAVE) )
+     DPRINT("BeginPath 1 0x%x\n", dc->dclevel.hPath);
+     if ( !(dc->dclevel.flPath & DCPATH_SAVE) )
      {  // Remove previous handle.
-        if (!PATH_Delete(dc->DcLevel.hPath))
+        if (!PATH_Delete(dc->dclevel.hPath))
         {
            DC_UnlockDc ( dc );
            return FALSE;
@@ -1915,24 +2169,24 @@ NtGdiBeginPath( HDC  hDC )
      }
      else
      {  // Clear flags and Handle.
-        dc->DcLevel.flPath &= ~(DCPATH_SAVE|DCPATH_ACTIVE);
-        dc->DcLevel.hPath = NULL;
+        dc->dclevel.flPath &= ~(DCPATH_SAVE|DCPATH_ACTIVE);
+        dc->dclevel.hPath = NULL;
      }
   }
   pPath = PATH_AllocPathWithHandle();
   if (!pPath)
   {
-     SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+     EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
      return FALSE;
   }
-  dc->DcLevel.flPath |= DCPATH_ACTIVE; // Set active ASAP!
+  dc->dclevel.flPath |= DCPATH_ACTIVE; // Set active ASAP!
 
-  dc->DcLevel.hPath = pPath->BaseObject.hHmgr;
+  dc->dclevel.hPath = pPath->BaseObject.hHmgr;
 
-  DPRINT1("BeginPath 2 h 0x%x p 0x%x\n", dc->DcLevel.hPath, pPath);
+  DPRINT("BeginPath 2 h 0x%x p 0x%x\n", dc->dclevel.hPath, pPath);
   // Path handles are shared. Also due to recursion with in the same thread.
-  GDIOBJ_UnlockObjByPtr((POBJ)pPath);       // Unlock
-  pPath = PATH_LockPath(dc->DcLevel.hPath); // Share Lock.
+  GDIOBJ_vUnlockObject((POBJ)pPath);       // Unlock
+  pPath = PATH_LockPath(dc->dclevel.hPath); // Share Lock.
 
   /* Make sure that path is empty */
   PATH_EmptyPath( pPath );
@@ -1947,7 +2201,7 @@ NtGdiBeginPath( HDC  hDC )
 }
 
 BOOL
-STDCALL
+APIENTRY
 NtGdiCloseFigure(HDC hDC)
 {
   BOOL Ret = FALSE; // default to failure
@@ -1959,10 +2213,10 @@ NtGdiCloseFigure(HDC hDC)
   pDc = DC_LockDc(hDC);
   if (!pDc)
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return FALSE;
-  }   
-  pPath = PATH_LockPath( pDc->DcLevel.hPath );
+  }
+  pPath = PATH_LockPath( pDc->dclevel.hPath );
   if (!pPath)
   {
      DC_UnlockDc(pDc);
@@ -1977,7 +2231,7 @@ NtGdiCloseFigure(HDC hDC)
   else
   {
      // FIXME: check if lasterror is set correctly
-     SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+     EngSetLastError(ERROR_CAN_NOT_COMPLETE);
   }
 
   PATH_UnlockPath( pPath );
@@ -1986,7 +2240,7 @@ NtGdiCloseFigure(HDC hDC)
 }
 
 BOOL
-STDCALL
+APIENTRY
 NtGdiEndPath(HDC  hDC)
 {
   BOOL ret = TRUE;
@@ -1995,29 +2249,29 @@ NtGdiEndPath(HDC  hDC)
 
   if ( !dc )
   {
-     SetLastWin32Error(ERROR_INVALID_HANDLE);
+     EngSetLastError(ERROR_INVALID_HANDLE);
      return FALSE;
   }
 
-  pPath = PATH_LockPath( dc->DcLevel.hPath );
+  pPath = PATH_LockPath( dc->dclevel.hPath );
   if (!pPath)
   {
      DC_UnlockDc ( dc );
      return FALSE;
   }
   /* Check that path is currently being constructed */
-  if ( (pPath->state != PATH_Open) || !(dc->DcLevel.flPath & DCPATH_ACTIVE) )
+  if ( (pPath->state != PATH_Open) || !(dc->dclevel.flPath & DCPATH_ACTIVE) )
   {
-    DPRINT1("EndPath ERROR! 0x%x\n", dc->DcLevel.hPath);
-    SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+    DPRINT1("EndPath ERROR! 0x%x\n", dc->dclevel.hPath);
+    EngSetLastError(ERROR_CAN_NOT_COMPLETE);
     ret = FALSE;
   }
   /* Set flag to indicate that path is finished */
   else
   {
-     DPRINT1("EndPath 0x%x\n", dc->DcLevel.hPath);
+     DPRINT("EndPath 0x%x\n", dc->dclevel.hPath);
      pPath->state = PATH_Closed;
-     dc->DcLevel.flPath &= ~DCPATH_ACTIVE;
+     dc->dclevel.flPath &= ~DCPATH_ACTIVE;
   }
   PATH_UnlockPath( pPath );
   DC_UnlockDc ( dc );
@@ -2025,25 +2279,39 @@ NtGdiEndPath(HDC  hDC)
 }
 
 BOOL
-STDCALL
+APIENTRY
 NtGdiFillPath(HDC  hDC)
 {
-  BOOL ret = TRUE;
+  BOOL ret = FALSE;
   PPATH pPath;
-  PDC dc = DC_LockDc ( hDC );
-  if ( !dc )
+  PDC_ATTR pdcattr;
+  PDC dc;
+
+  dc = DC_LockDc(hDC);
+  if (!dc)
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return FALSE;
   }
-  pPath = PATH_LockPath( dc->DcLevel.hPath );
+
+  pPath = PATH_LockPath( dc->dclevel.hPath );
   if (!pPath)
   {
      DC_UnlockDc ( dc );
      return FALSE;
   }
 
+  DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
+                            NULL, dc->rosdc.CombinedClip->rclBounds);
+
+  pdcattr = dc->pdcattr;
+
+  if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+      DC_vUpdateLineBrush(dc);
+
+  if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+      DC_vUpdateFillBrush(dc);
+
   ret = PATH_FillPath( dc, pPath );
   if ( ret )
   {
@@ -2053,12 +2321,13 @@ NtGdiFillPath(HDC  hDC)
   }
 
   PATH_UnlockPath( pPath );
+  DC_vFinishBlit(dc, NULL);
   DC_UnlockDc ( dc );
   return ret;
 }
 
 BOOL
-STDCALL
+APIENTRY
 NtGdiFlattenPath(HDC  hDC)
 {
    BOOL Ret = FALSE;
@@ -2070,11 +2339,11 @@ NtGdiFlattenPath(HDC  hDC)
    pDc = DC_LockDc(hDC);
    if (!pDc)
    {
-      SetLastWin32Error(ERROR_INVALID_HANDLE);  
+      EngSetLastError(ERROR_INVALID_HANDLE);
       return FALSE;
    }
 
-   pPath = PATH_LockPath( pDc->DcLevel.hPath );
+   pPath = PATH_LockPath( pDc->dclevel.hPath );
    if (!pPath)
    {
       DC_UnlockDc ( pDc );
@@ -2101,26 +2370,26 @@ NtGdiGetMiterLimit(
 
   if (!(pDc = DC_LockDc(hdc)))
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return FALSE;
   }
 
-  worker.f = pDc->DcLevel.laPath.eMiterLimit;
+  worker.f = pDc->dclevel.laPath.eMiterLimit;
 
   if (pdwOut)
   {
-      _SEH_TRY
+      _SEH2_TRY
       {
           ProbeForWrite(pdwOut,
                  sizeof(DWORD),
                              1);
           *pdwOut = worker.l;
       }
-      _SEH_HANDLE
+      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
       {
-          Status = _SEH_GetExceptionCode();
+          Status = _SEH2_GetExceptionCode();
       }
-       _SEH_END;
+       _SEH2_END;
       if (!NT_SUCCESS(Status))
       {
          SetLastNtError(Status);
@@ -2135,7 +2404,7 @@ NtGdiGetMiterLimit(
 }
 
 INT
-STDCALL
+APIENTRY
 NtGdiGetPath(
    HDC hDC,
    LPPOINT Points,
@@ -2149,11 +2418,11 @@ NtGdiGetPath(
   if (!dc)
   {
      DPRINT1("Can't lock dc!\n");
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return -1;
   }
 
-  pPath = PATH_LockPath( dc->DcLevel.hPath );
+  pPath = PATH_LockPath( dc->dclevel.hPath );
   if (!pPath)
   {
      DC_UnlockDc ( dc );
@@ -2162,7 +2431,7 @@ NtGdiGetPath(
 
   if (pPath->state != PATH_Closed)
   {
-     SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+     EngSetLastError(ERROR_CAN_NOT_COMPLETE);
      goto done;
   }
 
@@ -2172,12 +2441,12 @@ NtGdiGetPath(
   }
   else if(nSize<pPath->numEntriesUsed)
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      goto done;
   }
   else
   {
-      _SEH_TRY
+      _SEH2_TRY
       {
          memcpy(Points, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed);
          memcpy(Types, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed);
@@ -2187,11 +2456,11 @@ NtGdiGetPath(
 
          ret = pPath->numEntriesUsed;
       }
-      _SEH_HANDLE
+      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
       {
-         SetLastNtError(_SEH_GetExceptionCode());
+         SetLastNtError(_SEH2_GetExceptionCode());
       }
-      _SEH_END
+      _SEH2_END
   }
 
 done:
@@ -2201,27 +2470,26 @@ done:
 }
 
 HRGN
-STDCALL
+APIENTRY
 NtGdiPathToRegion(HDC  hDC)
 {
   PPATH pPath;
   HRGN  hrgnRval = 0;
   DC *pDc;
-  PDC_ATTR Dc_Attr;
+  PDC_ATTR pdcattr;
 
   DPRINT("Enter %s\n", __FUNCTION__);
 
   pDc = DC_LockDc(hDC);
   if (!pDc)
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return NULL;
   }
 
-  Dc_Attr = pDc->pDc_Attr;
-  if(!Dc_Attr) Dc_Attr = &pDc->Dc_Attr;
+  pdcattr = pDc->pdcattr;
 
-  pPath = PATH_LockPath( pDc->DcLevel.hPath );
+  pPath = PATH_LockPath( pDc->dclevel.hPath );
   if (!pPath)
   {
      DC_UnlockDc ( pDc );
@@ -2231,12 +2499,12 @@ NtGdiPathToRegion(HDC  hDC)
   if (pPath->state!=PATH_Closed)
   {
      //FIXME: check that setlasterror is being called correctly
-     SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+     EngSetLastError(ERROR_CAN_NOT_COMPLETE);
   }
   else
   {
      /* FIXME: Should we empty the path even if conversion failed? */
-     if(PATH_PathToRegion(pPath, Dc_Attr->jFillMode, &hrgnRval))
+     if(PATH_PathToRegion(pPath, pdcattr->jFillMode, &hrgnRval))
           PATH_EmptyPath(pPath);
   }
 
@@ -2258,28 +2526,28 @@ NtGdiSetMiterLimit(
 
   if (!(pDc = DC_LockDc(hdc)))
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return FALSE;
   }
 
   worker.l  = dwNew;
-  worker1.f = pDc->DcLevel.laPath.eMiterLimit;
-  pDc->DcLevel.laPath.eMiterLimit = worker.f;
+  worker1.f = pDc->dclevel.laPath.eMiterLimit;
+  pDc->dclevel.laPath.eMiterLimit = worker.f;
 
   if (pdwOut)
   {
-      _SEH_TRY
+      _SEH2_TRY
       {
           ProbeForWrite(pdwOut,
                  sizeof(DWORD),
                              1);
           *pdwOut = worker1.l;
       }
-      _SEH_HANDLE
+      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
       {
-          Status = _SEH_GetExceptionCode();
+          Status = _SEH2_GetExceptionCode();
       }
-       _SEH_END;
+       _SEH2_END;
       if (!NT_SUCCESS(Status))
       {
          SetLastNtError(Status);
@@ -2293,10 +2561,11 @@ NtGdiSetMiterLimit(
 }
 
 BOOL
-STDCALL
+APIENTRY
 NtGdiStrokeAndFillPath(HDC hDC)
 {
   DC *pDc;
+  PDC_ATTR pdcattr;
   PPATH pPath;
   BOOL bRet = FALSE;
 
@@ -2304,29 +2573,43 @@ NtGdiStrokeAndFillPath(HDC hDC)
 
   if (!(pDc = DC_LockDc(hDC)))
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return FALSE;
   }
-  pPath = PATH_LockPath( pDc->DcLevel.hPath );
+  pPath = PATH_LockPath( pDc->dclevel.hPath );
   if (!pPath)
   {
      DC_UnlockDc ( pDc );
      return FALSE;
   }
+
+  DC_vPrepareDCsForBlit(pDc, pDc->rosdc.CombinedClip->rclBounds,
+                            NULL, pDc->rosdc.CombinedClip->rclBounds);
+
+  pdcattr = pDc->pdcattr;
+
+  if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+    DC_vUpdateFillBrush(pDc);
+
+  if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+    DC_vUpdateLineBrush(pDc);
+
   bRet = PATH_FillPath(pDc, pPath);
   if (bRet) bRet = PATH_StrokePath(pDc, pPath);
   if (bRet) PATH_EmptyPath(pPath);
 
   PATH_UnlockPath( pPath );
+  DC_vFinishBlit(pDc, NULL);
   DC_UnlockDc(pDc);
   return bRet;
 }
 
 BOOL
-STDCALL
+APIENTRY
 NtGdiStrokePath(HDC hDC)
 {
   DC *pDc;
+  PDC_ATTR pdcattr;
   PPATH pPath;
   BOOL bRet = FALSE;
 
@@ -2334,17 +2617,27 @@ NtGdiStrokePath(HDC hDC)
 
   if (!(pDc = DC_LockDc(hDC)))
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return FALSE;
   }
-  pPath = PATH_LockPath( pDc->DcLevel.hPath );
+  pPath = PATH_LockPath( pDc->dclevel.hPath );
   if (!pPath)
   {
      DC_UnlockDc ( pDc );
      return FALSE;
   }
 
+  DC_vPrepareDCsForBlit(pDc, pDc->rosdc.CombinedClip->rclBounds,
+                            NULL, pDc->rosdc.CombinedClip->rclBounds);
+
+  pdcattr = pDc->pdcattr;
+
+  if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+     DC_vUpdateLineBrush(pDc);
+
   bRet = PATH_StrokePath(pDc, pPath);
+
+  DC_vFinishBlit(pDc, NULL);
   PATH_EmptyPath(pPath);
 
   PATH_UnlockPath( pPath );
@@ -2353,14 +2646,14 @@ NtGdiStrokePath(HDC hDC)
 }
 
 BOOL
-STDCALL
+APIENTRY
 NtGdiWidenPath(HDC  hDC)
 {
   BOOL Ret;
-  PDC pdc = DC_LockDc ( hDC );    
+  PDC pdc = DC_LockDc ( hDC );
   if ( !pdc )
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return FALSE;
   }
   Ret = PATH_WidenPath(pdc);
@@ -2368,52 +2661,4 @@ NtGdiWidenPath(HDC  hDC)
   return Ret;
 }
 
-BOOL
-STDCALL
-NtGdiSelectClipPath(HDC  hDC,
-                   int  Mode)
-{
- HRGN  hrgnPath;
- PPATH pPath;
- BOOL  success = FALSE;
- PDC_ATTR Dc_Attr;
- PDC dc = DC_LockDc ( hDC );
- if ( !dc )
- {
-    SetLastWin32Error(ERROR_INVALID_PARAMETER);
-    return FALSE;
- }
-
- Dc_Attr = dc->pDc_Attr;
- if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
-
- pPath = PATH_LockPath( dc->DcLevel.hPath );
- if (!pPath)
- {
-    DC_UnlockDc ( dc );
-    return FALSE;
- }
- /* Check that path is closed */
- if( pPath->state != PATH_Closed )
- {
-   SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
-   return FALSE;
- }
- /* Construct a region from the path */
- else if( PATH_PathToRegion( pPath, Dc_Attr->jFillMode, &hrgnPath ) )
- {
-   success = GdiExtSelectClipRgn( dc, hrgnPath, Mode ) != ERROR;
-   NtGdiDeleteObject( hrgnPath );
-
-   /* Empty the path */
-   if( success )
-     PATH_EmptyPath( pPath);
-   /* FIXME: Should this function delete the path even if it failed? */
- }
- PATH_UnlockPath( pPath );
- DC_UnlockDc ( dc );
- return success;
-}
-
 /* EOF */