Signed-off-by: Connor McAdams conmanx360@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;