[RFC PATCH 5/5] d2d1: Update apply_intersections for cubic beziers.
Connor McAdams
conmanx360 at gmail.com
Sun Mar 15 14:42:58 CDT 2020
Signed-off-by: Connor McAdams <conmanx360 at gmail.com>
---
dlls/d2d1/geometry.c | 84 ++++++++++++++++++++++++++++++++++----------
1 file changed, 66 insertions(+), 18 deletions(-)
diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c
index dd6f50bbec..154741a364 100644
--- a/dlls/d2d1/geometry.c
+++ b/dlls/d2d1/geometry.c
@@ -830,6 +830,26 @@ static BOOL d2d_figure_add_quadratic_bezier_control(struct d2d_figure *figure, c
return TRUE;
}
+static BOOL d2d_figure_insert_cubic_bezier_control(struct d2d_figure *figure, size_t idx, const D2D1_POINT_2F *c0,
+ const D2D1_POINT_2F *c1)
+{
+ if (!d2d_array_reserve((void **)&figure->bezier_controls, &figure->bezier_controls_size,
+ figure->bezier_control_points + 2, sizeof(*figure->bezier_controls)))
+ {
+ ERR("Failed to grow bezier controls array.\n");
+ return FALSE;
+ }
+
+ memmove(&figure->bezier_controls[idx + 2], &figure->bezier_controls[idx],
+ (figure->bezier_control_count - idx) * sizeof(*figure->bezier_controls));
+ figure->bezier_controls[idx] = *c0;
+ figure->bezier_controls[idx + 1] = *c1;
+ figure->bezier_control_points += 2;
+ ++figure->bezier_control_count;
+
+ return TRUE;
+}
+
static void d2d_cdt_edge_rot(struct d2d_cdt_edge_ref *dst, const struct d2d_cdt_edge_ref *src)
{
dst->idx = src->idx;
@@ -2237,8 +2257,9 @@ static BOOL d2d_geometry_apply_intersections(struct d2d_geometry *geometry,
size_t vertex_offset, control_offset, next, i;
struct d2d_geometry_intersection *inter;
enum d2d_vertex_type vertex_type;
- const D2D1_POINT_2F *p[3];
+ const D2D1_POINT_2F *p[4];
struct d2d_figure *figure;
+ D2D1_BEZIER_SEGMENT left, right;
D2D1_POINT_2F q[2];
float t, t_prev;
@@ -2272,25 +2293,52 @@ static BOOL d2d_geometry_apply_intersections(struct d2d_geometry *geometry,
t = (t - t_prev) / (1.0f - t_prev);
}
- p[0] = &figure->vertices[inter->vertex_idx + vertex_offset];
- p[1] = &figure->bezier_controls[inter->control_idx + control_offset];
- next = inter->vertex_idx + vertex_offset + 1;
- if (next == figure->vertex_count)
- next = 0;
- p[2] = &figure->vertices[next];
-
- d2d_point_lerp(&q[0], p[0], p[1], t);
- d2d_point_lerp(&q[1], p[1], p[2], t);
+ if (vertex_type == D2D_VERTEX_TYPE_CUBIC_BEZIER || vertex_type == D2D_VERTEX_TYPE_SPLIT_CUBIC_BEZIER)
+ {
+ p[0] = &figure->vertices[inter->vertex_idx + vertex_offset];
+ p[1] = &figure->bezier_controls[inter->control_idx + control_offset];
+ p[2] = &figure->bezier_controls[inter->control_idx + control_offset + 1];
+ next = inter->vertex_idx + vertex_offset + 1;
+ if (next == figure->vertex_count)
+ next = 0;
+ p[3] = &figure->vertices[next];
+
+ d2d_bezier_split_cubic(p[0], p[1], p[2], p[3], t, &left, &right, NULL);
+
+ figure->bezier_controls[inter->control_idx + control_offset] = left.point1;
+ figure->bezier_controls[inter->control_idx + control_offset + 1] = left.point2;
+ if (!(d2d_figure_insert_cubic_bezier_control(figure, inter->control_idx + control_offset + 1, &right.point1,
+ &right.point2)))
+ return FALSE;
+ control_offset += 2;
- figure->bezier_controls[inter->control_idx + control_offset] = q[0];
- if (!(d2d_figure_insert_quadratic_bezier_control(figure, inter->control_idx + control_offset + 1, &q[1])))
- return FALSE;
- ++control_offset;
+ if (!(d2d_figure_insert_vertex(figure, inter->vertex_idx + vertex_offset + 1, inter->p)))
+ return FALSE;
+ figure->vertex_types[inter->vertex_idx + vertex_offset + 1] = D2D_VERTEX_TYPE_SPLIT_CUBIC_BEZIER;
+ ++vertex_offset;
+ }
+ else
+ {
+ p[0] = &figure->vertices[inter->vertex_idx + vertex_offset];
+ p[1] = &figure->bezier_controls[inter->control_idx + control_offset];
+ next = inter->vertex_idx + vertex_offset + 1;
+ if (next == figure->vertex_count)
+ next = 0;
+ p[2] = &figure->vertices[next];
+
+ d2d_point_lerp(&q[0], p[0], p[1], t);
+ d2d_point_lerp(&q[1], p[1], p[2], t);
+
+ figure->bezier_controls[inter->control_idx + control_offset] = q[0];
+ if (!(d2d_figure_insert_quadratic_bezier_control(figure, inter->control_idx + control_offset + 1, &q[1])))
+ return FALSE;
+ ++control_offset;
- if (!(d2d_figure_insert_vertex(figure, inter->vertex_idx + vertex_offset + 1, inter->p)))
- return FALSE;
- figure->vertex_types[inter->vertex_idx + vertex_offset + 1] = D2D_VERTEX_TYPE_SPLIT_QUAD_BEZIER;
- ++vertex_offset;
+ if (!(d2d_figure_insert_vertex(figure, inter->vertex_idx + vertex_offset + 1, inter->p)))
+ return FALSE;
+ figure->vertex_types[inter->vertex_idx + vertex_offset + 1] = D2D_VERTEX_TYPE_SPLIT_QUAD_BEZIER;
+ ++vertex_offset;
+ }
}
return TRUE;
--
2.20.1
More information about the wine-devel
mailing list