[ros-diffs] [jimtabor] 54210: [Win32k] - Fix path support, now all wine path tests pass. - Need a PolyDraw test for non-path functions! The non-path code was synced ported, but still failed 16 path tests, then...

jimtabor at svn.reactos.org jimtabor at svn.reactos.org
Thu Oct 20 12:02:16 UTC 2011


Author: jimtabor
Date: Thu Oct 20 12:02:15 2011
New Revision: 54210

URL: http://svn.reactos.org/svn/reactos?rev=54210&view=rev
Log:
[Win32k]
- Fix path support, now all wine path tests pass.
- Need a PolyDraw test for non-path functions! The non-path code was synced ported, but still failed 16 path tests, then path was moved out. Purged missing patches from the last trunk freeze, tested with the program Area.
- Sync Information:
  Evan Stade <estade at gmail.com> : Improved PolyDraw in path closed case. Added PATH_PolyDraw.

Modified:
    trunk/reactos/subsystems/win32/win32k/include/path.h
    trunk/reactos/subsystems/win32/win32k/objects/line.c
    trunk/reactos/subsystems/win32/win32k/objects/path.c

Modified: trunk/reactos/subsystems/win32/win32k/include/path.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/path.h?rev=54210&r1=54209&r2=54210&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/path.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/path.h [iso-8859-1] Thu Oct 20 12:02:15 2011
@@ -55,6 +55,7 @@
 BOOL FASTCALL PATH_MoveTo (PDC dc);
 BOOL FASTCALL PATH_PolyBezier (PDC dc, const POINT *pts, DWORD cbPoints);
 BOOL FASTCALL PATH_PolyBezierTo (PDC dc, const POINT *pts, DWORD cbPoints);
+BOOL FASTCALL PATH_PolyDraw(PDC dc, const POINT *pts, const BYTE *types, DWORD cbPoints);
 BOOL FASTCALL PATH_Polygon (PDC dc, const POINT *pts, DWORD cbPoints);
 BOOL FASTCALL PATH_Polyline (PDC dc, const POINT *pts, DWORD cbPoints);
 BOOL FASTCALL PATH_PolylineTo (PDC dc, const POINT *pts, DWORD cbPoints);

