From 1da5cd6a8ff89742a506a52ea785216c73844529 Mon Sep 17 00:00:00 2001 From: Jeff Smith Date: Tue, 18 Feb 2020 23:51:59 -0600 Subject: [PATCH] gdiplus: Add LineCapSquareAnchor path widening. Signed-off-by: Jeff Smith Signed-off-by: Vincent Povirk Signed-off-by: Alexandre Julliard --- dlls/gdiplus/graphicspath.c | 50 +++++++++++++++++++++++++++++++++++++-- dlls/gdiplus/tests/graphicspath.c | 2 +- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 96078c3da9a..fcb2ed0b9eb 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -1983,6 +1983,44 @@ static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint, } } +static void add_anchor(const GpPointF *endpoint, const GpPointF *nextpoint, + GpPen *pen, GpLineCap cap, GpCustomLineCap *custom, path_list_node_t **last_point) +{ + switch (cap) + { + default: + case LineCapNoAnchor: + return; + case LineCapSquareAnchor: + { + 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 distance = pen->width / sqrtf(2.0); + REAL par_dx, par_dy; + REAL perp_dx, perp_dy; + + par_dx = -distance * segment_dx / segment_length; + par_dy = -distance * segment_dy / segment_length; + + perp_dx = -distance * segment_dy / segment_length; + perp_dy = distance * segment_dx / segment_length; + + *last_point = add_path_list_node(*last_point, endpoint->X - par_dx - perp_dx, + endpoint->Y - par_dy - perp_dy, PathPointTypeStart); + *last_point = add_path_list_node(*last_point, endpoint->X - par_dx + perp_dx, + endpoint->Y - par_dy + perp_dy, PathPointTypeLine); + *last_point = add_path_list_node(*last_point, endpoint->X + par_dx + perp_dx, + endpoint->Y + par_dy + perp_dy, PathPointTypeLine); + *last_point = add_path_list_node(*last_point, endpoint->X + par_dx - perp_dx, + endpoint->Y + par_dy - perp_dy, PathPointTypeLine); + break; + } + } + + (*last_point)->type |= PathPointTypeCloseSubpath; +} + static void widen_open_figure(const GpPointF *points, GpPen *pen, int start, int end, GpLineCap start_cap, GpCustomLineCap *start_custom, GpLineCap end_cap, GpCustomLineCap *end_custom, path_list_node_t **last_point) @@ -2014,6 +2052,14 @@ static void widen_open_figure(const GpPointF *points, GpPen *pen, int start, int prev_point->next->type = PathPointTypeStart; (*last_point)->type |= PathPointTypeCloseSubpath; + + if (start_cap & LineCapAnchorMask) + add_anchor(&points[start], &points[start+1], + pen, start_cap, start_custom, last_point); + + if (end_cap & LineCapAnchorMask) + add_anchor(&points[end], &points[end-1], + pen, end_cap, end_custom, last_point); } static void widen_closed_figure(GpPath *path, GpPen *pen, int start, int end, @@ -2225,10 +2271,10 @@ GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix, { last_point = points; - if (pen->endcap > LineCapTriangle) + if (pen->endcap > LineCapSquareAnchor) FIXME("unimplemented end cap %x\n", pen->endcap); - if (pen->startcap > LineCapTriangle) + if (pen->startcap > LineCapSquareAnchor) FIXME("unimplemented start cap %x\n", pen->startcap); if (pen->dashcap != DashCapFlat) diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index b8408017394..9ce95a2c74f 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -1385,7 +1385,7 @@ static void test_widen_cap(void) { LineCapNoAnchor, widenline_capflat_path, ARRAY_SIZE(widenline_capflat_path) }, { LineCapSquareAnchor, widenline_capsquareanchor_path, - ARRAY_SIZE(widenline_capsquareanchor_path), TRUE }, + ARRAY_SIZE(widenline_capsquareanchor_path) }, { LineCapRoundAnchor, widenline_caproundanchor_path, ARRAY_SIZE(widenline_caproundanchor_path), TRUE }, { LineCapDiamondAnchor, widenline_capdiamondanchor_path, -- 2.11.4.GIT