Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/graphicspath.c | 41 ++++++++++++++++++++++++------- dlls/gdiplus/tests/graphicspath.c | 34 +++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 9 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 4d5a73588f..6d2760bef4 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -166,6 +166,33 @@ static BOOL flatten_bezier(path_list_node_t *start, REAL x2, REAL y2, REAL x3, R return TRUE; }
+GpStatus extend_current_figure(GpPath *path, INT count, REAL x1, REAL y1, INT *old_count) +{ + *old_count = path->pathdata.Count; + + if(path->newfigure || + path->pathdata.Points[*old_count - 1].X != x1 || + path->pathdata.Points[*old_count - 1].Y != y1) + { + if(!lengthen_path(path, count)) + return OutOfMemory; + + path->pathdata.Points[*old_count].X = x1; + path->pathdata.Points[*old_count].Y = y1; + path->pathdata.Types[*old_count] = + (path->newfigure ? PathPointTypeStart : PathPointTypeLine); + } + else + { + if(!lengthen_path(path, count - 1)) + return OutOfMemory; + + (*old_count)--; + } + + return Ok; +} + /******************************************************************************* * GdipAddPathArc [GDIPLUS.1] * @@ -244,6 +271,7 @@ GpStatus WINGDIPAPI GdipAddPathBezier(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2, REAL x3, REAL y3, REAL x4, REAL y4) { INT old_count; + GpStatus status;
TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n", path, x1, y1, x2, y2, x3, y3, x4, y4); @@ -251,13 +279,10 @@ GpStatus WINGDIPAPI GdipAddPathBezier(GpPath *path, REAL x1, REAL y1, REAL x2, if(!path) return InvalidParameter;
- if(!lengthen_path(path, 4)) - return OutOfMemory; - - old_count = path->pathdata.Count; + status = extend_current_figure(path, 4, x1, y1, &old_count); + if(status != Ok) + return status;
- path->pathdata.Points[old_count].X = x1; - path->pathdata.Points[old_count].Y = y1; path->pathdata.Points[old_count + 1].X = x2; path->pathdata.Points[old_count + 1].Y = y2; path->pathdata.Points[old_count + 2].X = x3; @@ -265,14 +290,12 @@ GpStatus WINGDIPAPI GdipAddPathBezier(GpPath *path, REAL x1, REAL y1, REAL x2, path->pathdata.Points[old_count + 3].X = x4; path->pathdata.Points[old_count + 3].Y = y4;
- path->pathdata.Types[old_count] = - (path->newfigure ? PathPointTypeStart : PathPointTypeLine); path->pathdata.Types[old_count + 1] = PathPointTypeBezier; path->pathdata.Types[old_count + 2] = PathPointTypeBezier; path->pathdata.Types[old_count + 3] = PathPointTypeBezier;
path->newfigure = FALSE; - path->pathdata.Count += 4; + path->pathdata.Count = old_count + 4;
return Ok; } diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index 7670a6c41f..d85cf68dfc 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -332,6 +332,39 @@ static void test_line2(void) GdipDeletePath(path); }
+static path_test_t bezier_path[] = { + {10.0, 10.0, PathPointTypeStart, 0, 0}, /*0*/ + {20.0, 10.0, PathPointTypeBezier, 0, 0}, /*1*/ + {20.0, 20.0, PathPointTypeBezier, 0, 0}, /*2*/ + {30.0, 20.0, PathPointTypeBezier, 0, 0}, /*3*/ + {40.0, 20.0, PathPointTypeBezier, 0, 0}, /*4*/ + {40.0, 30.0, PathPointTypeBezier, 0, 0}, /*5*/ + {50.0, 30.0, PathPointTypeBezier, 0, 0}, /*6*/ + {50.0, 10.0, PathPointTypeLine, 0, 0}, /*7*/ + {60.0, 10.0, PathPointTypeBezier, 0, 0}, /*8*/ + {60.0, 20.0, PathPointTypeBezier, 0, 0}, /*9*/ + {70.0, 20.0, PathPointTypeBezier, 0, 0} /*10*/ + }; + +static void test_bezier(void) +{ + GpStatus status; + GpPath* path; + + GdipCreatePath(FillModeAlternate, &path); + + status = GdipAddPathBezier(path, 10.0, 10.0, 20.0, 10.0, 20.0, 20.0, 30.0, 20.0); + expect(Ok, status); + status = GdipAddPathBezier(path, 30.0, 20.0, 40.0, 20.0, 40.0, 30.0, 50.0, 30.0); + expect(Ok, status); + status = GdipAddPathBezier(path, 50.0, 10.0, 60.0, 10.0, 60.0, 20.0, 70.0, 20.0); + expect(Ok, status); + + ok_path(path, bezier_path, ARRAY_SIZE(bezier_path), FALSE); + + GdipDeletePath(path); +} + static path_test_t arc_path[] = { {600.0, 450.0, PathPointTypeStart, 0, 0}, /*0*/ {600.0, 643.3, PathPointTypeBezier, 0, 0}, /*1*/ @@ -1784,6 +1817,7 @@ START_TEST(graphicspath) test_getpathdata(); test_createpath2(); test_line2(); + test_bezier(); test_arc(); test_worldbounds(); test_pathpath();
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48877 Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/graphicspath.c | 14 ++++++-------- dlls/gdiplus/tests/graphicspath.c | 23 +++++++++++++++++++++++ 2 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 6d2760bef4..cabe8d4bd4 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -314,27 +314,25 @@ GpStatus WINGDIPAPI GdipAddPathBeziers(GpPath *path, GDIPCONST GpPointF *points, INT count) { INT i, old_count; + GpStatus status;
TRACE("(%p, %p, %d)\n", path, points, count);
if(!path || !points || ((count - 1) % 3)) return InvalidParameter;
- if(!lengthen_path(path, count)) - return OutOfMemory; - - old_count = path->pathdata.Count; + status = extend_current_figure(path, count, points[0].X, points[0].Y, &old_count); + if(status != Ok) + return status;
- for(i = 0; i < count; i++){ + for(i = 1; i < count; i++){ path->pathdata.Points[old_count + i].X = points[i].X; path->pathdata.Points[old_count + i].Y = points[i].Y; path->pathdata.Types[old_count + i] = PathPointTypeBezier; }
- path->pathdata.Types[old_count] = - (path->newfigure ? PathPointTypeStart : PathPointTypeLine); path->newfigure = FALSE; - path->pathdata.Count += count; + path->pathdata.Count = old_count + count;
return Ok; } diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index d85cf68dfc..d19c7836fb 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -365,6 +365,28 @@ static void test_bezier(void) GdipDeletePath(path); }
+static void test_beziers(void) +{ + GpStatus status; + GpPath* path; + PointF bezier_points1[] = {{10.0,10.0}, {20.0,10.0}, {20.0,20.0}, {30.0,20.0}}; + PointF bezier_points2[] = {{30.0,20.0}, {40.0,20.0}, {40.0,30.0}, {50.0,30.0}}; + PointF bezier_points3[] = {{50.0,10.0}, {60.0,10.0}, {60.0,20.0}, {70.0,20.0}}; + + GdipCreatePath(FillModeAlternate, &path); + + status = GdipAddPathBeziers(path, bezier_points1, 4); + expect(Ok, status); + status = GdipAddPathBeziers(path, bezier_points2, 4); + expect(Ok, status); + status = GdipAddPathBeziers(path, bezier_points3, 4); + expect(Ok, status); + + ok_path(path, bezier_path, ARRAY_SIZE(bezier_path), FALSE); + + GdipDeletePath(path); +} + static path_test_t arc_path[] = { {600.0, 450.0, PathPointTypeStart, 0, 0}, /*0*/ {600.0, 643.3, PathPointTypeBezier, 0, 0}, /*1*/ @@ -1818,6 +1840,7 @@ START_TEST(graphicspath) test_createpath2(); test_line2(); test_bezier(); + test_beziers(); test_arc(); test_worldbounds(); test_pathpath();
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/graphicspath.c | 15 +++++---------- dlls/gdiplus/tests/graphicspath.c | 5 ++++- 2 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index cabe8d4bd4..66a99bf2ce 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -725,28 +725,23 @@ GpStatus WINGDIPAPI GdipAddPathLine2I(GpPath *path, GDIPCONST GpPoint *points, I GpStatus WINGDIPAPI GdipAddPathLine(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2) { INT old_count; + GpStatus status;
TRACE("(%p, %.2f, %.2f, %.2f, %.2f)\n", path, x1, y1, x2, y2);
if(!path) return InvalidParameter;
- if(!lengthen_path(path, 2)) - return OutOfMemory; - - old_count = path->pathdata.Count; + status = extend_current_figure(path, 2, x1, y1, &old_count); + if(status != Ok) + return status;
- path->pathdata.Points[old_count].X = x1; - path->pathdata.Points[old_count].Y = y1; path->pathdata.Points[old_count + 1].X = x2; path->pathdata.Points[old_count + 1].Y = y2; - - path->pathdata.Types[old_count] = - (path->newfigure ? PathPointTypeStart : PathPointTypeLine); path->pathdata.Types[old_count + 1] = PathPointTypeLine;
path->newfigure = FALSE; - path->pathdata.Count += 2; + path->pathdata.Count = old_count + 2;
return Ok; } diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index d19c7836fb..1af53762e4 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -722,7 +722,8 @@ static path_test_t linei_path[] = { {15.00, 15.00, PathPointTypeLine, 0, 0}, /*9*/ {26.00, 28.00, PathPointTypeLine | PathPointTypeCloseSubpath, 0, 0}, /*10*/ {35.00, 35.00, PathPointTypeStart, 0, 0}, /*11*/ - {36.00, 38.00, PathPointTypeLine, 0, 0} /*12*/ + {36.00, 38.00, PathPointTypeLine, 0, 0}, /*12*/ + {39.00, 40.00, PathPointTypeLine, 0, 0} /*13*/ };
static void test_linei(void) @@ -739,6 +740,8 @@ static void test_linei(void) GdipClosePathFigure(path); status = GdipAddPathLineI(path, 35.0, 35.0, 36.0, 38.0); expect(Ok, status); + status = GdipAddPathLineI(path, 36, 38, 39, 40); + expect(Ok, status);
ok_path(path, linei_path, ARRAY_SIZE(linei_path), FALSE);
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/graphicspath.c | 18 +++++++----------- dlls/gdiplus/tests/graphicspath.c | 8 ++++++++ 2 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 66a99bf2ce..12ecd344cb 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -645,29 +645,25 @@ GpStatus WINGDIPAPI GdipAddPathLine2(GpPath *path, GDIPCONST GpPointF *points, INT count) { INT i, old_count; + GpStatus status;
TRACE("(%p, %p, %d)\n", path, points, count);
if(!path || !points || count < 1) return InvalidParameter;
- if(!lengthen_path(path, count)) - return OutOfMemory; - - old_count = path->pathdata.Count; + status = extend_current_figure(path, count, points[0].X, points[0].Y, &old_count); + if(status != Ok) + return status;
- for(i = 0; i < count; i++){ + for(i = 1; i < count; i++){ path->pathdata.Points[old_count + i].X = points[i].X; path->pathdata.Points[old_count + i].Y = points[i].Y; path->pathdata.Types[old_count + i] = PathPointTypeLine; }
- if(path->newfigure){ - path->pathdata.Types[old_count] = PathPointTypeStart; - path->newfigure = FALSE; - } - - path->pathdata.Count += count; + path->newfigure = FALSE; + path->pathdata.Count = old_count + count;
return Ok; } diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index 1af53762e4..b3ee72f29b 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -329,6 +329,14 @@ static void test_line2(void)
ok_path(path, line2_path, ARRAY_SIZE(line2_path), FALSE);
+ GdipResetPath(path); + status = GdipAddPathLine2(path, line2_points, 3); + expect(Ok, status); + status = GdipAddPathLine2(path, &(line2_points[2]), 3); + expect(Ok, status); + + ok_path(path, line2_path, 5, FALSE); + GdipDeletePath(path); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=69568
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/gdiplus/graphicspath.c:645 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/gdiplus/graphicspath.c:645 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/gdiplus/graphicspath.c:645 Task: Patch failed to apply
Oops. This won't apply because it assumes the GdipAddPathLine2 patch from my previous set is already applied.
On Tue, Apr 14, 2020 at 2:07 PM Marvin testbot@winehq.org wrote:
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=69568
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/gdiplus/graphicspath.c:645 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/gdiplus/graphicspath.c:645 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/gdiplus/graphicspath.c:645 Task: Patch failed to apply
On Tue, 14 Apr 2020, Marvin wrote: [...]
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=69568
=== build (build log) ===
error: patch failed: dlls/gdiplus/graphicspath.c:645 Task: Patch failed to apply
[...]
Oops. This won't apply because it assumes the GdipAddPathLine2 patch from my previous set is already applied.
I'm not entirely sure but this apply failure seems to have caused some confusion. So in case a clarification is needed, here is what happened:
* A first GdipAddPathLine2() patch was submitted on the 13th and did not cause any TestBot failure. https://testbot.winehq.org/JobDetails.pl?Key=69502
* The next day a 5-part patchset was sent and part 4 failed to apply. Looking at the patch below one can see that the TestBot used patches 1 to 4 of the patchset, as it should: https://testbot.winehq.org/GetFile.pl?JobKey=69568&StepKey=1
* The reason the combined parts 1-4 patch failed to apply is that part 4 depended on the previous day's patch. However, despite passing the tests that patch had not yet been committed to Wine: when to commit is up to Alexandre. It depends on him having the time to review the patch and being convinced that the patch is right.
Maybe that's the confusion: passing the tests is no guarantee that the patch will be applied promptly, if at all. It just isn't automatic.
Also the patches were in separate series so the TestBot had no reason to combine them.
* One hour after this job ran, the patch from the previous day got committed: if I got all the timestamps right for my timezone, the job ran at 21:07, the previous day's patch got committed at 22:04, got pushed to the public repository probably a few minutes later, and the TestBot picked up on the update at 02:00.
But then, maybe the confusion is just me misinterpreting the emails and IRC messages. If so ignore this message.
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/graphicspath.c | 25 ++++++++++--------------- dlls/gdiplus/tests/graphicspath.c | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 15 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 12ecd344cb..9454a9dfbf 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -222,7 +222,9 @@ GpStatus extend_current_figure(GpPath *path, INT count, REAL x1, REAL y1, INT *o GpStatus WINGDIPAPI GdipAddPathArc(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2, REAL startAngle, REAL sweepAngle) { - INT count, old_count, i; + GpPointF *ptf; + GpStatus status; + INT count;
TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n", path, x1, y1, x2, y2, startAngle, sweepAngle); @@ -231,26 +233,19 @@ GpStatus WINGDIPAPI GdipAddPathArc(GpPath *path, REAL x1, REAL y1, REAL x2, return InvalidParameter;
count = arc2polybezier(NULL, x1, y1, x2, y2, startAngle, sweepAngle); - if(count == 0) return Ok; - if(!lengthen_path(path, count)) - return OutOfMemory;
- old_count = path->pathdata.Count; - arc2polybezier(&path->pathdata.Points[old_count], x1, y1, x2, y2, - startAngle, sweepAngle); + ptf = heap_alloc_zero(sizeof(GpPointF)*count); + if(!ptf) + return OutOfMemory;
- for(i = 0; i < count; i++){ - path->pathdata.Types[old_count + i] = PathPointTypeBezier; - } + arc2polybezier(ptf, x1, y1, x2, y2, startAngle, sweepAngle);
- path->pathdata.Types[old_count] = - (path->newfigure ? PathPointTypeStart : PathPointTypeLine); - path->newfigure = FALSE; - path->pathdata.Count += count; + status = GdipAddPathBeziers(path, ptf, count);
- return Ok; + heap_free(ptf); + return status; }
/******************************************************************************* diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index b3ee72f29b..a02500bc1d 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -435,6 +435,13 @@ static path_test_t arc_path[] = { {450.9, 824.1, PathPointTypeBezier, 0, 0}, /*36*/ {540.4, 676.9, PathPointTypeBezier | PathPointTypeCloseSubpath, 0, 1} /*37*/ }; +static path_test_t arc_path2[] = { + {1.0, 0.0, PathPointTypeStart, 0, 0}, /*0*/ + {1.0, 0.5, PathPointTypeLine, 0, 0}, /*1*/ + {1.0, 0.776142, PathPointTypeBezier, 0, 0}, /*2*/ + {0.776142, 1.0, PathPointTypeBezier, 0, 0}, /*3*/ + {0.5, 1.0, PathPointTypeBezier, 0, 0} /*4*/ + };
static void test_arc(void) { @@ -463,6 +470,13 @@ static void test_arc(void)
ok_path(path, arc_path, ARRAY_SIZE(arc_path), FALSE);
+ GdipResetPath(path); + GdipAddPathLine(path, 1.0, 0.0, 1.0, 0.5); + status = GdipAddPathArc(path, 0.0, 0.0, 1.0, 1.0, 0.0, 90.0); + expect(Ok, status); + + ok_path_fudge(path, arc_path2, ARRAY_SIZE(arc_path2), FALSE, 0.000005); + GdipDeletePath(path); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=69569
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/gdiplus/graphicspath.c:645 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/gdiplus/graphicspath.c:645 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/gdiplus/graphicspath.c:645 Task: Patch failed to apply
+GpStatus extend_current_figure(GpPath *path, INT count, REAL x1, REAL y1, INT *old_count)
I don't like this interface. It's hard for me to think about what "count" and "old_count" really mean. One of them is an index into Points, and one is a number of points.
I'd probably do something like: extend_current_figure(GpPath *path, REAL start_x, REAL start_y, INT extra_points, INT *start_index)
I don't really like extra_points as a name, but passing in the number of points that need to be added other than the start point makes more sense to me when we don't know if the start point will be added or reused.
I think no matter how we do it, we'll need a comment explaining what this function does.
Another possibility is to pass an array of points and point types to extend_current_figure, and let it take care of updating the path.
extend_current_figure should be declared static.
Another possibility is to pass an array of points and point types to extend_current_figure, and let it take care of updating the path.
Actually, we probably don't need an array of point types, we can assume that all points have the same type except for the first point, which is either Start or Line.
Signed-off-by: Jeff Smith whydoubt@gmail.com --- v2: Handle all new points in extend_current_figure.
dlls/gdiplus/graphicspath.c | 80 +++++++++++++++++++++---------- dlls/gdiplus/tests/graphicspath.c | 34 +++++++++++++ 2 files changed, 90 insertions(+), 24 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 4d5a73588f..547f172d98 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -166,6 +166,52 @@ static BOOL flatten_bezier(path_list_node_t *start, REAL x2, REAL y2, REAL x3, R return TRUE; }
+/* GdipAddPath* helper + * + * Several GdipAddPath functions are expected to add onto an open figure. + * So if the first point being added is an exact match to the last point + * of the existing line, that point should not be added. + * + * Parameters: + * path : path to which points should be added + * points : array of points to add + * count : number of points to add (at least 1) + * type : type of the points being added + * + * Return value: + * OutOfMemory : out of memory, could not lengthen path + * Ok : success + */ +static GpStatus extend_current_figure(GpPath *path, GDIPCONST PointF *points, INT count, BYTE type) +{ + INT insert_index = path->pathdata.Count; + BYTE first_point_type = (path->newfigure ? PathPointTypeStart : PathPointTypeLine); + + if(!path->newfigure && + path->pathdata.Points[insert_index-1].X == points[0].X && + path->pathdata.Points[insert_index-1].Y == points[0].Y) + { + points++; + count--; + first_point_type = type; + } + + if(!count) + return Ok; + + if(!lengthen_path(path, count)) + return OutOfMemory; + + memcpy(path->pathdata.Points + insert_index, points, sizeof(GpPointF)*count); + path->pathdata.Types[insert_index] = first_point_type; + memset(path->pathdata.Types + insert_index + 1, type, count - 1); + + path->newfigure = FALSE; + path->pathdata.Count += count; + + return Ok; +} + /******************************************************************************* * GdipAddPathArc [GDIPLUS.1] * @@ -243,7 +289,7 @@ GpStatus WINGDIPAPI GdipAddPathArcI(GpPath *path, INT x1, INT y1, INT x2, GpStatus WINGDIPAPI GdipAddPathBezier(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2, REAL x3, REAL y3, REAL x4, REAL y4) { - INT old_count; + PointF points[4];
TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n", path, x1, y1, x2, y2, x3, y3, x4, y4); @@ -251,30 +297,16 @@ GpStatus WINGDIPAPI GdipAddPathBezier(GpPath *path, REAL x1, REAL y1, REAL x2, if(!path) return InvalidParameter;
- if(!lengthen_path(path, 4)) - return OutOfMemory; - - old_count = path->pathdata.Count; + points[0].X = x1; + points[0].Y = y1; + points[1].X = x2; + points[1].Y = y2; + points[2].X = x3; + points[2].Y = y3; + points[3].X = x4; + points[3].Y = y4;
- path->pathdata.Points[old_count].X = x1; - path->pathdata.Points[old_count].Y = y1; - path->pathdata.Points[old_count + 1].X = x2; - path->pathdata.Points[old_count + 1].Y = y2; - path->pathdata.Points[old_count + 2].X = x3; - path->pathdata.Points[old_count + 2].Y = y3; - path->pathdata.Points[old_count + 3].X = x4; - path->pathdata.Points[old_count + 3].Y = y4; - - path->pathdata.Types[old_count] = - (path->newfigure ? PathPointTypeStart : PathPointTypeLine); - path->pathdata.Types[old_count + 1] = PathPointTypeBezier; - path->pathdata.Types[old_count + 2] = PathPointTypeBezier; - path->pathdata.Types[old_count + 3] = PathPointTypeBezier; - - path->newfigure = FALSE; - path->pathdata.Count += 4; - - return Ok; + return extend_current_figure(path, points, 4, PathPointTypeBezier); }
GpStatus WINGDIPAPI GdipAddPathBezierI(GpPath *path, INT x1, INT y1, INT x2, diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index 7670a6c41f..d85cf68dfc 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -332,6 +332,39 @@ static void test_line2(void) GdipDeletePath(path); }
+static path_test_t bezier_path[] = { + {10.0, 10.0, PathPointTypeStart, 0, 0}, /*0*/ + {20.0, 10.0, PathPointTypeBezier, 0, 0}, /*1*/ + {20.0, 20.0, PathPointTypeBezier, 0, 0}, /*2*/ + {30.0, 20.0, PathPointTypeBezier, 0, 0}, /*3*/ + {40.0, 20.0, PathPointTypeBezier, 0, 0}, /*4*/ + {40.0, 30.0, PathPointTypeBezier, 0, 0}, /*5*/ + {50.0, 30.0, PathPointTypeBezier, 0, 0}, /*6*/ + {50.0, 10.0, PathPointTypeLine, 0, 0}, /*7*/ + {60.0, 10.0, PathPointTypeBezier, 0, 0}, /*8*/ + {60.0, 20.0, PathPointTypeBezier, 0, 0}, /*9*/ + {70.0, 20.0, PathPointTypeBezier, 0, 0} /*10*/ + }; + +static void test_bezier(void) +{ + GpStatus status; + GpPath* path; + + GdipCreatePath(FillModeAlternate, &path); + + status = GdipAddPathBezier(path, 10.0, 10.0, 20.0, 10.0, 20.0, 20.0, 30.0, 20.0); + expect(Ok, status); + status = GdipAddPathBezier(path, 30.0, 20.0, 40.0, 20.0, 40.0, 30.0, 50.0, 30.0); + expect(Ok, status); + status = GdipAddPathBezier(path, 50.0, 10.0, 60.0, 10.0, 60.0, 20.0, 70.0, 20.0); + expect(Ok, status); + + ok_path(path, bezier_path, ARRAY_SIZE(bezier_path), FALSE); + + GdipDeletePath(path); +} + static path_test_t arc_path[] = { {600.0, 450.0, PathPointTypeStart, 0, 0}, /*0*/ {600.0, 643.3, PathPointTypeBezier, 0, 0}, /*1*/ @@ -1784,6 +1817,7 @@ START_TEST(graphicspath) test_getpathdata(); test_createpath2(); test_line2(); + test_bezier(); test_arc(); test_worldbounds(); test_pathpath();
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48877 Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/graphicspath.c | 20 +------------------- dlls/gdiplus/tests/graphicspath.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 19 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 547f172d98..2729455567 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -322,30 +322,12 @@ GpStatus WINGDIPAPI GdipAddPathBezierI(GpPath *path, INT x1, INT y1, INT x2, GpStatus WINGDIPAPI GdipAddPathBeziers(GpPath *path, GDIPCONST GpPointF *points, INT count) { - INT i, old_count; - TRACE("(%p, %p, %d)\n", path, points, count);
if(!path || !points || ((count - 1) % 3)) return InvalidParameter;
- if(!lengthen_path(path, count)) - return OutOfMemory; - - old_count = path->pathdata.Count; - - for(i = 0; i < count; i++){ - path->pathdata.Points[old_count + i].X = points[i].X; - path->pathdata.Points[old_count + i].Y = points[i].Y; - path->pathdata.Types[old_count + i] = PathPointTypeBezier; - } - - path->pathdata.Types[old_count] = - (path->newfigure ? PathPointTypeStart : PathPointTypeLine); - path->newfigure = FALSE; - path->pathdata.Count += count; - - return Ok; + return extend_current_figure(path, points, count, PathPointTypeBezier); }
GpStatus WINGDIPAPI GdipAddPathBeziersI(GpPath *path, GDIPCONST GpPoint *points, diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index d85cf68dfc..d19c7836fb 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -365,6 +365,28 @@ static void test_bezier(void) GdipDeletePath(path); }
+static void test_beziers(void) +{ + GpStatus status; + GpPath* path; + PointF bezier_points1[] = {{10.0,10.0}, {20.0,10.0}, {20.0,20.0}, {30.0,20.0}}; + PointF bezier_points2[] = {{30.0,20.0}, {40.0,20.0}, {40.0,30.0}, {50.0,30.0}}; + PointF bezier_points3[] = {{50.0,10.0}, {60.0,10.0}, {60.0,20.0}, {70.0,20.0}}; + + GdipCreatePath(FillModeAlternate, &path); + + status = GdipAddPathBeziers(path, bezier_points1, 4); + expect(Ok, status); + status = GdipAddPathBeziers(path, bezier_points2, 4); + expect(Ok, status); + status = GdipAddPathBeziers(path, bezier_points3, 4); + expect(Ok, status); + + ok_path(path, bezier_path, ARRAY_SIZE(bezier_path), FALSE); + + GdipDeletePath(path); +} + static path_test_t arc_path[] = { {600.0, 450.0, PathPointTypeStart, 0, 0}, /*0*/ {600.0, 643.3, PathPointTypeBezier, 0, 0}, /*1*/ @@ -1818,6 +1840,7 @@ START_TEST(graphicspath) test_createpath2(); test_line2(); test_bezier(); + test_beziers(); test_arc(); test_worldbounds(); test_pathpath();
Signed-off-by: Vincent Povirk vincent@codeweavers.com
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/graphicspath.c | 24 ++++++------------------ dlls/gdiplus/tests/graphicspath.c | 5 ++++- 2 files changed, 10 insertions(+), 19 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 2729455567..083b79b932 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -717,31 +717,19 @@ GpStatus WINGDIPAPI GdipAddPathLine2I(GpPath *path, GDIPCONST GpPoint *points, I */ GpStatus WINGDIPAPI GdipAddPathLine(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2) { - INT old_count; + PointF points[2];
TRACE("(%p, %.2f, %.2f, %.2f, %.2f)\n", path, x1, y1, x2, y2);
if(!path) return InvalidParameter;
- if(!lengthen_path(path, 2)) - return OutOfMemory; - - old_count = path->pathdata.Count; - - path->pathdata.Points[old_count].X = x1; - path->pathdata.Points[old_count].Y = y1; - path->pathdata.Points[old_count + 1].X = x2; - path->pathdata.Points[old_count + 1].Y = y2; - - path->pathdata.Types[old_count] = - (path->newfigure ? PathPointTypeStart : PathPointTypeLine); - path->pathdata.Types[old_count + 1] = PathPointTypeLine; - - path->newfigure = FALSE; - path->pathdata.Count += 2; + points[0].X = x1; + points[0].Y = y1; + points[1].X = x2; + points[1].Y = y2;
- return Ok; + return extend_current_figure(path, points, 2, PathPointTypeLine); }
/************************************************************************* diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index d19c7836fb..1af53762e4 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -722,7 +722,8 @@ static path_test_t linei_path[] = { {15.00, 15.00, PathPointTypeLine, 0, 0}, /*9*/ {26.00, 28.00, PathPointTypeLine | PathPointTypeCloseSubpath, 0, 0}, /*10*/ {35.00, 35.00, PathPointTypeStart, 0, 0}, /*11*/ - {36.00, 38.00, PathPointTypeLine, 0, 0} /*12*/ + {36.00, 38.00, PathPointTypeLine, 0, 0}, /*12*/ + {39.00, 40.00, PathPointTypeLine, 0, 0} /*13*/ };
static void test_linei(void) @@ -739,6 +740,8 @@ static void test_linei(void) GdipClosePathFigure(path); status = GdipAddPathLineI(path, 35.0, 35.0, 36.0, 38.0); expect(Ok, status); + status = GdipAddPathLineI(path, 36, 38, 39, 40); + expect(Ok, status);
ok_path(path, linei_path, ARRAY_SIZE(linei_path), FALSE);
Signed-off-by: Vincent Povirk vincent@codeweavers.com
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/graphicspath.c | 22 +--------------------- dlls/gdiplus/tests/graphicspath.c | 8 ++++++++ 2 files changed, 9 insertions(+), 21 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 083b79b932..04806a95af 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -637,32 +637,12 @@ GpStatus WINGDIPAPI GdipAddPathEllipseI(GpPath *path, INT x, INT y, INT width, GpStatus WINGDIPAPI GdipAddPathLine2(GpPath *path, GDIPCONST GpPointF *points, INT count) { - INT i, old_count; - TRACE("(%p, %p, %d)\n", path, points, count);
if(!path || !points || count < 1) return InvalidParameter;
- if(!lengthen_path(path, count)) - return OutOfMemory; - - old_count = path->pathdata.Count; - - for(i = 0; i < count; i++){ - path->pathdata.Points[old_count + i].X = points[i].X; - path->pathdata.Points[old_count + i].Y = points[i].Y; - path->pathdata.Types[old_count + i] = PathPointTypeLine; - } - - if(path->newfigure){ - path->pathdata.Types[old_count] = PathPointTypeStart; - path->newfigure = FALSE; - } - - path->pathdata.Count += count; - - return Ok; + return extend_current_figure(path, points, count, PathPointTypeLine); }
GpStatus WINGDIPAPI GdipAddPathLine2I(GpPath *path, GDIPCONST GpPoint *points, INT count) diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index 1af53762e4..b3ee72f29b 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -329,6 +329,14 @@ static void test_line2(void)
ok_path(path, line2_path, ARRAY_SIZE(line2_path), FALSE);
+ GdipResetPath(path); + status = GdipAddPathLine2(path, line2_points, 3); + expect(Ok, status); + status = GdipAddPathLine2(path, &(line2_points[2]), 3); + expect(Ok, status); + + ok_path(path, line2_path, 5, FALSE); + GdipDeletePath(path); }
Signed-off-by: Vincent Povirk vincent@codeweavers.com
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/graphicspath.c | 25 ++++++++++--------------- dlls/gdiplus/tests/graphicspath.c | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 15 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 04806a95af..ba977f970a 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -241,7 +241,9 @@ static GpStatus extend_current_figure(GpPath *path, GDIPCONST PointF *points, IN GpStatus WINGDIPAPI GdipAddPathArc(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2, REAL startAngle, REAL sweepAngle) { - INT count, old_count, i; + GpPointF *points; + GpStatus status; + INT count;
TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n", path, x1, y1, x2, y2, startAngle, sweepAngle); @@ -250,26 +252,19 @@ GpStatus WINGDIPAPI GdipAddPathArc(GpPath *path, REAL x1, REAL y1, REAL x2, return InvalidParameter;
count = arc2polybezier(NULL, x1, y1, x2, y2, startAngle, sweepAngle); - if(count == 0) return Ok; - if(!lengthen_path(path, count)) + + points = heap_alloc_zero(sizeof(GpPointF)*count); + if(!points) return OutOfMemory;
- old_count = path->pathdata.Count; - arc2polybezier(&path->pathdata.Points[old_count], x1, y1, x2, y2, - startAngle, sweepAngle); + arc2polybezier(points, x1, y1, x2, y2, startAngle, sweepAngle);
- for(i = 0; i < count; i++){ - path->pathdata.Types[old_count + i] = PathPointTypeBezier; - } - - path->pathdata.Types[old_count] = - (path->newfigure ? PathPointTypeStart : PathPointTypeLine); - path->newfigure = FALSE; - path->pathdata.Count += count; + status = extend_current_figure(path, points, count, PathPointTypeBezier);
- return Ok; + heap_free(points); + return status; }
/******************************************************************************* diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index b3ee72f29b..a02500bc1d 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -435,6 +435,13 @@ static path_test_t arc_path[] = { {450.9, 824.1, PathPointTypeBezier, 0, 0}, /*36*/ {540.4, 676.9, PathPointTypeBezier | PathPointTypeCloseSubpath, 0, 1} /*37*/ }; +static path_test_t arc_path2[] = { + {1.0, 0.0, PathPointTypeStart, 0, 0}, /*0*/ + {1.0, 0.5, PathPointTypeLine, 0, 0}, /*1*/ + {1.0, 0.776142, PathPointTypeBezier, 0, 0}, /*2*/ + {0.776142, 1.0, PathPointTypeBezier, 0, 0}, /*3*/ + {0.5, 1.0, PathPointTypeBezier, 0, 0} /*4*/ + };
static void test_arc(void) { @@ -463,6 +470,13 @@ static void test_arc(void)
ok_path(path, arc_path, ARRAY_SIZE(arc_path), FALSE);
+ GdipResetPath(path); + GdipAddPathLine(path, 1.0, 0.0, 1.0, 0.5); + status = GdipAddPathArc(path, 0.0, 0.0, 1.0, 1.0, 0.0, 90.0); + expect(Ok, status); + + ok_path_fudge(path, arc_path2, ARRAY_SIZE(arc_path2), FALSE, 0.000005); + GdipDeletePath(path); }
Signed-off-by: Vincent Povirk vincent@codeweavers.com
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/graphicspath.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index ba977f970a..79e231bf1b 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -424,7 +424,7 @@ GpStatus WINGDIPAPI GdipAddPathClosedCurve2(GpPath *path, GDIPCONST GpPointF *po pt[len_pt-1].X = pt[0].X; pt[len_pt-1].Y = pt[0].Y;
- stat = GdipAddPathBeziers(path, pt, len_pt); + stat = extend_current_figure(path, pt, len_pt, PathPointTypeBezier);
/* close figure */ if(stat == Ok){ @@ -532,7 +532,7 @@ GpStatus WINGDIPAPI GdipAddPathCurve2(GpPath *path, GDIPCONST GpPointF *points, pt[len_pt-1].X = points[count-1].X; pt[len_pt-1].Y = points[count-1].Y;
- stat = GdipAddPathBeziers(path, pt, len_pt); + stat = extend_current_figure(path, pt, len_pt, PathPointTypeBezier);
heap_free(pt);
Signed-off-by: Vincent Povirk vincent@codeweavers.com
Signed-off-by: Vincent Povirk vincent@codeweavers.com