[CMAKE]
[reactos.git] / subsystems / win32 / win32k / objects / path.c
index 1dfca39..82ccf43 100644 (file)
@@ -32,8 +32,9 @@
  * PROGRAMMER:
  */
 
-#include <w32k.h>
-#include "math.h"
+#include <win32k.h>
+#define _USE_MATH_DEFINES
+#include <math.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -69,8 +70,7 @@ PATH_Delete(HPATH hPath)
   pPath = PATH_LockPath( hPath );
   if (!pPath) return FALSE;
   PATH_DestroyGdiPath( pPath );
-  PATH_UnlockPath( pPath );
-  PATH_FreeExtPathByHandle(hPath);
+  GDIOBJ_vDeleteObject(&pPath->BaseObject);
   return TRUE;
 }
 
@@ -98,16 +98,16 @@ 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 pdcattr = dc->pdcattr;
 
   if( pPath->state != PATH_Closed )
   {
-    SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+    EngSetLastError(ERROR_CAN_NOT_COMPLETE);
     return FALSE;
   }
 
@@ -122,11 +122,11 @@ PATH_FillPath( PDC dc, PPATH pPath )
      */
 
     /* Save the information about the old mapping mode */
-    mapMode = pdcattr->iMapMode;
-    ptViewportExt = pdcattr->szlViewportExt;
-    ptViewportOrg = pdcattr->ptlViewportOrg;
-    ptWindowExt   = pdcattr->szlWindowExt;
-    ptWindowOrg   = pdcattr->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
@@ -143,7 +143,7 @@ PATH_FillPath( PDC dc, PPATH pPath )
 //    pdcattr->ptlWindowOrg.x = 0;
 //    pdcattr->ptlWindowOrg.y = 0;
 
-    graphicsMode = pdcattr->iGraphicsMode;
+   // graphicsMode = pdcattr->iGraphicsMode;
 //    pdcattr->iGraphicsMode = GM_ADVANCED;
 //    IntGdiModifyWorldTransform( dc, &xform, MWT_IDENTITY );
 //    pdcattr->iGraphicsMode =  graphicsMode;
@@ -159,7 +159,7 @@ PATH_FillPath( PDC dc, PPATH pPath )
 //    pdcattr->ptlWindowOrg   = ptWindowOrg;
 
     /* Go to GM_ADVANCED temporarily to restore the world transform */
-    graphicsMode = pdcattr->iGraphicsMode;
+    //graphicsMode = pdcattr->iGraphicsMode;
 //    pdcattr->iGraphicsMode = GM_ADVANCED;
 //    IntGdiModifyWorldTransform( dc, &xform, MWT_MAX+1 );
 //    pdcattr->iGraphicsMode = graphicsMode;
@@ -408,7 +408,7 @@ BOOL FASTCALL PATH_RoundRect(DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_wid
    FLOAT_POINT ellCorners[2];
 
    pPath = PATH_LockPath( dc->dclevel.hPath );
-   if (!pPath) return FALSE;   
+   if (!pPath) return FALSE;
 
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
@@ -544,7 +544,7 @@ PATH_Arc ( PDC dc, INT x1, INT y1, INT x2, INT y2,
   if ( pPath->state != PATH_Open )
   {
     Ret = FALSE;
-    goto ArcExit;    
+    goto ArcExit;
   }
 
   /* Check for zero height / width */
@@ -697,7 +697,7 @@ PATH_PolyBezierTo ( PDC dc, const POINT *pts, DWORD cbPoints )
 
    pPath = PATH_LockPath( dc->dclevel.hPath );
    if (!pPath) return FALSE;
-   
+
   /* Check that path is open */
   if ( pPath->state != PATH_Open )
   {
@@ -805,7 +805,7 @@ PATH_PolylineTo ( PDC dc, const POINT *pts, DWORD cbPoints )
 
   pPath = PATH_LockPath( dc->dclevel.hPath );
   if (!pPath) return FALSE;
-   
+
   /* Check that path is open */
   if ( pPath->state != PATH_Open )
   {
@@ -1062,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;
@@ -1071,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;
   }
 
@@ -1100,7 +1103,7 @@ 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;
   }
 
@@ -1372,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;
@@ -1517,24 +1520,24 @@ PATH_WidenPath(DC *dc)
     if(pPath->state == PATH_Open)
     {
        PATH_UnlockPath( pPath );
-       SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+       EngSetLastError(ERROR_CAN_NOT_COMPLETE);
        return FALSE;
     }
 
     PATH_FlattenPath(pPath);
 
-    size = IntGdiGetObject( pdcattr->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( pdcattr->hpen, size, elp);
+    GreGetObject(pdcattr->hpen, size, elp);
 
-    obj_type = GDIOBJ_GetObjectType(pdcattr->hpen);
+    obj_type = GDI_HANDLE_GET_TYPE(pdcattr->hpen);
     if(obj_type == GDI_OBJECT_TYPE_PEN)
     {
         penStyle = ((LOGPEN*)elp)->lopnStyle;
@@ -1545,7 +1548,7 @@ PATH_WidenPath(DC *dc)
     }
     else
     {
-        SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+        EngSetLastError(ERROR_CAN_NOT_COMPLETE);
         ExFreePoolWithTag(elp, TAG_PATH);
         PATH_UnlockPath( pPath );
         return FALSE;
@@ -1562,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;
     }
 
@@ -1594,7 +1597,7 @@ PATH_WidenPath(DC *dc)
                 numStrokes++;
                 j = 0;
                 if (numStrokes == 1)
-                   pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH);                
+                   pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH);
                 else
                 {
                    pOldStrokes = pStrokes; // Save old pointer.
@@ -1624,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;
 
@@ -1854,13 +1857,14 @@ PATH_WidenPath(DC *dc)
         PATH_DestroyGdiPath(pDownPath);
         ExFreePoolWithTag(pDownPath, TAG_PATH);
     }
-    ExFreePoolWithTag(pStrokes, TAG_PATH);
+    if (pStrokes) ExFreePoolWithTag(pStrokes, TAG_PATH);
 
     pNewPath->state = PATH_Closed;
     if (!(ret = PATH_AssignGdiPath(pPath, pNewPath)))
         DPRINT1("Assign path failed\n");
     PATH_DestroyGdiPath(pNewPath);
     ExFreePoolWithTag(pNewPath, TAG_PATH);
+    PATH_UnlockPath(pPath);
     return ret;
 }
 
@@ -2009,7 +2013,7 @@ PATH_add_outline(PDC dc, INT x, INT y, TTPOLYGONHEADER *header, DWORD size)
   }
 
   IntGdiCloseFigure( pPath );
-  PATH_UnlockPath( pPath );     
+  PATH_UnlockPath( pPath );
   return TRUE;
 }
 
@@ -2017,7 +2021,7 @@ PATH_add_outline(PDC dc, INT x, INT y, TTPOLYGONHEADER *header, DWORD size)
  *      PATH_ExtTextOut
  */
 BOOL
-FASTCALL 
+FASTCALL
 PATH_ExtTextOut(PDC dc, INT x, INT y, UINT flags, const RECTL *lprc,
                      LPCWSTR str, UINT count, const INT *dx)
 {
@@ -2037,6 +2041,7 @@ PATH_ExtTextOut(PDC dc, INT x, INT y, UINT flags, const RECTL *lprc,
     if ( !TextObj ) return FALSE;
 
     FontGetObject( TextObj, sizeof(lf), &lf);
+    TEXTOBJ_UnlockText(TextObj);
 
     if (lf.lfEscapement != 0)
     {
@@ -2048,7 +2053,7 @@ PATH_ExtTextOut(PDC dc, INT x, INT y, UINT flags, const RECTL *lprc,
         sinEsc = 0;
     }
 
-    IntGdiGetDCOrg(dc, &org);
+    org = dc->ptlDCOrig;
 
     for (idx = 0; idx < count; idx++)
     {
@@ -2110,11 +2115,12 @@ NtGdiAbortPath(HDC  hDC)
   PDC dc = DC_LockDc ( hDC );
   if ( !dc )
   {
-     SetLastWin32Error(ERROR_INVALID_HANDLE);
+     EngSetLastError(ERROR_INVALID_HANDLE);
      return FALSE;
   }
 
   pPath = PATH_LockPath(dc->dclevel.hPath);
+  if (!pPath)
   {
       DC_UnlockDc(dc);
       return FALSE;
@@ -2123,6 +2129,8 @@ NtGdiAbortPath(HDC  hDC)
   PATH_EmptyPath(pPath);
 
   PATH_UnlockPath(pPath);
+  dc->dclevel.flPath &= ~DCPATH_ACTIVE;
+
   DC_UnlockDc ( dc );
   return TRUE;
 }
@@ -2137,7 +2145,7 @@ NtGdiBeginPath( HDC  hDC )
   dc = DC_LockDc ( hDC );
   if ( !dc )
   {
-     SetLastWin32Error(ERROR_INVALID_HANDLE);
+     EngSetLastError(ERROR_INVALID_HANDLE);
      return FALSE;
   }
 
@@ -2150,7 +2158,7 @@ NtGdiBeginPath( HDC  hDC )
 
   if ( dc->dclevel.hPath )
   {
-     DPRINT1("BeginPath 1 0x%x\n", dc->dclevel.hPath);
+     DPRINT("BeginPath 1 0x%x\n", dc->dclevel.hPath);
      if ( !(dc->dclevel.flPath & DCPATH_SAVE) )
      {  // Remove previous handle.
         if (!PATH_Delete(dc->dclevel.hPath))
@@ -2168,16 +2176,16 @@ NtGdiBeginPath( HDC  hDC )
   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.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
+  GDIOBJ_vUnlockObject((POBJ)pPath);       // Unlock
   pPath = PATH_LockPath(dc->dclevel.hPath); // Share Lock.
 
   /* Make sure that path is empty */
@@ -2205,9 +2213,9 @@ 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 );
   if (!pPath)
   {
@@ -2223,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 );
@@ -2241,7 +2249,7 @@ NtGdiEndPath(HDC  hDC)
 
   if ( !dc )
   {
-     SetLastWin32Error(ERROR_INVALID_HANDLE);
+     EngSetLastError(ERROR_INVALID_HANDLE);
      return FALSE;
   }
 
@@ -2255,13 +2263,13 @@ NtGdiEndPath(HDC  hDC)
   if ( (pPath->state != PATH_Open) || !(dc->dclevel.flPath & DCPATH_ACTIVE) )
   {
     DPRINT1("EndPath ERROR! 0x%x\n", dc->dclevel.hPath);
-    SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+    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;
   }
@@ -2277,13 +2285,15 @@ NtGdiFillPath(HDC  hDC)
   BOOL ret = FALSE;
   PPATH pPath;
   PDC_ATTR pdcattr;
-  PDC dc = DC_LockDc ( hDC );
-  if ( !dc )
+  PDC dc;
+
+  dc = DC_LockDc(hDC);
+  if (!dc)
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return FALSE;
   }
+
   pPath = PATH_LockPath( dc->dclevel.hPath );
   if (!pPath)
   {
@@ -2291,6 +2301,9 @@ NtGdiFillPath(HDC  hDC)
      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))
@@ -2308,6 +2321,7 @@ NtGdiFillPath(HDC  hDC)
   }
 
   PATH_UnlockPath( pPath );
+  DC_vFinishBlit(dc, NULL);
   DC_UnlockDc ( dc );
   return ret;
 }
@@ -2325,7 +2339,7 @@ NtGdiFlattenPath(HDC  hDC)
    pDc = DC_LockDc(hDC);
    if (!pDc)
    {
-      SetLastWin32Error(ERROR_INVALID_HANDLE);  
+      EngSetLastError(ERROR_INVALID_HANDLE);
       return FALSE;
    }
 
@@ -2356,7 +2370,7 @@ NtGdiGetMiterLimit(
 
   if (!(pDc = DC_LockDc(hdc)))
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return FALSE;
   }
 
@@ -2404,7 +2418,7 @@ NtGdiGetPath(
   if (!dc)
   {
      DPRINT1("Can't lock dc!\n");
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return -1;
   }
 
@@ -2417,7 +2431,7 @@ NtGdiGetPath(
 
   if (pPath->state != PATH_Closed)
   {
-     SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+     EngSetLastError(ERROR_CAN_NOT_COMPLETE);
      goto done;
   }
 
@@ -2427,7 +2441,7 @@ NtGdiGetPath(
   }
   else if(nSize<pPath->numEntriesUsed)
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      goto done;
   }
   else
@@ -2469,7 +2483,7 @@ NtGdiPathToRegion(HDC  hDC)
   pDc = DC_LockDc(hDC);
   if (!pDc)
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return NULL;
   }
 
@@ -2485,7 +2499,7 @@ 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
   {
@@ -2512,7 +2526,7 @@ NtGdiSetMiterLimit(
 
   if (!(pDc = DC_LockDc(hdc)))
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return FALSE;
   }
 
@@ -2559,7 +2573,7 @@ NtGdiStrokeAndFillPath(HDC hDC)
 
   if (!(pDc = DC_LockDc(hDC)))
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return FALSE;
   }
   pPath = PATH_LockPath( pDc->dclevel.hPath );
@@ -2569,6 +2583,9 @@ NtGdiStrokeAndFillPath(HDC hDC)
      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))
@@ -2582,6 +2599,7 @@ NtGdiStrokeAndFillPath(HDC hDC)
   if (bRet) PATH_EmptyPath(pPath);
 
   PATH_UnlockPath( pPath );
+  DC_vFinishBlit(pDc, NULL);
   DC_UnlockDc(pDc);
   return bRet;
 }
@@ -2599,7 +2617,7 @@ NtGdiStrokePath(HDC hDC)
 
   if (!(pDc = DC_LockDc(hDC)))
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return FALSE;
   }
   pPath = PATH_LockPath( pDc->dclevel.hPath );
@@ -2609,12 +2627,17 @@ NtGdiStrokePath(HDC hDC)
      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 );
@@ -2627,10 +2650,10 @@ 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);