Nikolay Sivov : gdiplus: Implemented GdipAddPathClosedCurve2 with tests.
Alexandre Julliard
julliard at winehq.org
Mon Aug 4 08:53:47 CDT 2008
Module: wine
Branch: master
Commit: 8be642c4c0c0596763069d6d2f5012a9d1fcbd3c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8be642c4c0c0596763069d6d2f5012a9d1fcbd3c
Author: Nikolay Sivov <bunglehead at gmail.com>
Date: Sun Aug 3 02:45:19 2008 +0400
gdiplus: Implemented GdipAddPathClosedCurve2 with tests.
---
dlls/gdiplus/gdiplus.spec | 2 +-
dlls/gdiplus/graphicspath.c | 69 +++++++++++++++++++++++++++++++++++++
dlls/gdiplus/tests/graphicspath.c | 50 ++++++++++++++++++++++++++
include/gdiplusflat.h | 1 +
4 files changed, 121 insertions(+), 1 deletions(-)
diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec
index d812fcf..a84667f 100644
--- a/dlls/gdiplus/gdiplus.spec
+++ b/dlls/gdiplus/gdiplus.spec
@@ -4,7 +4,7 @@
@ stdcall GdipAddPathBezierI(ptr long long long long long long long long)
@ stdcall GdipAddPathBeziers(ptr ptr long)
@ stdcall GdipAddPathBeziersI(ptr ptr long)
-@ stub GdipAddPathClosedCurve2
+@ stdcall GdipAddPathClosedCurve2(ptr ptr long long)
@ stub GdipAddPathClosedCurve2I
@ stub GdipAddPathClosedCurve
@ stub GdipAddPathClosedCurveI
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c
index 86059f0..040e13a 100644
--- a/dlls/gdiplus/graphicspath.c
+++ b/dlls/gdiplus/graphicspath.c
@@ -196,6 +196,75 @@ GpStatus WINGDIPAPI GdipAddPathBeziersI(GpPath *path, GDIPCONST GpPoint *points,
return ret;
}
+GpStatus WINGDIPAPI GdipAddPathClosedCurve2(GpPath *path, GDIPCONST GpPointF *points,
+ INT count, REAL tension)
+{
+ INT i, len_pt = (count + 1)*3-2;
+ GpPointF *pt;
+ GpPointF *pts;
+ REAL x1, x2, y1, y2;
+ GpStatus stat;
+
+ if(!path || !points || count <= 1)
+ return InvalidParameter;
+
+ pt = GdipAlloc(len_pt * sizeof(GpPointF));
+ pts = GdipAlloc((count + 1)*sizeof(GpPointF));
+ if(!pt || !pts){
+ GdipFree(pt);
+ GdipFree(pts);
+ return OutOfMemory;
+ }
+
+ /* copy source points to extend with the last one */
+ memcpy(pts, points, sizeof(GpPointF)*count);
+ pts[count] = pts[0];
+
+ tension = tension * TENSION_CONST;
+
+ for(i = 0; i < count-1; i++){
+ calc_curve_bezier(&(pts[i]), tension, &x1, &y1, &x2, &y2);
+
+ pt[3*i+2].X = x1;
+ pt[3*i+2].Y = y1;
+ pt[3*i+3].X = pts[i+1].X;
+ pt[3*i+3].Y = pts[i+1].Y;
+ pt[3*i+4].X = x2;
+ pt[3*i+4].Y = y2;
+ }
+
+ /* points [len_pt-2] and [0] are calculated
+ separetely to connect splines properly */
+ pts[0] = points[count-1];
+ pts[1] = points[0]; /* equals to start and end of a resulting path */
+ pts[2] = points[1];
+
+ calc_curve_bezier(pts, tension, &x1, &y1, &x2, &y2);
+ pt[len_pt-2].X = x1;
+ pt[len_pt-2].Y = y1;
+ pt[0].X = pts[1].X;
+ pt[0].Y = pts[1].Y;
+ pt[1].X = x2;
+ pt[1].Y = y2;
+ /* close path */
+ pt[len_pt-1].X = pt[0].X;
+ pt[len_pt-1].Y = pt[0].Y;
+
+ stat = GdipAddPathBeziers(path, pt, len_pt);
+
+ /* close figure */
+ if(stat == Ok){
+ INT count = path->pathdata.Count;
+ path->pathdata.Types[count - 1] |= PathPointTypeCloseSubpath;
+ path->newfigure = TRUE;
+ }
+
+ GdipFree(pts);
+ GdipFree(pt);
+
+ return stat;
+}
+
GpStatus WINGDIPAPI GdipAddPathCurve(GpPath *path, GDIPCONST GpPointF *points, INT count)
{
if(!path || !points || count <= 1)
diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c
index 7af1814..eb7e2de 100644
--- a/dlls/gdiplus/tests/graphicspath.c
+++ b/dlls/gdiplus/tests/graphicspath.c
@@ -764,6 +764,55 @@ static void test_addcurve(void)
GdipDeletePath(path);
}
+static path_test_t addclosedcurve_path[] = {
+ {0.0, 0.0, PathPointTypeStart, 0, 0}, /*0*/
+ {-6.7, 0.0, 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*/
+ {33.3, 16.7, PathPointTypeBezier, 0, 0}, /*8*/
+ {30.0, 10.0, PathPointTypeBezier, 0, 0}, /*9*/
+ {26.7, 3.3, PathPointTypeBezier, 0, 0}, /*10*/
+ {6.7, 0.0, PathPointTypeBezier, 0, 0}, /*11*/
+ {0.0, 0.0, PathPointTypeBezier | PathPointTypeCloseSubpath, 0, 0} /*12*/
+ };
+static void test_addclosedcurve(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 = GdipAddPathClosedCurve2(NULL, NULL, 0, 0.0);
+ expect(InvalidParameter, status);
+ status = GdipAddPathClosedCurve2(path, NULL, 0, 0.0);
+ expect(InvalidParameter, status);
+ status = GdipAddPathClosedCurve2(path, points, -1, 0.0);
+ expect(InvalidParameter, status);
+ status = GdipAddPathClosedCurve2(path, points, 1, 1.0);
+ expect(InvalidParameter, status);
+
+ /* add to empty path */
+ status = GdipAddPathClosedCurve2(path, points, 4, 1.0);
+ expect(Ok, status);
+ ok_path(path, addclosedcurve_path, sizeof(addclosedcurve_path)/sizeof(path_test_t), FALSE);
+ GdipDeletePath(path);
+}
+
START_TEST(graphicspath)
{
struct GdiplusStartupInput gdiplusStartupInput;
@@ -788,6 +837,7 @@ START_TEST(graphicspath)
test_polygon();
test_lastpoint();
test_addcurve();
+ test_addclosedcurve();
GdiplusShutdown(gdiplusToken);
}
diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h
index ca9975d..d9c9188 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 GdipAddPathClosedCurve2(GpPath*,GDIPCONST GpPointF*,INT,REAL);
GpStatus WINGDIPAPI GdipAddPathCurve(GpPath*,GDIPCONST GpPointF*,INT);
GpStatus WINGDIPAPI GdipAddPathCurveI(GpPath*,GDIPCONST GpPoint*,INT);
GpStatus WINGDIPAPI GdipAddPathCurve2(GpPath*,GDIPCONST GpPointF*,INT,REAL);
More information about the wine-cvs
mailing list