From 0c2f43d1bd4ca151fb204575775e8a3ab8bd56b1 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 6 Dec 2020 23:13:56 -0500 Subject: [PATCH] curve: Add gsk_curve_get_{start,end}_tangent Add a way to get the tangents at the start and end of the curve. This will be used in stroking. --- gsk/gskcurve.c | 78 +++++++++++++++++++++++++++++++++++++++++++ gsk/gskcurveprivate.h | 4 +++ 2 files changed, 82 insertions(+) diff --git a/gsk/gskcurve.c b/gsk/gskcurve.c index 55346e76fb..594e07a4fd 100644 --- a/gsk/gskcurve.c +++ b/gsk/gskcurve.c @@ -44,10 +44,23 @@ struct _GskCurveClass gskpathop (* pathop) (const GskCurve *curve); const graphene_point_t * (* get_start_point) (const GskCurve *curve); const graphene_point_t * (* get_end_point) (const GskCurve *curve); + void (* get_start_tangent) (const GskCurve *curve, + graphene_vec2_t *tangent); + void (* get_end_tangent) (const GskCurve *curve, + graphene_vec2_t *tangent); }; /* {{{ Line implementation */ +static void +get_tangent (const graphene_point_t *p0, + const graphene_point_t *p1, + graphene_vec2_t *t) +{ + graphene_vec2_init (t, p1->x - p0->x, p1->y - p0->y); + graphene_vec2_normalize (t, t); +} + static void gsk_line_curve_init_from_points (GskLineCurve *self, GskPathOperation op, @@ -139,6 +152,15 @@ gsk_line_curve_get_end_point (const GskCurve *curve) return &self->points[1]; } +static void +gsk_line_curve_get_tangent (const GskCurve *curve, + graphene_vec2_t *tangent) +{ + const GskLineCurve *self = &curve->line; + + get_tangent (&self->points[0], &self->points[1], tangent); +} + static const GskCurveClass GSK_LINE_CURVE_CLASS = { gsk_line_curve_init, gsk_line_curve_eval, @@ -147,6 +169,8 @@ static const GskCurveClass GSK_LINE_CURVE_CLASS = { gsk_line_curve_pathop, gsk_line_curve_get_start_point, gsk_line_curve_get_end_point, + gsk_line_curve_get_tangent, + gsk_line_curve_get_tangent }; /* }}} */ @@ -312,6 +336,24 @@ gsk_curve_curve_get_end_point (const GskCurve *curve) return &self->points[3]; } +static void +gsk_curve_curve_get_start_tangent (const GskCurve *curve, + graphene_vec2_t *tangent) +{ + const GskCurveCurve *self = &curve->curve; + + get_tangent (&self->points[0], &self->points[1], tangent); +} + +static void +gsk_curve_curve_get_end_tangent (const GskCurve *curve, + graphene_vec2_t *tangent) +{ + const GskCurveCurve *self = &curve->curve; + + get_tangent (&self->points[2], &self->points[3], tangent); +} + static const GskCurveClass GSK_CURVE_CURVE_CLASS = { gsk_curve_curve_init, gsk_curve_curve_eval, @@ -320,6 +362,8 @@ static const GskCurveClass GSK_CURVE_CURVE_CLASS = { gsk_curve_curve_pathop, gsk_curve_curve_get_start_point, gsk_curve_curve_get_end_point, + gsk_curve_curve_get_start_tangent, + gsk_curve_curve_get_end_tangent }; /* }}} */ @@ -626,6 +670,24 @@ gsk_conic_curve_get_end_point (const GskCurve *curve) return &self->points[3]; } +static void +gsk_conic_curve_get_start_tangent (const GskCurve *curve, + graphene_vec2_t *tangent) +{ + const GskConicCurve *self = &curve->conic; + + get_tangent (&self->points[0], &self->points[1], tangent); +} + +static void +gsk_conic_curve_get_end_tangent (const GskCurve *curve, + graphene_vec2_t *tangent) +{ + const GskConicCurve *self = &curve->conic; + + get_tangent (&self->points[1], &self->points[3], tangent); +} + static const GskCurveClass GSK_CONIC_CURVE_CLASS = { gsk_conic_curve_init, gsk_conic_curve_eval, @@ -634,6 +696,8 @@ static const GskCurveClass GSK_CONIC_CURVE_CLASS = { gsk_conic_curve_pathop, gsk_conic_curve_get_start_point, gsk_conic_curve_get_end_point, + gsk_conic_curve_get_start_tangent, + gsk_conic_curve_get_end_tangent }; /* }}} */ @@ -706,6 +770,20 @@ gsk_curve_get_end_point (const GskCurve *curve) return get_class (curve->op)->get_end_point (curve); } +void +gsk_curve_get_start_tangent (const GskCurve *curve, + graphene_vec2_t *tangent) +{ + get_class (curve->op)->get_start_tangent (curve, tangent); +} + +void +gsk_curve_get_end_tangent (const GskCurve *curve, + graphene_vec2_t *tangent) +{ + get_class (curve->op)->get_end_tangent (curve, tangent); +} + /* }}} */ /* vim:set foldmethod=marker expandtab: */ diff --git a/gsk/gskcurveprivate.h b/gsk/gskcurveprivate.h index 720ee71f1c..0f4e89d2c5 100644 --- a/gsk/gskcurveprivate.h +++ b/gsk/gskcurveprivate.h @@ -98,6 +98,10 @@ gskpathop gsk_curve_pathop (const GskCurve #define gsk_curve_builder_to(curve, builder) gsk_path_builder_pathop_to ((builder), gsk_curve_pathop (curve)) const graphene_point_t *gsk_curve_get_start_point (const GskCurve *curve); const graphene_point_t *gsk_curve_get_end_point (const GskCurve *curve); +void gsk_curve_get_start_tangent (const GskCurve *curve, + graphene_vec2_t *tangent); +void gsk_curve_get_end_tangent (const GskCurve *curve, + graphene_vec2_t *tangent);