Commit 930cdab2 authored by Vincent Povirk's avatar Vincent Povirk Committed by Alexandre Julliard

gdiplus: Add basic implementation of GdipWidenPath.

parent 3a3ca55f
......@@ -1656,12 +1656,180 @@ GpStatus WINGDIPAPI GdipWarpPath(GpPath *path, GpMatrix* matrix,
return NotImplemented;
}
static void add_bevel_point(const GpPointF *endpoint, const GpPointF *nextpoint,
GpPen *pen, int right_side, path_list_node_t **last_point)
{
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/2.0;
REAL bevel_dx, bevel_dy;
if (right_side)
{
bevel_dx = -distance * segment_dy / segment_length;
bevel_dy = distance * segment_dx / segment_length;
}
else
{
bevel_dx = distance * segment_dy / segment_length;
bevel_dy = -distance * segment_dx / segment_length;
}
*last_point = add_path_list_node(*last_point, endpoint->X + bevel_dx,
endpoint->Y + bevel_dy, PathPointTypeLine);
}
static void widen_joint(const GpPointF *p1, const GpPointF *p2, const GpPointF *p3,
GpPen* pen, path_list_node_t **last_point)
{
switch (pen->join)
{
default:
case LineJoinBevel:
add_bevel_point(p2, p1, pen, 1, last_point);
add_bevel_point(p2, p3, pen, 0, last_point);
break;
}
}
static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint,
GpPen *pen, GpLineCap cap, GpCustomLineCap *custom, int add_first_points,
int add_last_point, path_list_node_t **last_point)
{
switch (cap)
{
default:
case LineCapFlat:
if (add_first_points)
add_bevel_point(endpoint, nextpoint, pen, 1, last_point);
if (add_last_point)
add_bevel_point(endpoint, nextpoint, pen, 0, last_point);
break;
}
}
static void widen_open_figure(GpPath *path, GpPen *pen, int start, int end,
path_list_node_t **last_point)
{
int i;
if (end <= start)
return;
widen_cap(&path->pathdata.Points[start], &path->pathdata.Points[start+1],
pen, pen->startcap, pen->customstart, FALSE, TRUE, last_point);
(*last_point)->type = PathPointTypeStart;
for (i=start+1; i<end; i++)
widen_joint(&path->pathdata.Points[i-1], &path->pathdata.Points[i],
&path->pathdata.Points[i+1], pen, last_point);
widen_cap(&path->pathdata.Points[end], &path->pathdata.Points[end-1],
pen, pen->endcap, pen->customend, TRUE, TRUE, last_point);
for (i=end-1; i>start; i--)
widen_joint(&path->pathdata.Points[i+1], &path->pathdata.Points[i],
&path->pathdata.Points[i-1], pen, last_point);
widen_cap(&path->pathdata.Points[start], &path->pathdata.Points[start+1],
pen, pen->startcap, pen->customstart, TRUE, FALSE, last_point);
(*last_point)->type |= PathPointTypeCloseSubpath;
}
GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix,
REAL flatness)
{
FIXME("(%p,%p,%p,%0.2f)\n", path, pen, matrix, flatness);
GpPath *flat_path=NULL;
GpStatus status;
path_list_node_t *points=NULL, *last_point=NULL;
int i, subpath_start=0, new_length;
BYTE type;
return NotImplemented;
TRACE("(%p,%p,%p,%0.2f)\n", path, pen, matrix, flatness);
if (!path || !pen)
return InvalidParameter;
if (path->pathdata.Count <= 1)
return OutOfMemory;
status = GdipClonePath(path, &flat_path);
if (status == Ok)
status = GdipFlattenPath(flat_path, matrix, flatness);
if (status == Ok && !init_path_list(&points, 314.0, 22.0))
status = OutOfMemory;
if (status == Ok)
{
last_point = points;
if (pen->endcap != LineCapFlat)
FIXME("unimplemented end cap %x\n", pen->endcap);
if (pen->startcap != LineCapFlat)
FIXME("unimplemented start cap %x\n", pen->startcap);
if (pen->dashcap != DashCapFlat)
FIXME("unimplemented dash cap %d\n", pen->dashcap);
if (pen->join != LineJoinBevel)
FIXME("unimplemented line join %d\n", pen->join);
if (pen->dash != DashStyleSolid)
FIXME("unimplemented dash style %d\n", pen->dash);
if (pen->align != PenAlignmentCenter)
FIXME("unimplemented pen alignment %d\n", pen->align);
for (i=0; i < flat_path->pathdata.Count; i++)
{
type = flat_path->pathdata.Types[i];
if ((type&PathPointTypePathTypeMask) == PathPointTypeStart)
subpath_start = i;
if ((type&PathPointTypeCloseSubpath) == PathPointTypeCloseSubpath)
{
FIXME("closed figures unimplemented\n");
}
else if (i == flat_path->pathdata.Count-1 ||
(flat_path->pathdata.Types[i+1]&PathPointTypePathTypeMask) == PathPointTypeStart)
{
widen_open_figure(flat_path, pen, subpath_start, i, &last_point);
}
}
new_length = path_list_count(points)-1;
if (!lengthen_path(path, new_length))
status = OutOfMemory;
}
if (status == Ok)
{
path->pathdata.Count = new_length;
last_point = points->next;
for (i = 0; i < new_length; i++)
{
path->pathdata.Points[i] = last_point->pt;
path->pathdata.Types[i] = last_point->type;
last_point = last_point->next;
}
path->fill = FillModeWinding;
}
free_path_list(points);
GdipDeletePath(flat_path);
return status;
}
GpStatus WINGDIPAPI GdipAddPathRectangle(GpPath *path, REAL x, REAL y,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment