diff options
Diffstat (limited to 'gsk/gskcontour.c')
-rw-r--r-- | gsk/gskcontour.c | 240 |
1 files changed, 46 insertions, 194 deletions
diff --git a/gsk/gskcontour.c b/gsk/gskcontour.c index 359356d838..528540d2ad 100644 --- a/gsk/gskcontour.c +++ b/gsk/gskcontour.c @@ -21,6 +21,7 @@ #include "gskcontourprivate.h" +#include "gskcurveprivate.h" #include "gskpathbuilder.h" #include "gskpathprivate.h" #include "gsksplineprivate.h" @@ -1047,7 +1048,7 @@ typedef struct GskStandardContourMeasure measure; } LengthDecompose; -static void +static gboolean gsk_standard_contour_measure_add_point (const graphene_point_t *from, const graphene_point_t *to, float from_progress, @@ -1058,6 +1059,9 @@ gsk_standard_contour_measure_add_point (const graphene_point_t *from, float seg_length; seg_length = graphene_point_distance (from, to, NULL, NULL); + if (seg_length == 0) + return TRUE; + decomp->measure.end += seg_length; decomp->measure.start_progress = from_progress; decomp->measure.end_progress = to_progress; @@ -1066,6 +1070,8 @@ gsk_standard_contour_measure_add_point (const graphene_point_t *from, g_array_append_val (decomp->array, decomp->measure); decomp->measure.start += seg_length; + + return TRUE; } static gpointer @@ -1075,7 +1081,7 @@ gsk_standard_contour_init_measure (const GskContour *contour, { const GskStandardContour *self = (const GskStandardContour *) contour; gsize i; - float length, seg_length; + float length; GArray *array; array = g_array_new (FALSE, FALSE, sizeof (GskStandardContourMeasure)); @@ -1083,50 +1089,12 @@ gsk_standard_contour_init_measure (const GskContour *contour, for (i = 1; i < self->n_ops; i ++) { - const graphene_point_t *pt = gsk_pathop_points (self->ops[i]); - - switch (gsk_pathop_op (self->ops[i])) - { - case GSK_PATH_MOVE: - break; + GskCurve curve; + LengthDecompose decomp = { array, { length, length, 0, 0, { }, i } }; - case GSK_PATH_CLOSE: - case GSK_PATH_LINE: - seg_length = graphene_point_distance (&pt[0], &pt[1], NULL, NULL); - if (seg_length > 0) - { - g_array_append_vals (array, - &(GskStandardContourMeasure) { - length, - length + seg_length, - 0, 1, - pt[1], - i, - }, 1); - length += seg_length; - } - break; - - case GSK_PATH_CURVE: - { - LengthDecompose decomp = { array, { length, length, 0, 0, pt[0], i } }; - gsk_spline_decompose_cubic (pt, tolerance, gsk_standard_contour_measure_add_point, &decomp); - length = decomp.measure.start; - } - break; - - case GSK_PATH_CONIC: - { - LengthDecompose decomp = { array, { length, length, 0, 0, pt[0], i } }; - gsk_spline_decompose_conic (pt, tolerance, gsk_standard_contour_measure_add_point, &decomp); - length = decomp.measure.start; - } - break; - - default: - g_assert_not_reached(); - return NULL; - } + gsk_curve_init (&curve, self->ops[i]); + gsk_curve_decompose (&curve, tolerance, gsk_standard_contour_measure_add_point, &decomp); + length = decomp.measure.start; } *out_length = length; @@ -1163,35 +1131,11 @@ gsk_standard_contour_measure_get_point (GskStandardContour *self, graphene_point_t *pos, graphene_vec2_t *tangent) { - const graphene_point_t *pts; + GskCurve curve; - pts = gsk_pathop_points (self->ops[op]); - switch (gsk_pathop_op (self->ops[op])) - { - case GSK_PATH_LINE: - case GSK_PATH_CLOSE: - if (pos) - graphene_point_interpolate (&pts[0], &pts[1], progress, pos); - if (tangent) - { - graphene_vec2_init (tangent, pts[1].x - pts[0].x, pts[1].y - pts[0].y); - graphene_vec2_normalize (tangent, tangent); - } - break; - - case GSK_PATH_CURVE: - gsk_spline_get_point_cubic (pts, progress, pos, tangent); - break; - - case GSK_PATH_CONIC: - gsk_spline_get_point_conic (pts, progress, pos, tangent); - break; - - case GSK_PATH_MOVE: - default: - g_assert_not_reached (); - return; - } + gsk_curve_init (&curve, self->ops[op]); + + gsk_curve_eval (&curve, progress, pos, tangent); } static void @@ -1382,144 +1326,52 @@ gsk_standard_contour_add_segment (const GskContour *contour, * taking care that first and last operation might be identical */ if (start_measure) { - switch (gsk_pathop_op (self->ops[start_measure->op])) - { - case GSK_PATH_CLOSE: - case GSK_PATH_LINE: - { - const graphene_point_t *pts = gsk_pathop_points (self->ops[start_measure->op]); - graphene_point_t point; - - graphene_point_interpolate (&pts[0], &pts[1], start_progress, &point); - gsk_path_builder_move_to (builder, point.x, point.y); - if (end_measure && end_measure->op == start_measure->op) - { - graphene_point_interpolate (&pts[0], &pts[1], end_progress, &point); - gsk_path_builder_line_to (builder, point.x, point.y); - return; - } - gsk_path_builder_line_to (builder, pts[1].x, pts[1].y); - } - break; + GskCurve curve, cut; + const graphene_point_t *start_point; - case GSK_PATH_CURVE: - { - const graphene_point_t *pts = gsk_pathop_points (self->ops[start_measure->op]); - graphene_point_t curve[4], discard[4]; - - gsk_spline_split_cubic (pts, discard, curve, start_progress); - if (end_measure && end_measure->op == start_measure->op) - { - graphene_point_t tiny[4]; - gsk_spline_split_cubic (curve, tiny, discard, (end_progress - start_progress) / (1 - start_progress)); - gsk_path_builder_move_to (builder, tiny[0].x, tiny[0].y); - gsk_path_builder_curve_to (builder, tiny[1].x, tiny[1].y, tiny[2].x, tiny[2].y, tiny[3].x, tiny[3].y); - return; - } - gsk_path_builder_move_to (builder, curve[0].x, curve[0].y); - gsk_path_builder_curve_to (builder, curve[1].x, curve[1].y, curve[2].x, curve[2].y, curve[3].x, curve[3].y); - } - break; + gsk_curve_init (&curve, self->ops[start_measure->op]); - case GSK_PATH_CONIC: - { - const graphene_point_t *pts = gsk_pathop_points (self->ops[start_measure->op]); - graphene_point_t curve[4], discard[4]; - - gsk_spline_split_conic (pts, discard, curve, start_progress); - if (end_measure && end_measure->op == start_measure->op) - { - graphene_point_t tiny[4]; - gsk_spline_split_conic (curve, tiny, discard, (end_progress - start_progress) / (1 - start_progress)); - gsk_path_builder_move_to (builder, tiny[0].x, tiny[0].y); - gsk_path_builder_conic_to (builder, tiny[1].x, tiny[1].y, tiny[3].x, tiny[3].y, tiny[2].x); - return; - } - gsk_path_builder_move_to (builder, curve[0].x, curve[0].y); - gsk_path_builder_conic_to (builder, curve[1].x, curve[1].y, curve[3].x, curve[3].y, curve[2].x); - } - break; + gsk_curve_split (&curve, start_progress, NULL, &cut); + start_point = gsk_curve_get_start_point (&cut); + gsk_path_builder_move_to (builder, start_point->x, start_point->y); - case GSK_PATH_MOVE: - default: - g_assert_not_reached(); + if (end_measure && end_measure->op == start_measure->op) + { + GskCurve cut2; + + gsk_curve_split (&cut, (end_progress - start_progress) / (1 - start_progress), &cut2, NULL); + gsk_curve_builder_to (&cut2, builder); return; - } + } + + gsk_curve_builder_to (&cut, builder); i = start_measure->op + 1; } else i = 0; - for (; i < (end_measure ? end_measure->op : self->n_ops); i++) + for (; i < (end_measure ? end_measure->op : self->n_ops - 1); i++) { - const graphene_point_t *pt = gsk_pathop_points (self->ops[i]); - - switch (gsk_pathop_op (self->ops[i])) - { - case GSK_PATH_MOVE: - gsk_path_builder_move_to (builder, pt[0].x, pt[0].y); - break; - - case GSK_PATH_LINE: - case GSK_PATH_CLOSE: - gsk_path_builder_line_to (builder, pt[1].x, pt[1].y); - break; - - case GSK_PATH_CURVE: - gsk_path_builder_curve_to (builder, pt[1].x, pt[1].y, pt[2].x, pt[2].y, pt[3].x, pt[3].y); - break; - - case GSK_PATH_CONIC: - gsk_path_builder_conic_to (builder, pt[1].x, pt[1].y, pt[3].x, pt[3].y, pt[2].x); - break; - - default: - g_assert_not_reached(); - return; - } + gsk_path_builder_pathop_to (builder, self->ops[i]); } /* Add the last partial operation */ if (end_measure) { - switch (gsk_pathop_op (self->ops[end_measure->op])) - { - case GSK_PATH_CLOSE: - case GSK_PATH_LINE: - { - const graphene_point_t *pts = gsk_pathop_points (self->ops[end_measure->op]); - graphene_point_t point; - - graphene_point_interpolate (&pts[0], &pts[1], end_progress, &point); - gsk_path_builder_line_to (builder, point.x, point.y); - } - break; + GskCurve curve, cut; - case GSK_PATH_CURVE: - { - const graphene_point_t *pts = gsk_pathop_points (self->ops[end_measure->op]); - graphene_point_t curve[4], discard[4]; - - gsk_spline_split_cubic (pts, curve, discard, end_progress); - gsk_path_builder_curve_to (builder, curve[1].x, curve[1].y, curve[2].x, curve[2].y, curve[3].x, curve[3].y); - } - break; - - case GSK_PATH_CONIC: - { - const graphene_point_t *pts = gsk_pathop_points (self->ops[end_measure->op]); - graphene_point_t curve[4], discard[4]; + gsk_curve_init (&curve, self->ops[end_measure->op]); - gsk_spline_split_conic (pts, curve, discard, end_progress); - gsk_path_builder_conic_to (builder, curve[1].x, curve[1].y, curve[3].x, curve[3].y, curve[2].x); - } - break; - - case GSK_PATH_MOVE: - default: - g_assert_not_reached(); - return; - } + gsk_curve_split (&curve, end_progress, &cut, NULL); + gsk_curve_builder_to (&cut, builder); + } + else if (i == self->n_ops - 1) + { + gskpathop op = self->ops[i]; + if (gsk_pathop_op (op) == GSK_PATH_CLOSE) + gsk_path_builder_pathop_to (builder, gsk_pathop_encode (GSK_PATH_LINE, gsk_pathop_points (op))); + else + gsk_path_builder_pathop_to (builder, op); } } |