From 169140cc83b9604e5ab23f711183847e7e2e3c35 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Sun, 3 Aug 2008 02:45:06 +0400 Subject: [PATCH] gdiplus: Implemented GdipAddPathCurve2 with tests. --- dlls/gdiplus/gdiplus.spec | 2 +- dlls/gdiplus/graphicspath.c | 51 +++++++++++++++++++++++++++++ dlls/gdiplus/tests/graphicspath.c | 69 +++++++++++++++++++++++++++++++++++++++ include/gdiplusflat.h | 1 + 4 files changed, 122 insertions(+), 1 deletion(-) diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec index eeda4bef1e4..976bd3aa13a 100644 --- a/dlls/gdiplus/gdiplus.spec +++ b/dlls/gdiplus/gdiplus.spec @@ -8,7 +8,7 @@ @ stub GdipAddPathClosedCurve2I @ stub GdipAddPathClosedCurve @ stub GdipAddPathClosedCurveI -@ stub GdipAddPathCurve2 +@ stdcall GdipAddPathCurve2(ptr ptr long long) @ stub GdipAddPathCurve2I @ stub GdipAddPathCurve3 @ stub GdipAddPathCurve3I diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 75f89d4be8a..bf580b0775b 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -196,6 +196,57 @@ GpStatus WINGDIPAPI GdipAddPathBeziersI(GpPath *path, GDIPCONST GpPoint *points, return ret; } +GpStatus WINGDIPAPI GdipAddPathCurve2(GpPath *path, GDIPCONST GpPointF *points, INT count, + REAL tension) +{ + INT i, len_pt = count*3-2; + GpPointF *pt; + REAL x1, x2, y1, y2; + GpStatus stat; + + if(!path || !points || count <= 1) + return InvalidParameter; + + pt = GdipAlloc(len_pt * sizeof(GpPointF)); + if(!pt) + return OutOfMemory; + + tension = tension * TENSION_CONST; + + calc_curve_bezier_endp(points[0].X, points[0].Y, points[1].X, points[1].Y, + tension, &x1, &y1); + + pt[0].X = points[0].X; + pt[0].Y = points[0].Y; + pt[1].X = x1; + pt[1].Y = y1; + + for(i = 0; i < count-2; i++){ + calc_curve_bezier(&(points[i]), tension, &x1, &y1, &x2, &y2); + + pt[3*i+2].X = x1; + pt[3*i+2].Y = y1; + pt[3*i+3].X = points[i+1].X; + pt[3*i+3].Y = points[i+1].Y; + pt[3*i+4].X = x2; + pt[3*i+4].Y = y2; + } + + calc_curve_bezier_endp(points[count-1].X, points[count-1].Y, + points[count-2].X, points[count-2].Y, tension, &x1, &y1); + + pt[len_pt-2].X = x1; + pt[len_pt-2].Y = y1; + pt[len_pt-1].X = points[count-1].X; + pt[len_pt-1].Y = points[count-1].Y; + + stat = GdipAddPathBeziers(path, pt, len_pt); + + GdipFree(pt); + + return stat; +} + GpStatus WINGDIPAPI GdipAddPathEllipse(GpPath *path, REAL x, REAL y, REAL width, REAL height) { diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index 9f9af9cd50c..7af18147453 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -696,6 +696,74 @@ static void test_lastpoint(void) GdipDeletePath(path); } +static path_test_t addcurve_path[] = { + {0.0, 0.0, PathPointTypeStart, 0, 0}, /*0*/ + {3.3, 3.3, PathPointTypeBezier, 0, 0}, /*1*/ + {6.7, 3.3, PathPointTypeBezier, 0, 0}, /*2*/ + {10.0, 10.0, PathPointTypeBezier, 0, 0}, /*3*/ + {13.3, 16.7, PathPointTypeBezier, 0, 0}, /*4*/ + {3.3, 20.0, PathPointTypeBezier, 0, 0}, /*5*/ + {10.0, 20.0, PathPointTypeBezier, 0, 0}, /*6*/ + {16.7, 20.0, PathPointTypeBezier, 0, 0}, /*7*/ + {23.3, 13.3, PathPointTypeBezier, 0, 0}, /*8*/ + {30.0, 10.0, PathPointTypeBezier, 0, 0} /*9*/ + }; +static path_test_t addcurve_path2[] = { + {100.0,120.0,PathPointTypeStart, 0, 0}, /*0*/ + {123.0,10.0, PathPointTypeLine, 0, 0}, /*1*/ + {0.0, 0.0, PathPointTypeLine, 0, 0}, /*2*/ + {3.3, 3.3, PathPointTypeBezier, 0, 0}, /*3*/ + {6.7, 3.3, PathPointTypeBezier, 0, 0}, /*4*/ + {10.0, 10.0, PathPointTypeBezier, 0, 0}, /*5*/ + {13.3, 16.7, PathPointTypeBezier, 0, 0}, /*6*/ + {3.3, 20.0, PathPointTypeBezier, 0, 0}, /*7*/ + {10.0, 20.0, PathPointTypeBezier, 0, 0}, /*8*/ + {16.7, 20.0, PathPointTypeBezier, 0, 0}, /*9*/ + {23.3, 13.3, PathPointTypeBezier, 0, 0}, /*10*/ + {30.0, 10.0, PathPointTypeBezier, 0, 0} /*11*/ + }; +static void test_addcurve(void) +{ + GpStatus status; + GpPath *path; + GpPointF points[4]; + + points[0].X = 0.0; + points[0].Y = 0.0; + points[1].X = 10.0; + points[1].Y = 10.0; + points[2].X = 10.0; + points[2].Y = 20.0; + points[3].X = 30.0; + points[3].Y = 10.0; + + GdipCreatePath(FillModeAlternate, &path); + + /* NULL args */ + status = GdipAddPathCurve2(NULL, NULL, 0, 0.0); + expect(InvalidParameter, status); + status = GdipAddPathCurve2(path, NULL, 0, 0.0); + expect(InvalidParameter, status); + status = GdipAddPathCurve2(path, points, -1, 0.0); + expect(InvalidParameter, status); + status = GdipAddPathCurve2(path, points, 1, 1.0); + expect(InvalidParameter, status); + + /* add to empty path */ + status = GdipAddPathCurve2(path, points, 4, 1.0); + expect(Ok, status); + ok_path(path, addcurve_path, sizeof(addcurve_path)/sizeof(path_test_t), FALSE); + GdipDeletePath(path); + + /* add to notempty path and opened figure */ + GdipCreatePath(FillModeAlternate, &path); + GdipAddPathLine(path, 100.0, 120.0, 123.0, 10.0); + status = GdipAddPathCurve2(path, points, 4, 1.0); + expect(Ok, status); + ok_path(path, addcurve_path2, sizeof(addcurve_path2)/sizeof(path_test_t), FALSE); + GdipDeletePath(path); +} + START_TEST(graphicspath) { struct GdiplusStartupInput gdiplusStartupInput; @@ -719,6 +787,7 @@ START_TEST(graphicspath) test_rect(); test_polygon(); test_lastpoint(); + test_addcurve(); GdiplusShutdown(gdiplusToken); } diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h index 4293f6429e2..2928500058e 100644 --- a/include/gdiplusflat.h +++ b/include/gdiplusflat.h @@ -246,6 +246,7 @@ GpStatus WINGDIPAPI GdipAddPathBezier(GpPath*,REAL,REAL,REAL,REAL,REAL,REAL,REAL GpStatus WINGDIPAPI GdipAddPathBezierI(GpPath*,INT,INT,INT,INT,INT,INT,INT,INT); GpStatus WINGDIPAPI GdipAddPathBeziers(GpPath*,GDIPCONST GpPointF*,INT); GpStatus WINGDIPAPI GdipAddPathBeziersI(GpPath*,GDIPCONST GpPoint*,INT); +GpStatus WINGDIPAPI GdipAddPathCurve2(GpPath*,GDIPCONST GpPointF*,INT,REAL); GpStatus WINGDIPAPI GdipAddPathEllipse(GpPath*,REAL,REAL,REAL,REAL); GpStatus WINGDIPAPI GdipAddPathEllipseI(GpPath*,INT,INT,INT,INT); GpStatus WINGDIPAPI GdipAddPathLine(GpPath*,REAL,REAL,REAL,REAL); -- 2.11.4.GIT