Modified: trunk/reactos/subsystems/win32/win32k/objects/line.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/line.c?rev=54210&r1=54209&r2=54210&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/line.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/line.c [iso-8859-1] Thu Oct 20 12:02:15 2011
@@ -417,73 +417,110 @@
     IN ULONG cCount)
 {
     PDC dc;
-    PPATH pPath;
+    PDC_ATTR pdcattr;
+    POINT *line_pts = NULL, *line_pts_old, *bzr_pts = NULL, bzr[4];
+    INT i, num_pts, num_bzr_pts, space, space_old, size;
     BOOL result = FALSE;
-    POINT lastmove;
-    unsigned int i;
-    PDC_ATTR pdcattr;
 
     dc = DC_LockDc(hdc);
     if (!dc) return FALSE;
     pdcattr = dc->pdcattr;
 
+    if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+       DC_vUpdateFillBrush(dc);
+
+    if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+       DC_vUpdateLineBrush(dc);
+
+    if (!cCount)
+    {
+       DC_UnlockDc(dc);
+       return TRUE;
+    }
+
     _SEH2_TRY
     {
         ProbeArrayForRead(lppt, sizeof(POINT), cCount, sizeof(LONG));
         ProbeArrayForRead(lpbTypes, sizeof(BYTE), cCount, sizeof(BYTE));
 
-        /* check for each bezierto if there are two more points */
+        if (PATH_IsPathOpen(dc->dclevel))
+        {
+           result = PATH_PolyDraw(dc, (const POINT *)lppt, (const BYTE *)lpbTypes, cCount);
+           _SEH2_LEAVE;
+        }
+
+        /* check for valid point types */
+        for (i = 0; i < cCount; i++)
+        {
+           switch (lpbTypes[i])
+           {
+           case PT_MOVETO:
+           case PT_LINETO | PT_CLOSEFIGURE:
+           case PT_LINETO:
+               break;
+           case PT_BEZIERTO:
+               if((i + 2 < cCount) && (lpbTypes[i + 1] == PT_BEZIERTO) &&
+                  ((lpbTypes[i + 2] & ~PT_CLOSEFIGURE) == PT_BEZIERTO))
+               {
+                   i += 2;
+                   break;
+               }
+           default:
+               _SEH2_LEAVE;
+           }
+        }
+
+        space = cCount + 300;
+        line_pts = ExAllocatePoolWithTag(PagedPool, space * sizeof(POINT), TAG_SHAPE);
+        num_pts = 1;
+
+        line_pts[0].x = pdcattr->ptlCurrent.x;
+        line_pts[0].y = pdcattr->ptlCurrent.y;
+
         for ( i = 0; i < cCount; i++ )
         {
-            if ( lpbTypes[i] != PT_MOVETO &&
-                 lpbTypes[i] & PT_BEZIERTO )
-            {
-                if ( cCount < i+3 ) _SEH2_LEAVE;
-                else i += 2;
-            }
-        }
-
-        /* if no moveto occurs, we will close the figure here */
-        lastmove.x = pdcattr->ptlCurrent.x;
-        lastmove.y = pdcattr->ptlCurrent.y;
-
-        /* now let's draw */
-        for ( i = 0; i < cCount; i++ )
-        {
-            if ( lpbTypes[i] == PT_MOVETO )
-            {
-                IntGdiMoveToEx( dc, lppt[i].x, lppt[i].y, NULL, FALSE );
-                lastmove.x = pdcattr->ptlCurrent.x;
-                lastmove.y = pdcattr->ptlCurrent.y;
-            }
-            else if ( lpbTypes[i] & PT_LINETO )
-                IntGdiLineTo( dc, lppt[i].x, lppt[i].y );
-            else if ( lpbTypes[i] & PT_BEZIERTO )
-            {
-                POINT pts[4];
-                pts[0].x = pdcattr->ptlCurrent.x;
-                pts[0].y = pdcattr->ptlCurrent.y;
-                RtlCopyMemory(pts + 1, &lppt[i], sizeof(POINT) * 3);
-                IntGdiPolyBezier(dc, pts, 4);
-                i += 2;
-            }
-            else _SEH2_LEAVE;
-
-            if ( lpbTypes[i] & PT_CLOSEFIGURE )
-            {
-                if ( PATH_IsPathOpen(dc->dclevel) )
-                {
-                    pPath = PATH_LockPath( dc->dclevel.hPath );
-                    if (pPath)
-                    {
-                       IntGdiCloseFigure( pPath );
-                       PATH_UnlockPath( pPath );
-                    }
-                }
-                else IntGdiLineTo( dc, lastmove.x, lastmove.y );
-            }
-        }
-
+           switch (lpbTypes[i])
+           {
+           case PT_MOVETO:
+               if (num_pts >= 2) IntGdiPolyline( dc, line_pts, num_pts );
+               num_pts = 0;
+               line_pts[num_pts++] = lppt[i];
+               break;
+           case PT_LINETO:
+           case (PT_LINETO | PT_CLOSEFIGURE):
+               line_pts[num_pts++] = lppt[i];
+               break;
+           case PT_BEZIERTO:
+               bzr[0].x = line_pts[num_pts - 1].x;
+               bzr[0].y = line_pts[num_pts - 1].y;
+               RtlCopyMemory( &bzr[1], &lppt[i], 3 * sizeof(POINT) );
+
+               if ((bzr_pts = GDI_Bezier( bzr, 4, &num_bzr_pts )))
+               {
+                   size = num_pts + (cCount - i) + num_bzr_pts;
+                   if (space < size)
+                   {
+                      space_old = space;
+                      space = size * 2;
+                      line_pts_old = line_pts;
+                      line_pts = ExAllocatePoolWithTag(PagedPool, space * sizeof(POINT), TAG_SHAPE);
+                      if (!line_pts) _SEH2_LEAVE;
+                      RtlCopyMemory(line_pts, line_pts_old, space_old * sizeof(POINT));
+                      ExFreePoolWithTag(line_pts_old, TAG_SHAPE);
+                   }
+                   RtlCopyMemory( &line_pts[num_pts], &bzr_pts[1], (num_bzr_pts - 1) * sizeof(POINT) );
+                   num_pts += num_bzr_pts - 1;
+                   ExFreePoolWithTag(bzr_pts, TAG_BEZIER);
+               }
+               i += 2;
+               break;
+           }
+           if (lpbTypes[i] & PT_CLOSEFIGURE) line_pts[num_pts++] = line_pts[0];
+        }
+
+        if (num_pts >= 2) IntGdiPolyline( dc, line_pts, num_pts );
+        IntGdiMoveToEx( dc, line_pts[num_pts - 1].x, line_pts[num_pts - 1].y, NULL, TRUE );
+        ExFreePoolWithTag(line_pts, TAG_SHAPE);
         result = TRUE;
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@@ -497,8 +534,8 @@
     return result;
 }
 
