[2/2] gdi32: fixed PolyDraw for open path case [try3]

Evan Stade estade at gmail.com
Fri Jun 29 19:57:19 CDT 2007


Hi,

[try3] In the interest of keeping this patch as small as possible, it
does not include my fix for PolyDraw in the path closed case.  Thus
PolyDraw is still broken when called on a DC with no open path.
However, it is only half as broken as before.

Also, PolyDraw no longer access members of the path structure.  I
added a method to path.c to take care of that.

Changelog:
* added PATH_GetCurrentFigure to return coordinates of last PT_MOVETO
in the path.
* added changes to PolyDraw, that correct its behaviour when drawing
on a dc with an open path.  The following were broken:
- type equality checks
- handling of bad point types
- handling of closefigure

 dlls/gdi32/gdi_private.h |    1 +
 dlls/gdi32/painting.c    |   61 +++++++++++++++++++++++++++++++++++++++++++++-
 dlls/gdi32/path.c        |   22 +++++++++++++++++
 dlls/gdi32/tests/path.c  |   28 ++++++++++-----------
 4 files changed, 96 insertions(+), 16 deletions(-)

-- 
Evan Stade
-------------- next part --------------
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index c6810dd..c8bf207 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -488,6 +488,7 @@ extern BOOL PATH_PolyPolyline(DC *dc, co
 extern BOOL PATH_PolyPolygon(DC *dc, const POINT *pt, const INT *counts, UINT polygons);
 extern BOOL PATH_RoundRect(DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_width, INT ell_height);
 extern BOOL PATH_AddEntry(GdiPath *pPath, const POINT *pPoint, BYTE flags);
+extern BOOL PATH_GetCurrentFigure(const GdiPath *pPath, POINT *point);
 
 /* painting.c */
 extern POINT *GDI_Bezier( const POINT *Points, INT count, INT *nPtsOut );
diff --git a/dlls/gdi32/painting.c b/dlls/gdi32/painting.c
index 1b30d6d..5b6a561 100644
--- a/dlls/gdi32/painting.c
+++ b/dlls/gdi32/painting.c
@@ -824,7 +824,7 @@ BOOL WINAPI PolyDraw(HDC hdc, const POIN
 {
     DC *dc;
     BOOL result;
-    POINT lastmove;
+    POINT lastmove, orig_pos;
     unsigned int i;
 
     dc = DC_GetDCUpdate( hdc );
@@ -838,6 +838,65 @@ BOOL WINAPI PolyDraw(HDC hdc, const POIN
     }
     GDI_ReleaseObj( hdc );
 
+    if( PATH_IsPathOpen( dc->path ) ){
+        lastmove.x = orig_pos.x = dc->CursPosX;
+        lastmove.y = orig_pos.y = dc->CursPosY;
+
+        PATH_GetCurrentFigure(&(dc->path), &lastmove);
+
+        /* now let's draw */
+        for( i = 0; i < cCount; i++ )
+        {
+            if( (lpbTypes[i] & PT_MOVETO) == PT_MOVETO)
+            {
+                if(lpbTypes[i] & PT_CLOSEFIGURE)
+                {
+                    goto err;
+                }
+
+                MoveToEx( hdc, lppt[i].x, lppt[i].y, NULL );
+                lastmove.x = dc->CursPosX;
+                lastmove.y = dc->CursPosY;
+            }
+            else if( (lpbTypes[i] & PT_LINETO ) == PT_LINETO)
+                LineTo( hdc, lppt[i].x, lppt[i].y );
+            else if( (lpbTypes[i] & PT_BEZIERTO ) == PT_BEZIERTO)
+            {
+                if(!((i + 2 < cCount) &&
+                    (lpbTypes[i + 1] == PT_BEZIERTO)
+                    && ((lpbTypes[i + 2] & ~PT_CLOSEFIGURE) == PT_BEZIERTO)))
+                {
+                    goto err;
+                }
+                PolyBezierTo( hdc, &lppt[i], 3 );
+                i += 2;
+                if(lpbTypes[i] & PT_CLOSEFIGURE)
+                {
+                    CloseFigure( hdc );
+                    MoveToEx( hdc, lastmove.x, lastmove.y, NULL );
+                }
+            }
+            else
+            {
+                goto err;
+            }
+
+            if( lpbTypes[i] & PT_CLOSEFIGURE )
+            {
+                CloseFigure( hdc );
+                MoveToEx( hdc, lastmove.x, lastmove.y, NULL );
+            }
+        }
+
+        return TRUE;
+
+err:
+        if((dc->CursPosX != orig_pos.x) || (dc->CursPosY != orig_pos.y))
+            MoveToEx( hdc, orig_pos.x, orig_pos.y, NULL );
+
+        return FALSE;
+    }
+
     /* check for each bezierto if there are two more points */
     for( i = 0; i < cCount; i++ )
 	if( lpbTypes[i] != PT_MOVETO &&
diff --git a/dlls/gdi32/path.c b/dlls/gdi32/path.c
index 1a37adc..399919a 100644
--- a/dlls/gdi32/path.c
+++ b/dlls/gdi32/path.c
@@ -1467,6 +1467,28 @@ BOOL PATH_AddEntry(GdiPath *pPath, const
    return TRUE;
 }
 
+/* PATH_AddEntry
+ *
+ * Finds the location of the last PT_MOVETO.
+ * Returns false if it can find no PT_MOVETO, true otherwise.
+ */
+BOOL PATH_GetCurrentFigure(const GdiPath *pPath, POINT *point)
+{
+    INT i;
+
+    assert((pPath != NULL) && (point != NULL));
+
+    for( i = pPath->numEntriesUsed-1; i >= 0; i-- ){
+        if(pPath->pFlags[i] == PT_MOVETO){
+            point->x = pPath->pPoints[i].x;
+            point->y = pPath->pPoints[i].y;
+            return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
 /* PATH_ReserveEntries
  *
  * Ensures that at least "numEntries" entries (for points and flags) have
diff --git a/dlls/gdi32/tests/path.c b/dlls/gdi32/tests/path.c
index fee9ad3..0baad4a 100644
--- a/dlls/gdi32/tests/path.c
+++ b/dlls/gdi32/tests/path.c
@@ -301,25 +301,25 @@ static const path_test_t polydraw_path[]
     {95, 95, 2, 0, 0}, /*4*/
     {10, 10, 2, 0, 0}, /*5*/
     {10, 15, 3, 0, 0}, /*6*/
-    {100, 100, 6, 0, 1}, /*7*/
+    {100, 100, 6, 0, 0}, /*7*/
     {15, 15, 2, 0, 0}, /*8*/
-    {25, 25, 6, 0, 1}, /*9*/
-    {25, 30, 2, 0, 1}, /*10*/
-    {100, 100, 6, 0, 1}, /*11*/
+    {25, 25, 6, 0, 0}, /*9*/
+    {25, 30, 2, 0, 0}, /*10*/
+    {100, 100, 6, 0, 0}, /*11*/
     {30, 30, 4, 0, 0}, /*12*/
     {30, 35, 4, 0, 0}, /*13*/
     {35, 35, 4, 0, 0}, /*14*/
     {35, 40, 2, 0, 0}, /*15*/
     {40, 40, 6, 0, 0}, /*16*/
     {40, 45, 2, 0, 0}, /*17*/
-    {35, 40, 6, 0, 1}, /*18*/
-    {45, 50, 2, 0, 1}, /*19*/
-    {35, 40, 6, 0, 1}, /*20*/
+    {35, 40, 6, 0, 0}, /*18*/
+    {45, 50, 2, 0, 0}, /*19*/
+    {35, 40, 6, 0, 0}, /*20*/
     {50, 55, 2, 0, 0}, /*21*/
     {45, 50, 2, 0, 0}, /*22*/
-    {35, 40, 6, 0, 1}, /*23*/
-    {60, 60, 2, 0, 1}, /*24*/
-    {60, 65, 6, 0, 1}, /*25*/
+    {35, 40, 6, 0, 0}, /*23*/
+    {60, 60, 2, 0, 0}, /*24*/
+    {60, 65, 6, 0, 0}, /*25*/
     {65, 65, 2, 0, 0}, /*26*/
     };
 
@@ -366,8 +366,7 @@ static void test_polydraw(void)
     expect(TRUE, retb);
     /* bad bezier points */
     retb = PolyDraw(hdc, &(polydraw_pts[2]), &(polydraw_tps[2]), 4);
-    todo_wine
-        expect(FALSE, retb);
+    expect(FALSE, retb);
     retb = PolyDraw(hdc, &(polydraw_pts[6]), &(polydraw_tps[6]), 4);
     expect(FALSE, retb);
     /* good bezier points */
@@ -378,8 +377,7 @@ static void test_polydraw(void)
     expect(FALSE, retb);
     /* bad point type, has already moved cursor position */
     retb = PolyDraw(hdc, &(polydraw_pts[15]), &(polydraw_tps[15]), 4);
-    todo_wine
-        expect(FALSE, retb);
+    expect(FALSE, retb);
     /* bad point type, cursor position is moved, but back to its original spot */
     retb = PolyDraw(hdc, &(polydraw_pts[17]), &(polydraw_tps[17]), 4);
     expect(FALSE, retb);
@@ -388,7 +386,7 @@ static void test_polydraw(void)
     expect(TRUE, retb);
 
     EndPath(hdc);
-    ok_path(hdc, "polydraw_path", polydraw_path, sizeof(polydraw_path)/sizeof(path_test_t), 1);
+    ok_path(hdc, "polydraw_path", polydraw_path, sizeof(polydraw_path)/sizeof(path_test_t), 0);
 done:
     ReleaseDC(0, hdc);
 }
-- 
1.4.1


More information about the wine-patches mailing list