The MR is divided to three commits: 1. Extend AddPathCurve3 test with offset and nseg variables 2. Moving main curve implementation from GdipAddPathCurve2 to GdipAddPathCurve3, allow for use offset and nseg variables in GdipAddPathCurve3. The offset and nseg variables, will be used for fixing curve calculation in next commit. 3. Fix GdipAddPathCurve3 curve calculation with offset and nseg variables
From: Bartosz Kosiorek gang65@poczta.onet.pl
--- dlls/gdiplus/tests/graphicspath.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index 908ca8bcaf0..bf9b5a4246e 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -942,6 +942,19 @@ static path_test_t addcurve_path3[] = { {23.3, 13.3, PathPointTypeBezier, 0, 0}, /*5*/ {30.0, 10.0, PathPointTypeBezier, 0, 0} /*6*/ }; +static path_test_t addcurve_path4[] = { + {0.0, 0.0, PathPointTypeStart, 0, 0}, /*0*/ + {3.33, 3.33, PathPointTypeBezier, 0, 0}, /*1*/ + {6.66, 3.33, PathPointTypeBezier, 0, 1}, /*2*/ + {10.0, 10.0, PathPointTypeBezier, 0, 0}, /*3*/ + }; +static path_test_t addcurve_path5[] = { + {10.0, 10.0, PathPointTypeStart, 0, 0}, /*0*/ + {13.3, 16.6, PathPointTypeBezier, 0, 1}, /*1*/ + {3.33, 20.0, PathPointTypeBezier, 0, 1}, /*2*/ + {10.0, 20.0, PathPointTypeBezier, 0, 0} /*3*/ + }; + static void test_addcurve(void) { GpStatus status; @@ -1008,9 +1021,23 @@ static void test_addcurve(void) ok_path(path, addcurve_path, ARRAY_SIZE(addcurve_path), FALSE); GdipResetPath(path);
+ /* Skip first point */ status = GdipAddPathCurve3(path, points, 4, 1, 2, 1.0); expect(Ok, status); ok_path(path, addcurve_path3, ARRAY_SIZE(addcurve_path3), FALSE); + GdipResetPath(path); + + /* Skip two last points */ + status = GdipAddPathCurve3(path, points, 4, 0, 1, 1.0); + expect(Ok, status); + ok_path(path, addcurve_path4, ARRAY_SIZE(addcurve_path4), FALSE); + GdipResetPath(path); + + /* Skip first and last points */ + status = GdipAddPathCurve3(path, points, 4, 1, 1, 1.0); + expect(Ok, status); + ok_path(path, addcurve_path5, ARRAY_SIZE(addcurve_path5), FALSE); + GdipResetPath(path);
GdipDeletePath(path); }
From: Bartosz Kosiorek gang65@poczta.onet.pl
Moving main curve implementation from GdipAddPathCurve2 to GdipAddPathCurve3, allow for use offset and nseg variables in GdipAddPathCurve3. The offset and nseg variables, will be used for fixing curve calculation in next commit. --- dlls/gdiplus/graphicspath.c | 89 ++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 51 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 8e436f96f4e..1ffabcbba86 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -534,33 +534,26 @@ GpStatus WINGDIPAPI GdipAddPathCurve(GpPath *path, GDIPCONST GpPointF *points, I { TRACE("(%p, %p, %d)\n", path, points, count);
- if(!path || !points || count <= 1) - return InvalidParameter; - - return GdipAddPathCurve2(path, points, count, 1.0); + return GdipAddPathCurve3(path, points, count, 0, count - 1, 1.0); }
GpStatus WINGDIPAPI GdipAddPathCurveI(GpPath *path, GDIPCONST GpPoint *points, INT count) { TRACE("(%p, %p, %d)\n", path, points, count);
- if(!path || !points || count <= 1) - return InvalidParameter; - - return GdipAddPathCurve2I(path, points, count, 1.0); + return GdipAddPathCurve3I(path, points, count, 0, count - 1, 1.0); }
-GpStatus WINGDIPAPI GdipAddPathCurve2(GpPath *path, GDIPCONST GpPointF *points, INT count, - REAL tension) +GpStatus WINGDIPAPI GdipAddPathCurve3(GpPath *path, GDIPCONST GpPointF *points, + INT count, INT offset, INT nseg, REAL tension) { - INT i, len_pt = count*3-2; + INT i, len_pt = nseg * 3 + 1; GpPointF *pt; REAL x1, x2, y1, y2; GpStatus stat; + TRACE("(%p, %p, %d, %d, %d, %.2f)\n", path, points, count, offset, nseg, tension);
- TRACE("(%p, %p, %d, %.2f)\n", path, points, count, tension); - - if(!path || !points || count <= 1) + if(!path || !points || offset + 1 >= count || count - offset < nseg + 1 || nseg < 1) return InvalidParameter;
pt = heap_alloc_zero(len_pt * sizeof(GpPointF)); @@ -569,32 +562,32 @@ GpStatus WINGDIPAPI GdipAddPathCurve2(GpPath *path, GDIPCONST GpPointF *points,
tension = tension * TENSION_CONST;
- calc_curve_bezier_endp(points[0].X, points[0].Y, points[1].X, points[1].Y, + calc_curve_bezier_endp(points[offset].X, points[offset].Y, points[offset + 1].X, points[offset + 1].Y, tension, &x1, &y1);
- pt[0].X = points[0].X; - pt[0].Y = points[0].Y; + pt[0].X = points[offset].X; + pt[0].Y = points[offset].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); + for(i = 0; i < nseg-1; i++){ + calc_curve_bezier(&(points[offset + 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+3].X = points[offset + i + 1].X; + pt[3*i+3].Y = points[offset + 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); + calc_curve_bezier_endp(points[offset + nseg].X, points[offset + nseg].Y, + points[offset + nseg - 1].X, points[offset + nseg - 1].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; + pt[len_pt-1].X = points[offset + nseg].X; + pt[len_pt-1].Y = points[offset + nseg].Y;
stat = extend_current_figure(path, pt, len_pt, PathPointTypeBezier);
@@ -605,54 +598,48 @@ GpStatus WINGDIPAPI GdipAddPathCurve2(GpPath *path, GDIPCONST GpPointF *points,
GpStatus WINGDIPAPI GdipAddPathCurve2I(GpPath *path, GDIPCONST GpPoint *points, INT count, REAL tension) +{ + TRACE("(%p, %p, %d, %.2f)\n", path, points, count, tension); + + return GdipAddPathCurve3I(path, points, count, 0, count - 1, tension); +} + +GpStatus WINGDIPAPI GdipAddPathCurve2(GpPath *path, GDIPCONST GpPointF *points, INT count, + REAL tension) +{ + TRACE("(%p, %p, %d, %.2f)\n", path, points, count, tension); + + return GdipAddPathCurve3(path, points, count, 0, count - 1, tension); +} + +GpStatus WINGDIPAPI GdipAddPathCurve3I(GpPath *path, GDIPCONST GpPoint *points, + INT count, INT offset, INT nseg, REAL tension) { GpPointF *ptf; INT i; GpStatus stat;
- TRACE("(%p, %p, %d, %.2f)\n", path, points, count, tension); + TRACE("(%p, %p, %d, %d, %d, %.2f)\n", path, points, count, offset, nseg, tension);
- if(!path || !points || count <= 1) + if(!path || !points || offset + 1 >= count || count - offset < nseg + 1 || nseg < 1) return InvalidParameter;
ptf = heap_alloc_zero(sizeof(GpPointF)*count); if(!ptf) return OutOfMemory;
- for(i = 0; i < count; i++){ + for(i = 0; i < count; i++) { ptf[i].X = (REAL)points[i].X; ptf[i].Y = (REAL)points[i].Y; }
- stat = GdipAddPathCurve2(path, ptf, count, tension); + stat = GdipAddPathCurve3(path, ptf, count, offset, nseg, tension);
heap_free(ptf);
return stat; }
-GpStatus WINGDIPAPI GdipAddPathCurve3(GpPath *path, GDIPCONST GpPointF *points, - INT count, INT offset, INT nseg, REAL tension) -{ - TRACE("(%p, %p, %d, %d, %d, %.2f)\n", path, points, count, offset, nseg, tension); - - if(!path || !points || offset + 1 >= count || count - offset < nseg + 1) - return InvalidParameter; - - return GdipAddPathCurve2(path, &points[offset], nseg + 1, tension); -} - -GpStatus WINGDIPAPI GdipAddPathCurve3I(GpPath *path, GDIPCONST GpPoint *points, - INT count, INT offset, INT nseg, REAL tension) -{ - TRACE("(%p, %p, %d, %d, %d, %.2f)\n", path, points, count, offset, nseg, tension); - - if(!path || !points || offset + 1 >= count || count - offset < nseg + 1) - return InvalidParameter; - - return GdipAddPathCurve2I(path, &points[offset], nseg + 1, tension); -} - GpStatus WINGDIPAPI GdipAddPathEllipse(GpPath *path, REAL x, REAL y, REAL width, REAL height) {
From: Bartosz Kosiorek gang65@poczta.onet.pl
--- dlls/gdiplus/graphicspath.c | 32 +++++++++++++++++++++---------- dlls/gdiplus/tests/graphicspath.c | 8 ++++---- 2 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 1ffabcbba86..c2be46f1260 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -562,15 +562,23 @@ GpStatus WINGDIPAPI GdipAddPathCurve3(GpPath *path, GDIPCONST GpPointF *points,
tension = tension * TENSION_CONST;
- calc_curve_bezier_endp(points[offset].X, points[offset].Y, points[offset + 1].X, points[offset + 1].Y, - tension, &x1, &y1); - pt[0].X = points[offset].X; pt[0].Y = points[offset].Y; - pt[1].X = x1; - pt[1].Y = y1; + if (offset > 0) + { + calc_curve_bezier(&(points[offset - 1]), tension, &x1, &y1, &x2, &y2); + pt[1].X = x2; + pt[1].Y = y2; + } + else + { + calc_curve_bezier_endp(points[offset].X, points[offset].Y, + points[offset + 1].X, points[offset + 1].Y, tension, &x1, &y1); + pt[1].X = x1; + pt[1].Y = y1; + }
- for(i = 0; i < nseg-1; i++){ + for (i = 0; i < nseg - 1; i++){ calc_curve_bezier(&(points[offset + i]), tension, &x1, &y1, &x2, &y2);
pt[3*i+2].X = x1; @@ -581,13 +589,17 @@ GpStatus WINGDIPAPI GdipAddPathCurve3(GpPath *path, GDIPCONST GpPointF *points, pt[3*i+4].Y = y2; }
- calc_curve_bezier_endp(points[offset + nseg].X, points[offset + nseg].Y, - points[offset + nseg - 1].X, points[offset + nseg - 1].Y, tension, &x1, &y1); + if (offset + nseg + 1 < count) + /* If there are one more point in points table then use it for curve calculation */ + calc_curve_bezier(&(points[offset + nseg - 1]), tension, &x1, &y1, &x2, &y2); + else + calc_curve_bezier_endp(points[offset + nseg].X, points[offset + nseg].Y, + points[offset + nseg - 1].X, points[offset + nseg - 1].Y, tension, &x1, &y1);
- pt[len_pt-2].X = x1; - pt[len_pt-2].Y = y1; pt[len_pt-1].X = points[offset + nseg].X; pt[len_pt-1].Y = points[offset + nseg].Y; + pt[len_pt-2].X = x1; + pt[len_pt-2].Y = y1;
stat = extend_current_figure(path, pt, len_pt, PathPointTypeBezier);
diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index bf9b5a4246e..8eea57ec769 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -935,7 +935,7 @@ static path_test_t addcurve_path2[] = { }; static path_test_t addcurve_path3[] = { {10.0, 10.0, PathPointTypeStart, 0, 0}, /*0*/ - {13.3, 16.7, PathPointTypeBezier, 0, 1}, /*1*/ + {13.3, 16.7, PathPointTypeBezier, 0, 0}, /*1*/ {3.3, 20.0, PathPointTypeBezier, 0, 0}, /*2*/ {10.0, 20.0, PathPointTypeBezier, 0, 0}, /*3*/ {16.7, 20.0, PathPointTypeBezier, 0, 0}, /*4*/ @@ -945,13 +945,13 @@ static path_test_t addcurve_path3[] = { static path_test_t addcurve_path4[] = { {0.0, 0.0, PathPointTypeStart, 0, 0}, /*0*/ {3.33, 3.33, PathPointTypeBezier, 0, 0}, /*1*/ - {6.66, 3.33, PathPointTypeBezier, 0, 1}, /*2*/ + {6.66, 3.33, PathPointTypeBezier, 0, 0}, /*2*/ {10.0, 10.0, PathPointTypeBezier, 0, 0}, /*3*/ }; static path_test_t addcurve_path5[] = { {10.0, 10.0, PathPointTypeStart, 0, 0}, /*0*/ - {13.3, 16.6, PathPointTypeBezier, 0, 1}, /*1*/ - {3.33, 20.0, PathPointTypeBezier, 0, 1}, /*2*/ + {13.3, 16.6, PathPointTypeBezier, 0, 0}, /*1*/ + {3.33, 20.0, PathPointTypeBezier, 0, 0}, /*2*/ {10.0, 20.0, PathPointTypeBezier, 0, 0} /*3*/ };