gdiplus: Add LineCapSquareAnchor path widening.

Signed-off-by: Jeff Smith <whydoubt@gmail.com>
Signed-off-by: Vincent Povirk <vincent@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jeff Smith 2020-02-18 23:51:59 -06:00 committed by Alexandre Julliard
parent b3a68db9a0
commit 1da5cd6a8f
2 changed files with 49 additions and 3 deletions

View file

@ -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)

View file

@ -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,