[2/3] gdi32: added PATH_PolyDraw [try7]

Evan Stade estade at gmail.com
Mon Jul 16 21:45:28 CDT 2007


Hi,

[try7] PolyDraw uses same logic as other drawing functions, that is:

if( PATH_IsPathOpen( dc->path ) ) ...
else if(dc->funcs->pPolyDraw) ...
else ...

 dlls/gdi32/gdi_private.h |    1 +
 dlls/gdi32/painting.c    |   14 ++++------
 dlls/gdi32/path.c        |   67 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/gdi32/tests/path.c  |   28 +++++++++----------
 4 files changed, 87 insertions(+), 23 deletions(-)

-- 
Evan Stade
-------------- next part --------------
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index c6810dd..73627d7 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -481,6 +481,7 @@ extern BOOL PATH_Arc(DC *dc, INT x1, INT
                      INT xStart, INT yStart, INT xEnd, INT yEnd, INT lines);
 extern BOOL PATH_PolyBezierTo(DC *dc, const POINT *pt, DWORD cbCount);
 extern BOOL PATH_PolyBezier(DC *dc, const POINT *pt, DWORD cbCount);
+extern BOOL PATH_PolyDraw(DC *dc, const POINT *pts, const BYTE *types, DWORD cbCount);
 extern BOOL PATH_PolylineTo(DC *dc, const POINT *pt, DWORD cbCount);
 extern BOOL PATH_Polyline(DC *dc, const POINT *pt, DWORD cbCount);
 extern BOOL PATH_Polygon(DC *dc, const POINT *pt, DWORD cbCount);
diff --git a/dlls/gdi32/painting.c b/dlls/gdi32/painting.c
index 4a8b8c9..ed3f9b0 100644
--- a/dlls/gdi32/painting.c
+++ b/dlls/gdi32/painting.c
@@ -830,12 +830,11 @@ BOOL WINAPI PolyDraw(HDC hdc, const POIN
     dc = DC_GetDCUpdate( hdc );
     if(!dc) return FALSE;
 
-    if(dc->funcs->pPolyDraw)
-    {
+    if( PATH_IsPathOpen( dc->path ) )
+        result = PATH_PolyDraw(dc, lppt, lpbTypes, cCount);
+    else if(dc->funcs->pPolyDraw)
         result = dc->funcs->pPolyDraw( dc->physDev, lppt, lpbTypes, cCount );
-        goto end;
-    }
-
+    else {
     /* check for each bezierto if there are two more points */
     for( i = 0; i < cCount; i++ )
 	if( lpbTypes[i] != PT_MOVETO &&
@@ -872,14 +871,13 @@ BOOL WINAPI PolyDraw(HDC hdc, const POIN
 
 	if( lpbTypes[i] & PT_CLOSEFIGURE )
 	{
-	    if( PATH_IsPathOpen( dc->path ) )
-		CloseFigure( hdc );
-	    else
 		LineTo( hdc, lastmove.x, lastmove.y );
 	}
     }
 
     result = TRUE;
+    }
+
 end:
     GDI_ReleaseObj( hdc );
     return result;
diff --git a/dlls/gdi32/path.c b/dlls/gdi32/path.c
index 1a37adc..7de7385 100644
--- a/dlls/gdi32/path.c
+++ b/dlls/gdi32/path.c
@@ -933,6 +933,73 @@ BOOL PATH_PolyBezier(DC *dc, const POINT
    return TRUE;
 }
 
+/* PATH_PolyDraw
+ *
+ * Should be called when a call to PolyDraw is performed on a DC that has
+ * an open path. Returns TRUE if successful, else FALSE.
+ */
+BOOL PATH_PolyDraw(DC *dc, const POINT *pts, const BYTE *types,
+    DWORD cbPoints)
+{
+        GdiPath     *pPath = &dc->path;
+        POINT       lastmove, orig_pos;
+        INT         i;
+
+        lastmove.x = orig_pos.x = dc->CursPosX;
+        lastmove.y = orig_pos.y = dc->CursPosY;
+
+        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(!DPtoLP(dc->hSelf, &lastmove, 1))
+                    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;
+
+            dc->CursPosX = pts[i].x;
+            dc->CursPosY = pts[i].y;
+
+            if(types[i] & PT_CLOSEFIGURE){
+                pPath->pFlags[pPath->numEntriesUsed-1] |= PT_CLOSEFIGURE;
+                pPath->newStroke = TRUE;
+                dc->CursPosX = lastmove.x;
+                dc->CursPosY = lastmove.y;
+            }
+        }
+
+        return TRUE;
+
+err:
+        if((dc->CursPosX != orig_pos.x) || (dc->CursPosY != orig_pos.y)){
+            pPath->newStroke = TRUE;
+            dc->CursPosX = orig_pos.x;
+            dc->CursPosY = orig_pos.y;
+        }
+
+        return FALSE;
+}
+
 BOOL PATH_Polyline(DC *dc, const POINT *pts, DWORD cbPoints)
 {
    GdiPath     *pPath = &dc->path;
diff --git a/dlls/gdi32/tests/path.c b/dlls/gdi32/tests/path.c
index 6e256c7..9f08ea4 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, PT_LINETO, 0, 0}, /*4*/
     {10, 10, PT_LINETO, 0, 0}, /*5*/
     {10, 15, PT_LINETO | PT_CLOSEFIGURE, 0, 0}, /*6*/
-    {100, 100, PT_MOVETO, 0, 1}, /*7*/
+    {100, 100, PT_MOVETO, 0, 0}, /*7*/
     {15, 15, PT_LINETO, 0, 0}, /*8*/
-    {25, 25, PT_MOVETO, 0, 1}, /*9*/
-    {25, 30, PT_LINETO, 0, 1}, /*10*/
-    {100, 100, PT_MOVETO, 0, 1}, /*11*/
+    {25, 25, PT_MOVETO, 0, 0}, /*9*/
+    {25, 30, PT_LINETO, 0, 0}, /*10*/
+    {100, 100, PT_MOVETO, 0, 0}, /*11*/
     {30, 30, PT_BEZIERTO, 0, 0}, /*12*/
     {30, 35, PT_BEZIERTO, 0, 0}, /*13*/
     {35, 35, PT_BEZIERTO, 0, 0}, /*14*/
     {35, 40, PT_LINETO, 0, 0}, /*15*/
     {40, 40, PT_MOVETO, 0, 0}, /*16*/
     {40, 45, PT_LINETO, 0, 0}, /*17*/
-    {35, 40, PT_MOVETO, 0, 1}, /*18*/
-    {45, 50, PT_LINETO, 0, 1}, /*19*/
-    {35, 40, PT_MOVETO, 0, 1}, /*20*/
+    {35, 40, PT_MOVETO, 0, 0}, /*18*/
+    {45, 50, PT_LINETO, 0, 0}, /*19*/
+    {35, 40, PT_MOVETO, 0, 0}, /*20*/
     {50, 55, PT_LINETO, 0, 0}, /*21*/
     {45, 50, PT_LINETO, 0, 0}, /*22*/
-    {35, 40, PT_MOVETO, 0, 1}, /*23*/
-    {60, 60, PT_LINETO, 0, 1}, /*24*/
-    {60, 65, PT_MOVETO, 0, 1}, /*25*/
+    {35, 40, PT_MOVETO, 0, 0}, /*23*/
+    {60, 60, PT_LINETO, 0, 0}, /*24*/
+    {60, 65, PT_MOVETO, 0, 0}, /*25*/
     {65, 65, PT_LINETO, 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