Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45273
-- v7: gdiplus: add support for LineCapArrowAnchor.
From: Bartosz Kosiorek gang65@poczta.onet.pl
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45273 --- dlls/gdiplus/graphicspath.c | 53 +++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 23 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index fdb7dd24906..9194f6d42aa 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -1876,7 +1876,7 @@ static void widen_joint(const GpPointF *p1, const GpPointF *p2, const GpPointF * }
static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint, - REAL pen_width, GpLineCap cap, int add_first_points, + REAL pen_width, GpLineCap cap, GpCustomLineCap* custom_cap, int add_first_points, int add_last_point, path_list_node_t **last_point) { switch (cap) @@ -1889,6 +1889,7 @@ static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint, add_bevel_point(endpoint, nextpoint, pen_width, 0, last_point); break; case LineCapSquare: + case LineCapCustom: { REAL segment_dy = nextpoint->Y-endpoint->Y; REAL segment_dx = nextpoint->X-endpoint->X; @@ -1897,20 +1898,25 @@ static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint, REAL bevel_dx, bevel_dy; REAL extend_dx, extend_dy;
- extend_dx = -distance * segment_dx / segment_length; - extend_dy = -distance * segment_dy / segment_length; + extend_dx = distance * segment_dx / segment_length; + extend_dy = distance * segment_dy / segment_length;
- bevel_dx = -distance * segment_dy / segment_length; - bevel_dy = distance * segment_dx / segment_length; + bevel_dx = -extend_dy; + bevel_dy = extend_dx; + + if (cap == LineCapCustom) + { + extend_dx = -2.0 * custom_cap->inset * extend_dx; + extend_dy = -2.0 * custom_cap->inset * extend_dy; + }
if (add_first_points) - *last_point = add_path_list_node(*last_point, endpoint->X + extend_dx + bevel_dx, - endpoint->Y + extend_dy + bevel_dy, PathPointTypeLine); + *last_point = add_path_list_node(*last_point, endpoint->X - extend_dx + bevel_dx, + endpoint->Y - extend_dy + bevel_dy, PathPointTypeLine);
if (add_last_point) - *last_point = add_path_list_node(*last_point, endpoint->X + extend_dx - bevel_dx, - endpoint->Y + extend_dy - bevel_dy, PathPointTypeLine); - + *last_point = add_path_list_node(*last_point, endpoint->X - extend_dx - bevel_dx, + endpoint->Y - extend_dy - bevel_dy, PathPointTypeLine); break; } case LineCapRound: @@ -1983,8 +1989,8 @@ static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint, }
static void widen_open_figure(const GpPointF *points, int start, int end, - GpPen *pen, REAL pen_width, GpLineCap start_cap, - GpLineCap end_cap, path_list_node_t **last_point); + GpPen *pen, REAL pen_width, GpLineCap start_cap, GpCustomLineCap* custom_start, + GpLineCap end_cap, GpCustomLineCap* custom_end, path_list_node_t **last_point);
static void widen_closed_figure(const GpPointF *points, int start, int end, GpPen *pen, REAL pen_width, path_list_node_t **last_point); @@ -2145,7 +2151,7 @@ static void add_anchor(const GpPointF *endpoint, const GpPointF *nextpoint, if ((custom->pathdata.Types[custom->pathdata.Count - 1] & PathPointTypeCloseSubpath) == PathPointTypeCloseSubpath) widen_closed_figure(tmp_points, 0, custom->pathdata.Count - 1, pen, pen_width, last_point); else - widen_open_figure(tmp_points, 0, custom->pathdata.Count - 1, pen, pen_width, custom->strokeEndCap, custom->strokeStartCap, last_point); + widen_open_figure(tmp_points, 0, custom->pathdata.Count - 1, pen, pen_width, custom->strokeEndCap, NULL, custom->strokeStartCap, NULL, last_point); } else { @@ -2167,8 +2173,8 @@ static void add_anchor(const GpPointF *endpoint, const GpPointF *nextpoint, }
static void widen_open_figure(const GpPointF *points, int start, int end, - GpPen *pen, REAL pen_width, GpLineCap start_cap, - GpLineCap end_cap, path_list_node_t **last_point) + GpPen *pen, REAL pen_width, GpLineCap start_cap, GpCustomLineCap* custom_start, + GpLineCap end_cap, GpCustomLineCap* custom_end, path_list_node_t **last_point) { int i; path_list_node_t *prev_point; @@ -2179,21 +2185,21 @@ static void widen_open_figure(const GpPointF *points, int start, int end, prev_point = *last_point;
widen_cap(&points[start], &points[start+1], - pen_width, start_cap, FALSE, TRUE, last_point); + pen_width, start_cap, custom_start, FALSE, TRUE, last_point);
for (i=start+1; i<end; i++) widen_joint(&points[i-1], &points[i], &points[i+1], pen, pen_width, last_point);
widen_cap(&points[end], &points[end-1], - pen_width, end_cap, TRUE, TRUE, last_point); + pen_width, end_cap, custom_end, TRUE, TRUE, last_point);
for (i=end-1; i>start; i--) widen_joint(&points[i+1], &points[i], &points[i-1], pen, pen_width, last_point);
widen_cap(&points[start], &points[start+1], - pen_width, start_cap, TRUE, FALSE, last_point); + pen_width, start_cap, custom_start, TRUE, FALSE, last_point);
prev_point->next->type = PathPointTypeStart; (*last_point)->type |= PathPointTypeCloseSubpath; @@ -2337,8 +2343,8 @@ static void widen_dashed_figure(GpPath *path, int start, int end, int closed, tmp_points[num_tmp_points].Y = path->pathdata.Points[i].Y + segment_dy * segment_pos / segment_length;
widen_open_figure(tmp_points, 0, num_tmp_points, pen, pen_width, - draw_start_cap ? pen->startcap : LineCapFlat, - LineCapFlat, last_point); + draw_start_cap ? pen->startcap : LineCapFlat, pen->customstart, + LineCapFlat, NULL, last_point); draw_start_cap = 0; num_tmp_points = 0; } @@ -2371,8 +2377,8 @@ static void widen_dashed_figure(GpPath *path, int start, int end, int closed, { /* last dash overflows last segment */ widen_open_figure(tmp_points, 0, num_tmp_points-1, pen, pen_width, - draw_start_cap ? pen->startcap : LineCapFlat, - closed ? LineCapFlat : pen->endcap, last_point); + draw_start_cap ? pen->startcap : LineCapFlat, pen->customstart, + closed ? LineCapFlat : pen->endcap, pen->customend, last_point); }
heap_free(dash_pattern_scaled); @@ -2446,7 +2452,8 @@ GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix, if (pen->dash != DashStyleSolid) widen_dashed_figure(flat_path, subpath_start, i, 0, pen, pen_width, &last_point); else - widen_open_figure(flat_path->pathdata.Points, subpath_start, i, pen, pen_width, pen->startcap, pen->endcap, &last_point); + widen_open_figure(flat_path->pathdata.Points, subpath_start, i, pen, pen_width, + pen->startcap, pen->customstart, pen->endcap, pen->customend, &last_point); } }
From: Bartosz Kosiorek gang65@poczta.onet.pl
--- dlls/gdiplus/graphicspath.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 9194f6d42aa..10ffa85d6e3 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -2128,13 +2128,13 @@ static void add_anchor(const GpPointF *endpoint, const GpPointF *nextpoint, TRACE("GpCustomLineCap fill: %d basecap: %d inset: %f join: %d scale: %f pen_width:%f\n", custom->fill, custom->basecap, custom->inset, custom->join, custom->scale, pen_width);
- /* Coordination where cap needs to be drawn */ - posx = endpoint->X - pen_width * segment_dx / segment_length; - posy = endpoint->Y - pen_width * segment_dy / segment_length; - sina = -pen_width * custom->scale * segment_dx / segment_length; cosa = pen_width * custom->scale * segment_dy / segment_length;
+ /* Coordination where cap needs to be drawn */ + posx = endpoint->X + sina; + posy = endpoint->Y - cosa; + if (!custom->fill) { tmp_points = heap_alloc_zero(custom->pathdata.Count * sizeof(GpPoint));
From: Bartosz Kosiorek gang65@poczta.onet.pl
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=42809 --- dlls/gdiplus/graphicspath.c | 30 ++++++++++++++++++++++++------ dlls/gdiplus/tests/graphicspath.c | 7 +++---- 2 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 10ffa85d6e3..37828741c22 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -1890,6 +1890,7 @@ static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint, break; case LineCapSquare: case LineCapCustom: + case LineCapArrowAnchor: { REAL segment_dy = nextpoint->Y-endpoint->Y; REAL segment_dx = nextpoint->X-endpoint->X; @@ -1909,6 +1910,11 @@ static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint, extend_dx = -2.0 * custom_cap->inset * extend_dx; extend_dy = -2.0 * custom_cap->inset * extend_dy; } + else if (cap == LineCapArrowAnchor) + { + extend_dx = -3.0 * extend_dx; + extend_dy = -3.0 * extend_dy; + }
if (add_first_points) *last_point = add_path_list_node(*last_point, endpoint->X - extend_dx + bevel_dx, @@ -2105,6 +2111,24 @@ static void add_anchor(const GpPointF *endpoint, const GpPointF *nextpoint, endpoint->Y + perp_dy, PathPointTypeLine); break; } + case LineCapArrowAnchor: + { + REAL segment_dy = nextpoint->Y - endpoint->Y; + REAL segment_dx = nextpoint->X - endpoint->X; + REAL segment_length = sqrtf(segment_dy * segment_dy + segment_dx * segment_dx); + REAL par_dx = pen_width * segment_dx / segment_length; + REAL par_dy = pen_width * segment_dy / segment_length; + REAL perp_dx = -par_dy; + REAL perp_dy = par_dx; + + *last_point = add_path_list_node(*last_point, endpoint->X, + endpoint->Y, PathPointTypeStart); + *last_point = add_path_list_node(*last_point, endpoint->X + 1.733 * par_dx - perp_dx, + endpoint->Y + 1.733 * par_dy - perp_dy, PathPointTypeLine); + *last_point = add_path_list_node(*last_point, endpoint->X + 1.733 * par_dx + perp_dx, + endpoint->Y + 1.733 * par_dy + perp_dy, PathPointTypeLine); + break; + } case LineCapCustom: { REAL segment_dy = nextpoint->Y - endpoint->Y; @@ -2416,12 +2440,6 @@ GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix,
last_point = points;
- if (pen->endcap > LineCapDiamondAnchor && pen->endcap != LineCapCustom) - FIXME("unimplemented end cap %x\n", pen->endcap); - - if (pen->startcap > LineCapDiamondAnchor && pen->startcap != LineCapCustom) - FIXME("unimplemented start cap %x\n", pen->startcap); - if (pen->dashcap != DashCapFlat) FIXME("unimplemented dash cap %d\n", pen->dashcap);
diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index ab1e7cb2fda..a1a4601c83c 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -114,7 +114,7 @@ static void _ok_path_fudge(GpPath* path, const path_test_t *expected, INT expect stringify_point_type(types[idx], name);
todo_wine_if (expected[eidx].todo || numskip) - ok_(__FILE__,line)(match, "Expected #%d: %s (%.1f,%.1f) but got %s (%.1f,%.1f)\n", eidx, + ok_(__FILE__,line)(match, "Expected #%d: %s (%.6f,%.6f) but got %s (%.6f,%.6f)\n", eidx, ename, expected[eidx].X, expected[eidx].Y, name, points[idx].X, points[idx].Y);
@@ -1655,7 +1655,6 @@ static void test_widen_cap(void) const path_test_t *expected; INT expected_size; BOOL dashed; - BOOL todo_size; } caps[] = { @@ -1676,7 +1675,7 @@ static void test_widen_cap(void) { LineCapDiamondAnchor, 10.0, widenline_capdiamondanchor_path, ARRAY_SIZE(widenline_capdiamondanchor_path) }, { LineCapArrowAnchor, 10.0, widenline_caparrowanchor_path, - ARRAY_SIZE(widenline_caparrowanchor_path), FALSE, TRUE }, + ARRAY_SIZE(widenline_caparrowanchor_path) }, { LineCapSquareAnchor, 0.0, widenline_capsquareanchor_thin_path, ARRAY_SIZE(widenline_capsquareanchor_thin_path) }, { LineCapSquareAnchor, 10.0, widenline_capsquareanchor_dashed_path, @@ -1729,7 +1728,7 @@ static void test_widen_cap(void) } }
- ok_path_fudge(path, caps[i].expected, caps[i].expected_size, caps[i].todo_size, 0.000005); + ok_path_fudge(path, caps[i].expected, caps[i].expected_size, FALSE, 0.00005);
GdipDeletePen(pen); }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=126816
Your paranoid android.
=== debian11 (32 bit report) ===
gdiplus: graphicspath.c:1731: Test failed: Expected #5: PathPointTypeLine (22.320507,0.000000) but got PathPointTypeLine (22.330000,0.000000) graphicspath.c:1731: Test failed: Expected #6: PathPointTypeLine | PathPointTypeCloseSubpath (22.320507,20.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (22.330000,20.000000) graphicspath.c:1731: Test failed: Expected #8: PathPointTypeLine (32.679489,20.000000) but got PathPointTypeLine (32.669998,20.000000) graphicspath.c:1731: Test failed: Expected #9: PathPointTypeLine | PathPointTypeCloseSubpath (32.679489,0.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (32.669998,0.000000)
=== debian11 (32 bit ar:MA report) ===
gdiplus: graphicspath.c:1731: Test failed: Expected #5: PathPointTypeLine (22.320507,0.000000) but got PathPointTypeLine (22.330000,0.000000) graphicspath.c:1731: Test failed: Expected #6: PathPointTypeLine | PathPointTypeCloseSubpath (22.320507,20.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (22.330000,20.000000) graphicspath.c:1731: Test failed: Expected #8: PathPointTypeLine (32.679489,20.000000) but got PathPointTypeLine (32.669998,20.000000) graphicspath.c:1731: Test failed: Expected #9: PathPointTypeLine | PathPointTypeCloseSubpath (32.679489,0.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (32.669998,0.000000)
=== debian11 (32 bit de report) ===
gdiplus: graphicspath.c:1731: Test failed: Expected #5: PathPointTypeLine (22.320507,0.000000) but got PathPointTypeLine (22.330000,0.000000) graphicspath.c:1731: Test failed: Expected #6: PathPointTypeLine | PathPointTypeCloseSubpath (22.320507,20.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (22.330000,20.000000) graphicspath.c:1731: Test failed: Expected #8: PathPointTypeLine (32.679489,20.000000) but got PathPointTypeLine (32.669998,20.000000) graphicspath.c:1731: Test failed: Expected #9: PathPointTypeLine | PathPointTypeCloseSubpath (32.679489,0.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (32.669998,0.000000)
=== debian11 (32 bit fr report) ===
gdiplus: graphicspath.c:1731: Test failed: Expected #5: PathPointTypeLine (22.320507,0.000000) but got PathPointTypeLine (22.330000,0.000000) graphicspath.c:1731: Test failed: Expected #6: PathPointTypeLine | PathPointTypeCloseSubpath (22.320507,20.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (22.330000,20.000000) graphicspath.c:1731: Test failed: Expected #8: PathPointTypeLine (32.679489,20.000000) but got PathPointTypeLine (32.669998,20.000000) graphicspath.c:1731: Test failed: Expected #9: PathPointTypeLine | PathPointTypeCloseSubpath (32.679489,0.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (32.669998,0.000000)
=== debian11 (32 bit he:IL report) ===
gdiplus: graphicspath.c:1731: Test failed: Expected #5: PathPointTypeLine (22.320507,0.000000) but got PathPointTypeLine (22.330000,0.000000) graphicspath.c:1731: Test failed: Expected #6: PathPointTypeLine | PathPointTypeCloseSubpath (22.320507,20.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (22.330000,20.000000) graphicspath.c:1731: Test failed: Expected #8: PathPointTypeLine (32.679489,20.000000) but got PathPointTypeLine (32.669998,20.000000) graphicspath.c:1731: Test failed: Expected #9: PathPointTypeLine | PathPointTypeCloseSubpath (32.679489,0.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (32.669998,0.000000)
=== debian11 (32 bit hi:IN report) ===
gdiplus: graphicspath.c:1731: Test failed: Expected #5: PathPointTypeLine (22.320507,0.000000) but got PathPointTypeLine (22.330000,0.000000) graphicspath.c:1731: Test failed: Expected #6: PathPointTypeLine | PathPointTypeCloseSubpath (22.320507,20.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (22.330000,20.000000) graphicspath.c:1731: Test failed: Expected #8: PathPointTypeLine (32.679489,20.000000) but got PathPointTypeLine (32.669998,20.000000) graphicspath.c:1731: Test failed: Expected #9: PathPointTypeLine | PathPointTypeCloseSubpath (32.679489,0.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (32.669998,0.000000)
=== debian11 (32 bit ja:JP report) ===
gdiplus: graphicspath.c:1731: Test failed: Expected #5: PathPointTypeLine (22.320507,0.000000) but got PathPointTypeLine (22.330000,0.000000) graphicspath.c:1731: Test failed: Expected #6: PathPointTypeLine | PathPointTypeCloseSubpath (22.320507,20.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (22.330000,20.000000) graphicspath.c:1731: Test failed: Expected #8: PathPointTypeLine (32.679489,20.000000) but got PathPointTypeLine (32.669998,20.000000) graphicspath.c:1731: Test failed: Expected #9: PathPointTypeLine | PathPointTypeCloseSubpath (32.679489,0.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (32.669998,0.000000)
=== debian11 (32 bit zh:CN report) ===
gdiplus: graphicspath.c:1731: Test failed: Expected #5: PathPointTypeLine (22.320507,0.000000) but got PathPointTypeLine (22.330000,0.000000) graphicspath.c:1731: Test failed: Expected #6: PathPointTypeLine | PathPointTypeCloseSubpath (22.320507,20.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (22.330000,20.000000) graphicspath.c:1731: Test failed: Expected #8: PathPointTypeLine (32.679489,20.000000) but got PathPointTypeLine (32.669998,20.000000) graphicspath.c:1731: Test failed: Expected #9: PathPointTypeLine | PathPointTypeCloseSubpath (32.679489,0.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (32.669998,0.000000)
=== debian11b (32 bit WoW report) ===
gdiplus: graphicspath.c:1731: Test failed: Expected #5: PathPointTypeLine (22.320507,0.000000) but got PathPointTypeLine (22.330000,0.000000) graphicspath.c:1731: Test failed: Expected #6: PathPointTypeLine | PathPointTypeCloseSubpath (22.320507,20.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (22.330000,20.000000) graphicspath.c:1731: Test failed: Expected #8: PathPointTypeLine (32.679489,20.000000) but got PathPointTypeLine (32.669998,20.000000) graphicspath.c:1731: Test failed: Expected #9: PathPointTypeLine | PathPointTypeCloseSubpath (32.679489,0.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (32.669998,0.000000)
=== debian11b (64 bit WoW report) ===
gdiplus: graphicspath.c:1731: Test failed: Expected #5: PathPointTypeLine (22.320507,0.000000) but got PathPointTypeLine (22.330000,0.000000) graphicspath.c:1731: Test failed: Expected #6: PathPointTypeLine | PathPointTypeCloseSubpath (22.320507,20.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (22.330000,20.000000) graphicspath.c:1731: Test failed: Expected #8: PathPointTypeLine (32.679489,20.000000) but got PathPointTypeLine (32.669998,20.000000) graphicspath.c:1731: Test failed: Expected #9: PathPointTypeLine | PathPointTypeCloseSubpath (32.679489,0.000000) but got PathPointTypeLine | PathPointTypeCloseSubpath (32.669998,0.000000)