[PATCH 6/8] d2d1: Use segment indices in d2d_geometry_resolve_beziers().

Henri Verbeet hverbeet at codeweavers.com
Wed Aug 16 14:58:25 CDT 2017


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 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;
-- 
2.1.4




More information about the wine-patches mailing list