[1/2] gdiplus: implemented GdipReversePath with tests

Nikolay Sivov bunglehead at gmail.com
Mon Aug 4 12:45:05 CDT 2008


Changelog:
    - implemented GdipReversePath with tests

---
 dlls/gdiplus/gdiplus.spec         |    2 +-
 dlls/gdiplus/graphicspath.c       |   54 +++++++++++++++++++++++++++++++++++++
 dlls/gdiplus/tests/graphicspath.c |   44 ++++++++++++++++++++++++++++++
 include/gdiplusflat.h             |    1 +
 4 files changed, 100 insertions(+), 1 deletions(-)

diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec
index 18e7eeb..add7b0e 100644
--- a/dlls/gdiplus/gdiplus.spec
+++ b/dlls/gdiplus/gdiplus.spec
@@ -484,7 +484,7 @@
 @ stub GdipResetTextureTransform
 @ stub GdipResetWorldTransform
 @ stdcall GdipRestoreGraphics(ptr long)
-@ stub GdipReversePath
+@ stdcall GdipReversePath(ptr)
 @ stub GdipRotateLineTransform
 @ stdcall GdipRotateMatrix(ptr long long)
 @ stub GdipRotatePathGradientTransform
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c
index 136afe7..c5925b6 100644
--- a/dlls/gdiplus/graphicspath.c
+++ b/dlls/gdiplus/graphicspath.c
@@ -927,6 +927,60 @@ GpStatus WINGDIPAPI GdipGetPointCount(GpPath *path, INT *count)
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipReversePath(GpPath* path)
+{
+    INT i, count;
+    INT start = 0; /* position in reversed path */
+    GpPathData revpath;
+
+    if(!path)
+        return InvalidParameter;
+
+    count = path->pathdata.Count;
+
+    if(count == 0) return Ok;
+
+    revpath.Points = GdipAlloc(sizeof(GpPointF)*count);
+    revpath.Types  = GdipAlloc(sizeof(BYTE)*count);
+    revpath.Count  = count;
+    if(!revpath.Points || !revpath.Types){
+        GdipFree(revpath.Points);
+        GdipFree(revpath.Types);
+        return OutOfMemory;
+    }
+
+    for(i = 0; i < count; i++){
+
+        /* find next start point */
+        if(path->pathdata.Types[count-i-1] == PathPointTypeStart){
+            INT j;
+            for(j = start; j <= i; j++){
+                revpath.Points[j] = path->pathdata.Points[count-j-1];
+                revpath.Types[j] = path->pathdata.Types[count-j-1];
+            }
+            /* mark start point */
+            revpath.Types[start] = PathPointTypeStart;
+            /* set 'figure' endpoint type */
+            if(i-start > 1){
+                revpath.Types[i] = path->pathdata.Types[count-start-1] & ~PathPointTypePathTypeMask;
+                revpath.Types[i] |= revpath.Types[i-1];
+            }
+            else
+                revpath.Types[i] = path->pathdata.Types[start];
+
+            start = i+1;
+        }
+    }
+
+    memcpy(path->pathdata.Points, revpath.Points, sizeof(GpPointF)*count);
+    memcpy(path->pathdata.Types,  revpath.Types,  sizeof(BYTE)*count);
+
+    GdipFree(revpath.Points);
+    GdipFree(revpath.Types);
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPointI(GpPath* path, INT x, INT y,
     GpPen *pen, GpGraphics *graphics, BOOL *result)
 {
diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c
index eb7e2de..97e92fa 100644
--- a/dlls/gdiplus/tests/graphicspath.c
+++ b/dlls/gdiplus/tests/graphicspath.c
@@ -813,6 +813,49 @@ static void test_addclosedcurve(void)
     GdipDeletePath(path);
 }
 
+static path_test_t reverse_path[] = {
+    {0.0,  20.0, PathPointTypeStart, 0, 0}, /*0*/
+    {25.0, 25.0, PathPointTypeLine,  0, 0}, /*1*/
+    {0.0,  30.0, PathPointTypeLine,  0, 0}, /*2*/
+    {15.0, 35.0, PathPointTypeStart, 0, 0}, /*3*/
+    {0.0,  40.0, PathPointTypeLine,  0, 0}, /*4*/
+    {5.0,  45.0, PathPointTypeLine,  0, 0}, /*5*/
+    {0.0,  50.0, PathPointTypeLine | PathPointTypeCloseSubpath, 0, 0}  /*6*/
+    };
+
+static void test_reverse(void)
+{
+    GpStatus status;
+    GpPath *path;
+    GpPointF pts[7];
+    INT i;
+
+    for(i = 0; i < 7; i++){
+        pts[i].X = i * 5.0 * (REAL)(i % 2);
+        pts[i].Y = 50.0 - i * 5.0;
+    }
+
+    GdipCreatePath(FillModeAlternate, &path);
+
+    /* NULL argument */
+    status = GdipReversePath(NULL);
+    expect(InvalidParameter, status);
+
+    /* empty path */
+    status = GdipReversePath(path);
+    expect(Ok, status);
+
+    GdipAddPathLine2(path, pts, 4);
+    GdipClosePathFigure(path);
+    GdipAddPathLine2(path, &(pts[4]), 3);
+
+    status = GdipReversePath(path);
+    expect(Ok, status);
+    ok_path(path, reverse_path, sizeof(reverse_path)/sizeof(path_test_t), FALSE);
+
+    GdipDeletePath(path);
+}
+
 START_TEST(graphicspath)
 {
     struct GdiplusStartupInput gdiplusStartupInput;
@@ -838,6 +881,7 @@ START_TEST(graphicspath)
     test_lastpoint();
     test_addcurve();
     test_addclosedcurve();
+    test_reverse();
 
     GdiplusShutdown(gdiplusToken);
 }
diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h
index dc938ac..4203e16 100644
--- a/include/gdiplusflat.h
+++ b/include/gdiplusflat.h
@@ -291,6 +291,7 @@ GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPointI(GpPath*,INT,INT,GpPen*,
 GpStatus WINGDIPAPI GdipIsVisiblePathPoint(GpPath*,REAL,REAL,GpGraphics*,BOOL*);
 GpStatus WINGDIPAPI GdipIsVisiblePathPointI(GpPath*,INT,INT,GpGraphics*,BOOL*);
 GpStatus WINGDIPAPI GdipResetPath(GpPath*);
+GpStatus WINGDIPAPI GdipReversePath(GpPath*);
 GpStatus WINGDIPAPI GdipSetPathFillMode(GpPath*,GpFillMode);
 GpStatus WINGDIPAPI GdipStartPathFigure(GpPath*);
 GpStatus WINGDIPAPI GdipTransformPath(GpPath*,GpMatrix*);
-- 
1.4.4.4






More information about the wine-patches mailing list