Signed-off-by: Jeff Smith whydoubt@gmail.com --- Note: LineCapArrowAnchor and LineCapCustom implementations are not in this series as they are still WIP.
dlls/gdiplus/tests/graphicspath.c | 179 ++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+)
diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index 096fbc600a..e12d9e2c49 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -1245,6 +1245,184 @@ static void test_widen(void) GdipDeletePath(path); }
+static path_test_t widenline_capflat_path[] = { + {5.0, 5.0, PathPointTypeStart, 0, 0}, /*0*/ + {50.0, 5.0, PathPointTypeLine, 0, 0}, /*1*/ + {50.0, 15.0, PathPointTypeLine, 0, 0}, /*2*/ + {5.0, 15.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0} /*3*/ + }; + +static path_test_t widenline_capsquare_path[] = { + {0.0, 5.0, PathPointTypeStart, 0, 0}, /*0*/ + {55.0, 5.0, PathPointTypeLine, 0, 0}, /*1*/ + {55.0, 15.0, PathPointTypeLine, 0, 0}, /*2*/ + {0.0, 15.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0} /*3*/ + }; + +static path_test_t widenline_capround_path[] = { + {5.0, 5.0, PathPointTypeStart, 0, 2}, /*0*/ + {50.0, 5.0, PathPointTypeLine, 0, 1}, /*1*/ + {52.761421, 5.0, PathPointTypeBezier, 0, 0}, /*2*/ + {55.0, 7.238576, PathPointTypeBezier, 0, 0}, /*3*/ + {55.0, 10.0, PathPointTypeBezier, 0, 0}, /*4*/ + {55.0, 12.761423, PathPointTypeBezier, 0, 0}, /*5*/ + {52.761421, 15.0, PathPointTypeBezier, 0, 0}, /*6*/ + {50.0, 15.0, PathPointTypeBezier, 0, 0}, /*7*/ + {5.0, 15.0, PathPointTypeLine, 0, 0}, /*8*/ + {2.238576, 15.0, PathPointTypeBezier, 0, 0}, /*9*/ + {0.0, 12.761423, PathPointTypeBezier, 0, 0}, /*10*/ + {0.0, 10.0, PathPointTypeBezier, 0, 0}, /*11*/ + {0.0, 7.238576, PathPointTypeBezier, 0, 0}, /*12*/ + {2.238576, 5.0, PathPointTypeBezier, 0, 0}, /*13*/ + {5.0, 5.0, PathPointTypeBezier|PathPointTypeCloseSubpath, 0, 0}, /*14*/ + }; + +static path_test_t widenline_captriangle_path[] = { + {5.0, 5.0, PathPointTypeStart, 0, 0}, /*0*/ + {50.0, 5.0, PathPointTypeLine, 0, 0}, /*1*/ + {55.0, 10.0, PathPointTypeLine, 0, 0}, /*2*/ + {50.0, 15.0, PathPointTypeLine, 0, 0}, /*3*/ + {5.0, 15.0, PathPointTypeLine, 0, 0}, /*4*/ + {0.0, 10.0, PathPointTypeLine, 0, 1}, /*5*/ + {5.0, 5.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 2} /*6*/ + }; + +static path_test_t widenline_capsquareanchor_path[] = { + {5.0, 5.0, PathPointTypeStart, 0, 0}, /*0*/ + {50.0, 5.0, PathPointTypeLine, 0, 0}, /*1*/ + {50.0, 15.0, PathPointTypeLine, 0, 0}, /*2*/ + {5.0, 15.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*3*/ + {12.071068, 2.928932, PathPointTypeStart, 0, 0}, /*4*/ + {12.071068, 17.071066, PathPointTypeLine, 0, 0}, /*5*/ + {-2.071068, 17.071066, PathPointTypeLine, 0, 0}, /*6*/ + {-2.071068, 2.928932, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*7*/ + {42.928928, 17.071068, PathPointTypeStart, 0, 0}, /*8*/ + {42.928928, 2.928932, PathPointTypeLine, 0, 0}, /*9*/ + {57.071068, 2.928932, PathPointTypeLine, 0, 0}, /*10*/ + {57.071068, 17.071068, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*11*/ + }; + +static path_test_t widenline_caproundanchor_path[] = { + {5.0, 5.0, PathPointTypeStart, 0, 0}, /*0*/ + {50.0, 5.0, PathPointTypeLine, 0, 0}, /*1*/ + {50.0, 15.0, PathPointTypeLine, 0, 0}, /*2*/ + {5.0, 15.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*3*/ + {5.0, 20.0, PathPointTypeStart, 0, 0}, /*4*/ + {-0.522847, 20.0, PathPointTypeBezier, 0, 0}, /*5*/ + {-5.0, 15.522846, PathPointTypeBezier, 0, 0}, /*6*/ + {-5.0, 10.0, PathPointTypeBezier, 0, 0}, /*7*/ + {-5.0, 4.477152, PathPointTypeBezier, 0, 0}, /*8*/ + {-0.522847, 0.0, PathPointTypeBezier, 0, 0}, /*9*/ + {5.0, 0.0, PathPointTypeBezier, 0, 0}, /*10*/ + {10.522847, 0.0, PathPointTypeBezier, 0, 0}, /*11*/ + {15.0, 4.477152, PathPointTypeBezier, 0, 0}, /*12*/ + {15.0, 10.0, PathPointTypeBezier, 0, 0}, /*13*/ + {15.0, 15.522846, PathPointTypeBezier, 0, 0}, /*14*/ + {10.522847, 20.0, PathPointTypeBezier, 0, 0}, /*15*/ + {5.0, 20.0, PathPointTypeBezier|PathPointTypeCloseSubpath, 0, 0}, /*16*/ + {50.0, 0.0, PathPointTypeStart, 0, 0}, /*17*/ + {55.522846, 0.0, PathPointTypeBezier, 0, 0}, /*18*/ + {60.0, 4.477153, PathPointTypeBezier, 0, 0}, /*19*/ + {60.0, 10.0, PathPointTypeBezier, 0, 0}, /*20*/ + {60.0, 15.522847, PathPointTypeBezier, 0, 0}, /*21*/ + {55.522846, 20.0, PathPointTypeBezier, 0, 0}, /*22*/ + {50.0, 20.0, PathPointTypeBezier, 0, 0}, /*23*/ + {44.477150, 20.0, PathPointTypeBezier, 0, 0}, /*24*/ + {40.0, 15.522847, PathPointTypeBezier, 0, 0}, /*25*/ + {40.0, 10.0, PathPointTypeBezier, 0, 0}, /*26*/ + {40.0, 4.477153, PathPointTypeBezier, 0, 0}, /*27*/ + {44.477150, 0.0, PathPointTypeBezier, 0, 0}, /*28*/ + {50.0, 0.0, PathPointTypeBezier|PathPointTypeCloseSubpath, 0, 0}, /*29*/ + }; + +static path_test_t widenline_capdiamondanchor_path[] = { + {5.0, 5.0, PathPointTypeStart, 0, 0}, /*0*/ + {50.0, 5.0, PathPointTypeLine, 0, 0}, /*1*/ + {50.0, 15.0, PathPointTypeLine, 0, 0}, /*2*/ + {5.0, 15.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*3*/ + {-5.0, 10.0, PathPointTypeStart, 0, 0}, /*4*/ + {5.0, 0.0, PathPointTypeLine, 0, 0}, /*5*/ + {15.0, 10.0, PathPointTypeLine, 0, 0}, /*6*/ + {5.0, 20.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*7*/ + {60.0, 10.0, PathPointTypeStart, 0, 0}, /*8*/ + {50.0, 20.0, PathPointTypeLine, 0, 0}, /*9*/ + {40.0, 10.0, PathPointTypeLine, 0, 0}, /*10*/ + {50.0, 0.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*11*/ + }; + +static path_test_t widenline_caparrowanchor_path[] = { + {15.0, 5.0, PathPointTypeStart, 0, 1}, /*0*/ + {40.0, 5.0, PathPointTypeLine, 0, 1}, /*1*/ + {40.0, 15.0, PathPointTypeLine, 0, 1}, /*2*/ + {15.0, 15.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 1}, /*3*/ + {5.0, 10.0, PathPointTypeStart, 0, 0}, /*4*/ + {22.320507, 0.0, PathPointTypeLine, 0, 0}, /*5*/ + {22.320507, 20.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*6*/ + {50.0, 10.0, PathPointTypeStart, 0, 0}, /*7*/ + {32.679489, 20.0, PathPointTypeLine, 0, 0}, /*8*/ + {32.679489, 0.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*9*/ + }; + +static void test_widen_cap(void) +{ + struct + { + LineCap type; + const path_test_t *expected; + INT expected_size; + BOOL todo_size; + } + caps[] = + { + { LineCapFlat, widenline_capflat_path, + ARRAY_SIZE(widenline_capflat_path) }, + { LineCapSquare, widenline_capsquare_path, + ARRAY_SIZE(widenline_capsquare_path) }, + { LineCapRound, widenline_capround_path, + ARRAY_SIZE(widenline_capround_path), TRUE }, + { LineCapTriangle, widenline_captriangle_path, + ARRAY_SIZE(widenline_captriangle_path), TRUE }, + { LineCapNoAnchor, widenline_capflat_path, + ARRAY_SIZE(widenline_capflat_path) }, + { LineCapSquareAnchor, widenline_capsquareanchor_path, + ARRAY_SIZE(widenline_capsquareanchor_path), TRUE }, + { LineCapRoundAnchor, widenline_caproundanchor_path, + ARRAY_SIZE(widenline_caproundanchor_path), TRUE }, + { LineCapDiamondAnchor, widenline_capdiamondanchor_path, + ARRAY_SIZE(widenline_capdiamondanchor_path), TRUE }, + { LineCapArrowAnchor, widenline_caparrowanchor_path, + ARRAY_SIZE(widenline_caparrowanchor_path), TRUE }, + }; + GpStatus status; + GpPath *path; + GpPen *pen; + int i; + + status = GdipCreatePath(FillModeAlternate, &path); + expect(Ok, status); + status = GdipCreatePen1(0xffffffff, 10.0, UnitPixel, &pen); + expect(Ok, status); + + for (i = 0; i < ARRAY_SIZE(caps); i++) + { + status = GdipResetPath(path); + expect(Ok, status); + status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0); + expect(Ok, status); + status = GdipSetPenStartCap(pen, caps[i].type); + expect(Ok, status); + status = GdipSetPenEndCap(pen, caps[i].type); + expect(Ok, status); + + status = GdipWidenPath(path, pen, NULL, FlatnessDefault); + expect(Ok, status); + ok_path(path, caps[i].expected, caps[i].expected_size, caps[i].todo_size); + } + + GdipDeletePen(pen); + GdipDeletePath(path); +} + static void test_isvisible(void) { GpPath *path; @@ -1385,6 +1563,7 @@ START_TEST(graphicspath) test_addpie(); test_flatten(); test_widen(); + test_widen_cap(); test_isvisible(); test_empty_rect();
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/graphicspath.c | 2 ++ dlls/gdiplus/tests/graphicspath.c | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 7ec6061cb4..5ea82f4d0e 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -1955,6 +1955,8 @@ static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint, *last_point = add_path_list_node(*last_point, endpoint->X - dy, endpoint->Y + dx, PathPointTypeBezier); } + else if (add_last_point) + add_bevel_point(endpoint, nextpoint, pen, 0, last_point); break; } case LineCapTriangle: diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index e12d9e2c49..91b83166ad 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -1260,8 +1260,8 @@ static path_test_t widenline_capsquare_path[] = { };
static path_test_t widenline_capround_path[] = { - {5.0, 5.0, PathPointTypeStart, 0, 2}, /*0*/ - {50.0, 5.0, PathPointTypeLine, 0, 1}, /*1*/ + {5.0, 5.0, PathPointTypeStart, 0, 0}, /*0*/ + {50.0, 5.0, PathPointTypeLine, 0, 0}, /*1*/ {52.761421, 5.0, PathPointTypeBezier, 0, 0}, /*2*/ {55.0, 7.238576, PathPointTypeBezier, 0, 0}, /*3*/ {55.0, 10.0, PathPointTypeBezier, 0, 0}, /*4*/ @@ -1379,7 +1379,7 @@ static void test_widen_cap(void) { LineCapSquare, widenline_capsquare_path, ARRAY_SIZE(widenline_capsquare_path) }, { LineCapRound, widenline_capround_path, - ARRAY_SIZE(widenline_capround_path), TRUE }, + ARRAY_SIZE(widenline_capround_path) }, { LineCapTriangle, widenline_captriangle_path, ARRAY_SIZE(widenline_captriangle_path), TRUE }, { LineCapNoAnchor, widenline_capflat_path,
Signed-off-by: Vincent Povirk vincent@codeweavers.com
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/graphicspath.c | 2 +- dlls/gdiplus/tests/graphicspath.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 5ea82f4d0e..96078c3da9 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -1976,7 +1976,7 @@ static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint, *last_point = add_path_list_node(*last_point, endpoint->X - dx, endpoint->Y - dy, PathPointTypeLine); } - if (add_last_point) + if (add_first_points || add_last_point) add_bevel_point(endpoint, nextpoint, pen, 0, last_point); break; } diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index 91b83166ad..b840801739 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -1283,8 +1283,8 @@ static path_test_t widenline_captriangle_path[] = { {55.0, 10.0, PathPointTypeLine, 0, 0}, /*2*/ {50.0, 15.0, PathPointTypeLine, 0, 0}, /*3*/ {5.0, 15.0, PathPointTypeLine, 0, 0}, /*4*/ - {0.0, 10.0, PathPointTypeLine, 0, 1}, /*5*/ - {5.0, 5.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 2} /*6*/ + {0.0, 10.0, PathPointTypeLine, 0, 0}, /*5*/ + {5.0, 5.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0} /*6*/ };
static path_test_t widenline_capsquareanchor_path[] = { @@ -1381,7 +1381,7 @@ static void test_widen_cap(void) { LineCapRound, widenline_capround_path, ARRAY_SIZE(widenline_capround_path) }, { LineCapTriangle, widenline_captriangle_path, - ARRAY_SIZE(widenline_captriangle_path), TRUE }, + ARRAY_SIZE(widenline_captriangle_path) }, { LineCapNoAnchor, widenline_capflat_path, ARRAY_SIZE(widenline_capflat_path) }, { LineCapSquareAnchor, widenline_capsquareanchor_path,
Signed-off-by: Vincent Povirk vincent@codeweavers.com
Signed-off-by: Jeff Smith whydoubt@gmail.com --- 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 96078c3da9..fcb2ed0b9e 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 b840801739..9ce95a2c74 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,
Signed-off-by: Vincent Povirk vincent@codeweavers.com
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/graphicspath.c | 56 +++++++++++++++++++++++++++++-- dlls/gdiplus/tests/graphicspath.c | 2 +- 2 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index fcb2ed0b9e..79d99a3eb4 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -2016,6 +2016,58 @@ static void add_anchor(const GpPointF *endpoint, const GpPointF *nextpoint, endpoint->Y + par_dy - perp_dy, PathPointTypeLine); break; } + case LineCapRoundAnchor: + { + 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 dx, dy, dx2, dy2; + const REAL control_point_distance = 0.55228475; /* 4/3 * (sqrt(2) - 1) */ + + dx = -pen->width * segment_dx / segment_length; + dy = -pen->width * segment_dy / segment_length; + + dx2 = dx * control_point_distance; + dy2 = dy * control_point_distance; + + /* starting point */ + *last_point = add_path_list_node(*last_point, endpoint->X + dy, + endpoint->Y - dx, PathPointTypeStart); + + /* first 90-degree arc */ + *last_point = add_path_list_node(*last_point, endpoint->X + dy + dx2, + endpoint->Y - dx + dy2, PathPointTypeBezier); + *last_point = add_path_list_node(*last_point, endpoint->X + dx + dy2, + endpoint->Y + dy - dx2, PathPointTypeBezier); + *last_point = add_path_list_node(*last_point, endpoint->X + dx, + endpoint->Y + dy, PathPointTypeBezier); + + /* second 90-degree arc */ + *last_point = add_path_list_node(*last_point, endpoint->X + dx - dy2, + endpoint->Y + dy + dx2, PathPointTypeBezier); + *last_point = add_path_list_node(*last_point, endpoint->X - dy + dx2, + endpoint->Y + dx + dy2, PathPointTypeBezier); + *last_point = add_path_list_node(*last_point, endpoint->X - dy, + endpoint->Y + dx, PathPointTypeBezier); + + /* third 90-degree arc */ + *last_point = add_path_list_node(*last_point, endpoint->X - dy - dx2, + endpoint->Y + dx - dy2, PathPointTypeBezier); + *last_point = add_path_list_node(*last_point, endpoint->X - dx - dy2, + endpoint->Y - dy + dx2, PathPointTypeBezier); + *last_point = add_path_list_node(*last_point, endpoint->X - dx, + endpoint->Y - dy, PathPointTypeBezier); + + /* fourth 90-degree arc */ + *last_point = add_path_list_node(*last_point, endpoint->X - dx + dy2, + endpoint->Y - dy - dx2, PathPointTypeBezier); + *last_point = add_path_list_node(*last_point, endpoint->X + dy - dx2, + endpoint->Y - dx - dy2, PathPointTypeBezier); + *last_point = add_path_list_node(*last_point, endpoint->X + dy, + endpoint->Y - dx, PathPointTypeBezier); + + break; + } }
(*last_point)->type |= PathPointTypeCloseSubpath; @@ -2271,10 +2323,10 @@ GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix, { last_point = points;
- if (pen->endcap > LineCapSquareAnchor) + if (pen->endcap > LineCapRoundAnchor) FIXME("unimplemented end cap %x\n", pen->endcap);
- if (pen->startcap > LineCapSquareAnchor) + if (pen->startcap > LineCapRoundAnchor) 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 9ce95a2c74..6acfddd53e 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -1387,7 +1387,7 @@ static void test_widen_cap(void) { LineCapSquareAnchor, widenline_capsquareanchor_path, ARRAY_SIZE(widenline_capsquareanchor_path) }, { LineCapRoundAnchor, widenline_caproundanchor_path, - ARRAY_SIZE(widenline_caproundanchor_path), TRUE }, + ARRAY_SIZE(widenline_caproundanchor_path) }, { LineCapDiamondAnchor, widenline_capdiamondanchor_path, ARRAY_SIZE(widenline_capdiamondanchor_path), TRUE }, { LineCapArrowAnchor, widenline_caparrowanchor_path,
Signed-off-by: Vincent Povirk vincent@codeweavers.com
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/gdiplus/graphicspath.c | 28 ++++++++++++++++++++++++++-- dlls/gdiplus/tests/graphicspath.c | 2 +- 2 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index 79d99a3eb4..249f584089 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -2068,6 +2068,30 @@ static void add_anchor(const GpPointF *endpoint, const GpPointF *nextpoint,
break; } + case LineCapDiamondAnchor: + { + 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, par_dy; + REAL perp_dx, perp_dy; + + par_dx = -pen->width * segment_dx / segment_length; + par_dy = -pen->width * segment_dy / segment_length; + + perp_dx = -pen->width * segment_dy / segment_length; + perp_dy = pen->width * segment_dx / segment_length; + + *last_point = add_path_list_node(*last_point, endpoint->X + par_dx, + endpoint->Y + par_dy, PathPointTypeStart); + *last_point = add_path_list_node(*last_point, endpoint->X - perp_dx, + endpoint->Y - perp_dy, PathPointTypeLine); + *last_point = add_path_list_node(*last_point, endpoint->X - par_dx, + endpoint->Y - par_dy, PathPointTypeLine); + *last_point = add_path_list_node(*last_point, endpoint->X + perp_dx, + endpoint->Y + perp_dy, PathPointTypeLine); + break; + } }
(*last_point)->type |= PathPointTypeCloseSubpath; @@ -2323,10 +2347,10 @@ GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix, { last_point = points;
- if (pen->endcap > LineCapRoundAnchor) + if (pen->endcap > LineCapDiamondAnchor) FIXME("unimplemented end cap %x\n", pen->endcap);
- if (pen->startcap > LineCapRoundAnchor) + if (pen->startcap > LineCapDiamondAnchor) 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 6acfddd53e..aabacef3aa 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -1389,7 +1389,7 @@ static void test_widen_cap(void) { LineCapRoundAnchor, widenline_caproundanchor_path, ARRAY_SIZE(widenline_caproundanchor_path) }, { LineCapDiamondAnchor, widenline_capdiamondanchor_path, - ARRAY_SIZE(widenline_capdiamondanchor_path), TRUE }, + ARRAY_SIZE(widenline_capdiamondanchor_path) }, { LineCapArrowAnchor, widenline_caparrowanchor_path, ARRAY_SIZE(widenline_caparrowanchor_path), TRUE }, };
Signed-off-by: Vincent Povirk vincent@codeweavers.com