d2d1: Refactor outline generation as preparation for the new TYPE_END vertex type.
This is a preparative patch for the next change, behaviour is essentially unchanged, though it may be slightly faster. Rearrange code for outline segment and join generation so it will work for END_OPEN/END_CLOSED path, with coincident and disparate last/first vertex. Each vertex is now fetched once, and pivoted on the next iteration. Also move invariants in front of the loop, Path segments are drawn starting with the first segment, up to vertex_count - 2 (index of start vertex). Only in case of a END_CLOSED figure with non-coincident last/first vertex, also the last line segment is drawn. Joins are added between all drawn segments, and only for END_CLOSED also the join at the first vertex is added. Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
56f2d1c1a7
commit
065917d101
|
@ -2597,43 +2597,68 @@ static BOOL d2d_geometry_outline_add_arc_quadrant(struct d2d_geometry *geometry,
|
||||||
static BOOL d2d_geometry_add_figure_outline(struct d2d_geometry *geometry,
|
static BOOL d2d_geometry_add_figure_outline(struct d2d_geometry *geometry,
|
||||||
struct d2d_figure *figure, D2D1_FIGURE_END figure_end)
|
struct d2d_figure *figure, D2D1_FIGURE_END figure_end)
|
||||||
{
|
{
|
||||||
const D2D1_POINT_2F *prev, *p0, *next;
|
const D2D1_POINT_2F *prev, *p0, *p1, *next, *next_prev;
|
||||||
enum d2d_vertex_type prev_type, type;
|
size_t bezier_idx, i, vertex_count;
|
||||||
size_t bezier_idx, i;
|
enum d2d_vertex_type type;
|
||||||
|
|
||||||
for (i = 0, bezier_idx = 0; i < figure->vertex_count; ++i)
|
if (!(vertex_count = figure->vertex_count))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
p0 = &figure->vertices[0];
|
||||||
|
if (figure_end == D2D1_FIGURE_END_CLOSED)
|
||||||
{
|
{
|
||||||
type = figure->vertex_types[i];
|
/* In case of a CLOSED path, a join between first and last vertex is
|
||||||
if (type == D2D_VERTEX_TYPE_NONE)
|
* required. */
|
||||||
|
if (d2d_vertex_type_is_bezier(figure->vertex_types[vertex_count - 1]))
|
||||||
|
prev = &figure->bezier_controls[figure->bezier_control_count - 1];
|
||||||
|
else
|
||||||
|
prev = &figure->vertices[vertex_count - 1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!--vertex_count)
|
||||||
|
return TRUE;
|
||||||
|
prev = p0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0, bezier_idx = 0; i < vertex_count; ++i)
|
||||||
|
{
|
||||||
|
if ((type = figure->vertex_types[i]) == D2D_VERTEX_TYPE_NONE)
|
||||||
|
{
|
||||||
|
prev = next_prev = &figure->vertices[i];
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
p0 = &figure->vertices[i];
|
|
||||||
|
|
||||||
if (!i)
|
|
||||||
{
|
|
||||||
prev_type = figure->vertex_types[figure->vertex_count - 1];
|
|
||||||
if (d2d_vertex_type_is_bezier(prev_type))
|
|
||||||
prev = &figure->bezier_controls[figure->bezier_control_count - 1];
|
|
||||||
else
|
|
||||||
prev = &figure->vertices[figure->vertex_count - 1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prev_type = figure->vertex_types[i - 1];
|
|
||||||
if (d2d_vertex_type_is_bezier(prev_type))
|
|
||||||
prev = &figure->bezier_controls[bezier_idx - 1];
|
|
||||||
else
|
|
||||||
prev = &figure->vertices[i - 1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* next: tangent along next segment, at p0.
|
||||||
|
* p1: next vertex. */
|
||||||
if (d2d_vertex_type_is_bezier(type))
|
if (d2d_vertex_type_is_bezier(type))
|
||||||
next = &figure->bezier_controls[bezier_idx++];
|
{
|
||||||
else if (i == figure->vertex_count - 1)
|
next_prev = next = &figure->bezier_controls[bezier_idx++];
|
||||||
next = &figure->vertices[0];
|
/* type BEZIER implies i + 1 < figure->vertex_count. */
|
||||||
else
|
p1 = &figure->vertices[i + 1];
|
||||||
next = &figure->vertices[i + 1];
|
|
||||||
|
|
||||||
if (figure_end == D2D1_FIGURE_END_CLOSED || (i && i < figure->vertex_count - 1))
|
if (!d2d_geometry_outline_add_bezier_segment(geometry, p0, next, p1))
|
||||||
|
{
|
||||||
|
ERR("Failed to add bezier segment.\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (i + 1 == figure->vertex_count)
|
||||||
|
next = p1 = &figure->vertices[0];
|
||||||
|
else
|
||||||
|
next = p1 = &figure->vertices[i + 1];
|
||||||
|
next_prev = p0;
|
||||||
|
|
||||||
|
if (!d2d_geometry_outline_add_line_segment(geometry, p0, p1))
|
||||||
|
{
|
||||||
|
ERR("Failed to add line segment.\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i || figure_end == D2D1_FIGURE_END_CLOSED)
|
||||||
{
|
{
|
||||||
D2D1_POINT_2F q_next, q_prev;
|
D2D1_POINT_2F q_next, q_prev;
|
||||||
|
|
||||||
|
@ -2650,27 +2675,8 @@ static BOOL d2d_geometry_add_figure_outline(struct d2d_geometry *geometry,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == D2D_VERTEX_TYPE_LINE && (figure_end == D2D1_FIGURE_END_CLOSED || i < figure->vertex_count - 1)
|
p0 = p1;
|
||||||
&& !d2d_geometry_outline_add_line_segment(geometry, p0, next))
|
prev = next_prev;
|
||||||
{
|
|
||||||
ERR("Failed to add line segment.\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else if (d2d_vertex_type_is_bezier(type))
|
|
||||||
{
|
|
||||||
const D2D1_POINT_2F *p2;
|
|
||||||
|
|
||||||
if (i == figure->vertex_count - 1)
|
|
||||||
p2 = &figure->vertices[0];
|
|
||||||
else
|
|
||||||
p2 = &figure->vertices[i + 1];
|
|
||||||
|
|
||||||
if (!d2d_geometry_outline_add_bezier_segment(geometry, p0, next, p2))
|
|
||||||
{
|
|
||||||
ERR("Failed to add bezier segment.\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
Loading…
Reference in New Issue