[YAROTOWS] Reintegrate the branch. For a brighter future.
[reactos.git] / reactos / subsystems / win32 / win32k / objects / path.c
index 6e76823..da4e31f 100644 (file)
@@ -32,7 +32,7 @@
  * PROGRAMMER:
  */
 
-#include <w32k.h>
+#include <win32k.h>
 #include "math.h"
 
 #define NDEBUG
@@ -64,8 +64,9 @@ 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 );
@@ -97,9 +98,9 @@ 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;
@@ -121,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
@@ -142,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;
@@ -158,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;
@@ -407,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)
@@ -543,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 */
@@ -696,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 )
   {
@@ -804,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 )
   {
@@ -1061,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;
@@ -1070,6 +1069,11 @@ 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)
@@ -1490,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;
@@ -1503,9 +1507,9 @@ BOOL
 FASTCALL
 PATH_WidenPath(DC *dc)
 {
-    INT i, j, numStrokes, numOldStrokes, penWidth, penWidthIn, penWidthOut, size, penStyle;
+    INT i, j, numStrokes, penWidth, penWidthIn, penWidthOut, size, penStyle;
     BOOL ret = FALSE;
-    PPATH pPath, pNewPath, *pStrokes, *pOldStrokes, pUpPath, pDownPath;
+    PPATH pPath, pNewPath, *pStrokes = NULL, *pOldStrokes, pUpPath, pDownPath;
     EXTLOGPEN *elp;
     DWORD obj_type, joint, endcap, penType;
     PDC_ATTR pdcattr = dc->pdcattr;
@@ -1571,14 +1575,6 @@ PATH_WidenPath(DC *dc)
         penWidthOut++;
 
     numStrokes = 0;
-    numOldStrokes = 1;
-
-    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++)
     {
@@ -1600,11 +1596,17 @@ PATH_WidenPath(DC *dc)
                 }
                 numStrokes++;
                 j = 0;
-                pOldStrokes = pStrokes; // Save old pointer.
-                pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH);
-                RtlCopyMemory(pStrokes, pOldStrokes, numOldStrokes * sizeof(PPATH));
-                numOldStrokes = numStrokes; // Save orig count.
-                ExFreePoolWithTag(pOldStrokes, TAG_PATH); // Free old pointer.
+                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]);
@@ -1625,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;
 
@@ -2010,7 +2012,7 @@ PATH_add_outline(PDC dc, INT x, INT y, TTPOLYGONHEADER *header, DWORD size)
   }
 
   IntGdiCloseFigure( pPath );
-  PATH_UnlockPath( pPath );     
+  PATH_UnlockPath( pPath );
   return TRUE;
 }
 
@@ -2018,7 +2020,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)
 {
@@ -2208,7 +2210,7 @@ NtGdiCloseFigure(HDC hDC)
   {
      SetLastWin32Error(ERROR_INVALID_PARAMETER);
      return FALSE;
-  }   
+  }
   pPath = PATH_LockPath( pDc->dclevel.hPath );
   if (!pPath)
   {
@@ -2279,7 +2281,7 @@ NtGdiFillPath(HDC  hDC)
   PPATH pPath;
   PDC_ATTR pdcattr;
   PDC dc = DC_LockDc ( hDC );
+
   if ( !dc )
   {
      SetLastWin32Error(ERROR_INVALID_PARAMETER);
@@ -2292,11 +2294,17 @@ 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))
       DC_vUpdateLineBrush(dc);
 
+  if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+      DC_vUpdateFillBrush(dc);
+
   ret = PATH_FillPath( dc, pPath );
   if ( ret )
   {
@@ -2306,6 +2314,7 @@ NtGdiFillPath(HDC  hDC)
   }
 
   PATH_UnlockPath( pPath );
+  DC_vFinishBlit(dc, NULL);
   DC_UnlockDc ( dc );
   return ret;
 }
@@ -2323,7 +2332,7 @@ NtGdiFlattenPath(HDC  hDC)
    pDc = DC_LockDc(hDC);
    if (!pDc)
    {
-      SetLastWin32Error(ERROR_INVALID_HANDLE);  
+      SetLastWin32Error(ERROR_INVALID_HANDLE);
       return FALSE;
    }
 
@@ -2567,6 +2576,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))
@@ -2580,6 +2592,7 @@ NtGdiStrokeAndFillPath(HDC hDC)
   if (bRet) PATH_EmptyPath(pPath);
 
   PATH_UnlockPath( pPath );
+  DC_vFinishBlit(pDc, NULL);
   DC_UnlockDc(pDc);
   return bRet;
 }
@@ -2607,12 +2620,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 );
@@ -2625,7 +2643,7 @@ APIENTRY
 NtGdiWidenPath(HDC  hDC)
 {
   BOOL Ret;
-  PDC pdc = DC_LockDc ( hDC );    
+  PDC pdc = DC_LockDc ( hDC );
   if ( !pdc )
   {
      SetLastWin32Error(ERROR_INVALID_PARAMETER);