[PATCH 08/12] d2d1: Add function for getting figure orientation.
Connor McAdams
conmanx360 at gmail.com
Mon Feb 24 20:32:19 CST 2020
Add a function for getting figure orientation to find the correct fill
side of a cubic bezier.
Signed-off-by: Connor McAdams <conmanx360 at gmail.com>
---
dlls/d2d1/geometry.c | 73 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 73 insertions(+)
diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c
index c9ea108484..a231bed986 100644
--- a/dlls/d2d1/geometry.c
+++ b/dlls/d2d1/geometry.c
@@ -2915,11 +2915,19 @@ struct d2d_cubic_triangles
D2D1_POINT_2F p[4];
};
+enum figure_orientation
+{
+ ORIENTATION_CW, /* Clockwise. */
+ ORIENTATION_CCW, /* Counter clockwise. */
+};
+
struct d2d_cubic_triangulation
{
struct d2d_cubic_triangles *cubic_tri;
size_t cubic_tri_count;
size_t cubic_tri_size;
+
+ unsigned int orientation;
};
static BOOL d2d_point_approximately_equal(const D2D1_POINT_2F *a, const D2D1_POINT_2F *b)
@@ -3151,6 +3159,69 @@ static HRESULT d2d_geometry_triangulate_beziers(struct d2d_geometry *geometry,
return S_OK;
}
+static float d2d_geometry_point_orientation(const D2D1_POINT_2F *a, const D2D1_POINT_2F *b)
+{
+ return (b->x - a->x) * (b->y + a->y);
+}
+
+static void d2d_geometry_get_figure_orientation(struct d2d_geometry *geometry,
+ struct d2d_cubic_triangulation *triangles)
+{
+ const struct d2d_figure *figure;
+ struct d2d_segment_idx idx;
+ struct d2d_cubic_triangulation *fig_tri;
+ enum d2d_vertex_type type;
+ const D2D1_POINT_2F *p[4];
+ float orientation;
+ size_t next;
+ unsigned int i;
+
+ for (idx.figure_idx = 0; idx.figure_idx < geometry->u.path.figure_count; ++idx.figure_idx)
+ {
+ figure = &geometry->u.path.figures[idx.figure_idx];
+ fig_tri = &triangles[idx.figure_idx];
+ orientation = 0.0f;
+
+ for (idx.vertex_idx = 0, idx.control_idx = 0; idx.vertex_idx < figure->vertex_count; ++idx.vertex_idx)
+ {
+ type = figure->vertex_types[idx.vertex_idx];
+ next = idx.vertex_idx + 1;
+ if (next == figure->vertex_count)
+ next = 0;
+
+ switch (type)
+ {
+ case D2D_VERTEX_TYPE_LINE:
+ p[0] = &figure->vertices[idx.vertex_idx];
+ p[1] = &figure->vertices[next];
+ orientation += d2d_geometry_point_orientation(p[0], p[1]);
+ break;
+
+ case D2D_VERTEX_TYPE_BEZIER:
+ case D2D_VERTEX_TYPE_SPLIT_BEZIER:
+ p[0] = &figure->vertices[idx.vertex_idx];
+ p[1] = &figure->bezier_controls[idx.control_idx].c0;
+ p[2] = &figure->bezier_controls[idx.control_idx++].c1;
+ p[3] = &figure->vertices[next];
+
+ for (i = 1; i < 4; i++)
+ orientation += d2d_geometry_point_orientation(p[i - 1], p[i]);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* Depending on orientation value, set either clockwise or
+ * counter-clockwise. */
+ if (orientation < 0.0f)
+ fig_tri->orientation = ORIENTATION_CW;
+ else
+ fig_tri->orientation = ORIENTATION_CCW;
+ }
+}
+
static BOOL d2d_geometry_check_bezier_overlap(struct d2d_geometry *geometry,
const struct d2d_segment_idx *idx_p, const struct d2d_segment_idx *idx_q)
{
@@ -3337,6 +3408,8 @@ static HRESULT d2d_geometry_resolve_beziers(struct d2d_geometry *geometry)
}
}
+ d2d_geometry_get_figure_orientation(geometry, triangles);
+
for (i = 0; i < geometry->u.path.figure_count; ++i)
{
if (geometry->u.path.figures[i].flags & D2D_FIGURE_FLAG_HOLLOW)
--
2.20.1
More information about the wine-devel
mailing list