Module: wine Branch: master Commit: 3895f07c4b45dae038d4d8424abc31c1030ebaf1 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3895f07c4b45dae038d4d8424a...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Wed Aug 16 21:58:25 2017 +0200
d2d1: Use segment indices in d2d_geometry_resolve_beziers().
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/d2d1/geometry.c | 105 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 71 insertions(+), 34 deletions(-)
diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c index 537f57f..8796323 100644 --- a/dlls/d2d1/geometry.c +++ b/dlls/d2d1/geometry.c @@ -2603,9 +2603,54 @@ static void d2d_path_geometry_free_figures(struct d2d_geometry *geometry) geometry->u.path.figures_size = 0; }
+static BOOL d2d_geometry_get_bezier_segment_idx(struct d2d_geometry *geometry, struct d2d_segment_idx *idx, BOOL next) +{ + if (next) + { + ++idx->vertex_idx; + ++idx->control_idx; + } + + for (; idx->figure_idx < geometry->u.path.figure_count; ++idx->figure_idx, idx->vertex_idx = idx->control_idx = 0) + { + struct d2d_figure *figure = &geometry->u.path.figures[idx->figure_idx]; + + if (!figure->bezier_control_count) + continue; + + for (; idx->vertex_idx < figure->vertex_count; ++idx->vertex_idx) + { + if (figure->vertex_types[idx->vertex_idx] == D2D_VERTEX_TYPE_BEZIER + || figure->vertex_types[idx->vertex_idx] == D2D_VERTEX_TYPE_SPLIT_BEZIER) + return TRUE; + } + } + + return FALSE; +} + +static BOOL d2d_geometry_get_first_bezier_segment_idx(struct d2d_geometry *geometry, struct d2d_segment_idx *idx) +{ + memset(idx, 0, sizeof(*idx)); + + return d2d_geometry_get_bezier_segment_idx(geometry, idx, FALSE); +} + +static BOOL d2d_geometry_get_next_bezier_segment_idx(struct d2d_geometry *geometry, struct d2d_segment_idx *idx) +{ + return d2d_geometry_get_bezier_segment_idx(geometry, idx, TRUE); +} + static HRESULT d2d_geometry_resolve_beziers(struct d2d_geometry *geometry) { - size_t bezier_idx, control_idx, i, j; + struct d2d_segment_idx idx_p; + struct d2d_bezier_vertex *b; + const D2D1_POINT_2F *p[3]; + struct d2d_figure *figure; + size_t bezier_idx, i; + + if (!d2d_geometry_get_first_bezier_segment_idx(geometry, &idx_p)) + return S_OK;
for (i = 0; i < geometry->u.path.figure_count; ++i) { @@ -2620,45 +2665,37 @@ static HRESULT d2d_geometry_resolve_beziers(struct d2d_geometry *geometry) return E_OUTOFMEMORY; }
- for (i = 0, bezier_idx = 0; i < geometry->u.path.figure_count; ++i) + bezier_idx = 0; + for (;;) { - struct d2d_figure *figure = &geometry->u.path.figures[i]; - if (figure->bezier_control_count) - { - for (j = 0, control_idx = 0; j < figure->vertex_count; ++j) - { - const D2D1_POINT_2F *p0, *p1, *p2; - struct d2d_bezier_vertex *b; - float sign = -1.0f; + float sign = -1.0f;
- if (figure->vertex_types[j] != D2D_VERTEX_TYPE_BEZIER - && figure->vertex_types[j] != D2D_VERTEX_TYPE_SPLIT_BEZIER) - continue; + figure = &geometry->u.path.figures[idx_p.figure_idx]; + p[0] = &figure->vertices[idx_p.vertex_idx]; + p[1] = &figure->bezier_controls[idx_p.control_idx];
- b = &geometry->fill.bezier_vertices[bezier_idx * 3]; - p0 = &figure->vertices[j]; - p1 = &figure->bezier_controls[control_idx++]; + i = idx_p.vertex_idx + 1; + if (d2d_path_geometry_point_inside(geometry, p[1], FALSE)) + { + sign = 1.0f; + d2d_figure_insert_vertex(figure, i, *p[1]); + /* Inserting a vertex potentially invalidates p[0]. */ + p[0] = &figure->vertices[idx_p.vertex_idx]; + ++i; + }
- if (d2d_path_geometry_point_inside(geometry, p1, FALSE)) - { - sign = 1.0f; - d2d_figure_insert_vertex(figure, j + 1, *p1); - /* Inserting a vertex potentially invalidates p0. */ - p0 = &figure->vertices[j]; - ++j; - } + if (i == figure->vertex_count) + i = 0; + p[2] = &figure->vertices[i];
- if (j == figure->vertex_count - 1) - p2 = &figure->vertices[0]; - else - p2 = &figure->vertices[j + 1]; + b = &geometry->fill.bezier_vertices[bezier_idx * 3]; + d2d_bezier_vertex_set(&b[0], p[0], 0.0f, 0.0f, sign); + d2d_bezier_vertex_set(&b[1], p[1], 0.5f, 0.0f, sign); + d2d_bezier_vertex_set(&b[2], p[2], 1.0f, 1.0f, sign);
- d2d_bezier_vertex_set(&b[0], p0, 0.0f, 0.0f, sign); - d2d_bezier_vertex_set(&b[1], p1, 0.5f, 0.0f, sign); - d2d_bezier_vertex_set(&b[2], p2, 1.0f, 1.0f, sign); - ++bezier_idx; - } - } + if (!d2d_geometry_get_next_bezier_segment_idx(geometry, &idx_p)) + break; + ++bezier_idx; }
return S_OK;