- /*
- * @unimplemented
+/*
+ * @implemented
  */
 BOOL
 APIENTRY
@@ -508,8 +545,32 @@
     IN INT y,
     OUT OPTIONAL LPPOINT pptOut)
 {
-    UNIMPLEMENTED;
-    return FALSE;
+    PDC dc;
+    BOOL Ret;
+    POINT Point;
+
+    dc = DC_LockDc(hdc);
+    if (!dc) return FALSE;
+
+    Ret = IntGdiMoveToEx(dc, x, y, &Point, TRUE);
+
+    if (pptOut)
+    {
+       _SEH2_TRY
+       {
+           ProbeForWrite( pptOut, sizeof(POINT), 1);
+           RtlCopyMemory( pptOut, &Point, sizeof(POINT));
+       }
+       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+       {
+           SetLastNtError(_SEH2_GetExceptionCode());
+           Ret = FALSE;
+       }
+       _SEH2_END;
+    }
+    DC_UnlockDc(dc);
+
+    return Ret;
 }
 
 /* EOF */

Modified: trunk/reactos/subsystems/win32/win32k/objects/path.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/path.c?rev=54210&r1=54209&r2=54210&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/path.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/path.c [iso-8859-1] Thu Oct 20 12:02:15 2011
@@ -62,6 +62,18 @@
       pPath->pFlags[pPath->numEntriesUsed-1]|=PT_CLOSEFIGURE;
       pPath->newStroke=TRUE;
    }
+}
+
+/* MSDN: This fails if the device coordinates exceed 27 bits, or if the converted
+         logical coordinates exceed 32 bits. */
+BOOL
+FASTCALL
+GdiPathDPtoLP(PDC pdc, PPOINT ppt, INT count)
+{
+  XFORMOBJ xo;
+   
+  XFORMOBJ_vInit(&xo, &pdc->dclevel.mxDeviceToWorld);
+  return XFORMOBJ_bApplyXform(&xo, XF_LTOL, count, (PPOINTL)ppt, (PPOINTL)ppt);
 }
 
 /* PATH_FillPath
@@ -722,6 +734,103 @@
 
 BOOL
 FASTCALL
+PATH_PolyDraw(PDC dc, const POINT *pts, const BYTE *types, DWORD cbPoints)
+{
+  PPATH pPath;
+  POINT lastmove, orig_pos;
+  INT i;
+  PDC_ATTR pdcattr;
+  BOOL State = FALSE, Ret = FALSE;
+
+  pPath = PATH_LockPath( dc->dclevel.hPath );
+  if (!pPath) return FALSE;
+
+  if ( pPath->state != PATH_Open )
+  {
+    PATH_UnlockPath( pPath );
+    return FALSE;
+  }
+
+  pdcattr = dc->pdcattr;  
+
+  lastmove.x = orig_pos.x = pdcattr->ptlCurrent.x;
+  lastmove.y = orig_pos.y = pdcattr->ptlCurrent.y;
+
+  for (i = pPath->numEntriesUsed - 1; i >= 0; i--)
+  {
+      if (pPath->pFlags[i] == PT_MOVETO)
+      {
+         lastmove.x = pPath->pPoints[i].x;
+         lastmove.y = pPath->pPoints[i].y;
+         if (!GdiPathDPtoLP(dc, &lastmove, 1))
+         {
+            PATH_UnlockPath( pPath );
+            return FALSE;
+         }
+         break;
+       }
+  }
+
+  for (i = 0; i < cbPoints; i++)
+  {
+      if (types[i] == PT_MOVETO)
+      {
+                pPath->newStroke = TRUE;
+                lastmove.x = pts[i].x;
+                lastmove.y = pts[i].y;
+      }
+      else if((types[i] & ~PT_CLOSEFIGURE) == PT_LINETO)
+      {
+                PATH_LineTo(dc, pts[i].x, pts[i].y);
+      }
+      else if(types[i] == PT_BEZIERTO)
+      {
+          if (!((i + 2 < cbPoints) && (types[i + 1] == PT_BEZIERTO)
+              && ((types[i + 2] & ~PT_CLOSEFIGURE) == PT_BEZIERTO)))
+              goto err;
+          PATH_PolyBezierTo(dc, &(pts[i]), 3);
+          i += 2;
+      }
+      else
+         goto err;
+
+     pdcattr->ptlCurrent.x = pts[i].x;
+     pdcattr->ptlCurrent.y = pts[i].y;
+     State = TRUE;
+
+     if (types[i] & PT_CLOSEFIGURE)
+     {
+        pPath->pFlags[pPath->numEntriesUsed-1] |= PT_CLOSEFIGURE;
+        pPath->newStroke = TRUE;
+        pdcattr->ptlCurrent.x = lastmove.x;
+        pdcattr->ptlCurrent.y = lastmove.y;
+        State = TRUE;
+     }
+  }
+  Ret = TRUE;
+  goto Exit;
+
+err:
+  if ((pdcattr->ptlCurrent.x != orig_pos.x) || (pdcattr->ptlCurrent.y != orig_pos.y))
+  {
+     pPath->newStroke = TRUE;
+     pdcattr->ptlCurrent.x = orig_pos.x;
+     pdcattr->ptlCurrent.y = orig_pos.y;
+     State = TRUE;
+  }
+Exit:
+  if (State) // State change?
+  {
+     pdcattr->ptfxCurrent = pdcattr->ptlCurrent;
+     CoordLPtoDP(dc, &pdcattr->ptfxCurrent); // Update fx
+     pdcattr->ulDirty_ &= ~(DIRTY_PTLCURRENT|DIRTY_PTFXCURRENT|DIRTY_STYLESTATE);
+  }
+  PATH_UnlockPath( pPath );
+  return Ret;
+}
+
+BOOL
+FASTCALL
 PATH_Polyline ( PDC dc, const POINT *pts, DWORD cbPoints )
 {
   POINT   pt;
@@ -1467,7 +1576,7 @@
 FASTCALL
 PATH_WidenPath(DC *dc)
 {
-    INT i, j, numStrokes, penWidth, penWidthIn, penWidthOut, size, penStyle;
+    INT i, j, numStrokes, numOldStrokes, penWidth, penWidthIn, penWidthOut, size, penStyle;
     BOOL ret = FALSE;
     PPATH pPath, pNewPath, *pStrokes = NULL, *pOldStrokes, pUpPath, pDownPath;
     EXTLOGPEN *elp;
@@ -1554,6 +1663,7 @@
                 {
                     pStrokes[numStrokes - 1]->state = PATH_Closed;
                 }
+                numOldStrokes = numStrokes;
                 numStrokes++;
                 j = 0;
                 if (numStrokes == 1)
@@ -1563,7 +1673,7 @@
                    pOldStrokes = pStrokes; // Save old pointer.
                    pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH);
                    if (!pStrokes) return FALSE;
-                   RtlCopyMemory(pStrokes, pOldStrokes, numStrokes * sizeof(PPATH));
+                   RtlCopyMemory(pStrokes, pOldStrokes, numOldStrokes * sizeof(PPATH));
                    ExFreePoolWithTag(pOldStrokes, TAG_PATH); // Free old pointer.
                 }
                 if (!pStrokes) return FALSE;
@@ -2392,7 +2502,11 @@
          memcpy(Types, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed);
 
          /* Convert the points to logical coordinates */
-         IntDPtoLP(dc, Points, pPath->numEntriesUsed);
+         if (!GdiPathDPtoLP(dc, Points, pPath->numEntriesUsed))
+         {
+            EngSetLastError(ERROR_ARITHMETIC_OVERFLOW);
+            _SEH2_LEAVE;
+         }
 
          ret = pPath->numEntriesUsed;
       }




More information about the Ros-diffs mailing list