From 845102fc22ca5f1070f0213be846b0e09fdd7bb1 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 28 Nov 2020 14:52:17 +0100 Subject: [PATCH] pathbuilder: Add relative path commands And gsk_path_builder_get_current_point(). They will be needed by the string parser. --- gsk/gskpathbuilder.c | 103 +++++++++++++++++++++++++++++++++++++++++++ gsk/gskpathbuilder.h | 19 ++++++++ 2 files changed, 122 insertions(+) diff --git a/gsk/gskpathbuilder.c b/gsk/gskpathbuilder.c index 05bbc3b7b5..bba6dff6d0 100644 --- a/gsk/gskpathbuilder.c +++ b/gsk/gskpathbuilder.c @@ -272,6 +272,25 @@ gsk_path_builder_add_contour (GskPathBuilder *builder, builder->contours = g_slist_prepend (builder->contours, contour); } +/** + * gsk_path_builder_get_current_point: + * @builder: a #GskPathBuilder + * + * Gets the current point. The current point is used for relative + * drawing commands and updated after every operation. + * + * When @builder is created, the default current point is set to (0, 0). + * + * Returns: (transfer none): The current point + **/ +const graphene_point_t * +gsk_path_builder_get_current_point (GskPathBuilder *builder) +{ + g_return_val_if_fail (builder != NULL, NULL); + + return &builder->current_point; +} + /** * gsk_path_builder_add_path: * @builder: a `GskPathBuilder` @@ -372,6 +391,29 @@ gsk_path_builder_move_to (GskPathBuilder *builder, gsk_path_builder_ensure_current (builder); } +/** + * gsk_path_builder_rel_move_to: + * @builder: a `GskPathBuilder` + * @x: x offset + * @y: y offset + * + * Starts a new contour by placing the pen at @x, @y relative to the current + * point. + * + * This is the relative version of [method@Gsk.PathBuilder.move_to]. + **/ +void +gsk_path_builder_rel_move_to (GskPathBuilder *builder, + float x, + float y) +{ + g_return_if_fail (builder != NULL); + + gsk_path_builder_move_to (builder, + builder->current_point.x + x, + builder->current_point.y + y); +} + /** * gsk_path_builder_line_to: * @builder: a `GskPathBuilder` @@ -400,6 +442,29 @@ gsk_path_builder_line_to (GskPathBuilder *builder, }); } +/** + * gsk_path_builder_rel_line_to: + * @builder: a `GskPathBuilder` + * @x: x offset + * @y: y offset + * + * Draws a line from the current point to a point offset to it by @x, @y + * and makes it the new current point. + * + * This is the relative version of [method@Gsk.PathBuilder.line_to]. + **/ +void +gsk_path_builder_rel_line_to (GskPathBuilder *builder, + float x, + float y) +{ + g_return_if_fail (builder != NULL); + + gsk_path_builder_line_to (builder, + builder->current_point.x + x, + builder->current_point.y + y); +} + /** * gsk_path_builder_curve_to: * @builder: a `GskPathBuilder` @@ -413,6 +478,8 @@ gsk_path_builder_line_to (GskPathBuilder *builder, * Adds a [cubic Bézier curve](https://en.wikipedia.org/wiki/B%C3%A9zier_curve) * from the current point to @x3, @y3 with @x1, @y1 and @x2, @y2 as the control * points. + * + * After this, @x3, @y3 will be the new current point. **/ void gsk_path_builder_curve_to (GskPathBuilder *builder, @@ -435,6 +502,42 @@ gsk_path_builder_curve_to (GskPathBuilder *builder, }); } +/** + * gsk_path_builder_rel_curve_to: + * @builder: a `GskPathBuilder` + * @x1: x offset of first control point + * @y1: y offset of first control point + * @x2: x offset of second control point + * @y2: y offset of second control point + * @x3: x offset of the end of the curve + * @y3: y offset of the end of the curve + * + * Adds a [cubic Bézier curve](https://en.wikipedia.org/wiki/B%C3%A9zier_curve) + * from the current point to @x3, @y3 with @x1, @y1 and @x2, @y2 as the control + * points. All coordinates are given relative to the current point. + * + * This is the relative version of [method@Gsk.PathBuilder.curve_to]. + **/ +void +gsk_path_builder_rel_curve_to (GskPathBuilder *builder, + float x1, + float y1, + float x2, + float y2, + float x3, + float y3) +{ + g_return_if_fail (builder != NULL); + + gsk_path_builder_curve_to (builder, + builder->current_point.x + x1, + builder->current_point.y + y1, + builder->current_point.x + x2, + builder->current_point.y + y2, + builder->current_point.x + x3, + builder->current_point.y + y3); +} + /** * gsk_path_builder_close: * @builder: a `GskPathBuilder` diff --git a/gsk/gskpathbuilder.h b/gsk/gskpathbuilder.h index 2bc7a3933d..4868ccf25e 100644 --- a/gsk/gskpathbuilder.h +++ b/gsk/gskpathbuilder.h @@ -45,6 +45,9 @@ GskPath * gsk_path_builder_free_to_path (GskPathBuilder GDK_AVAILABLE_IN_ALL GskPath * gsk_path_builder_to_path (GskPathBuilder *builder) G_GNUC_WARN_UNUSED_RESULT; +GDK_AVAILABLE_IN_ALL +const graphene_point_t *gsk_path_builder_get_current_point (GskPathBuilder *builder); + GDK_AVAILABLE_IN_ALL void gsk_path_builder_add_path (GskPathBuilder *builder, GskPath *path); @@ -61,10 +64,18 @@ void gsk_path_builder_move_to (GskPathBuilder float x, float y); GDK_AVAILABLE_IN_ALL +void gsk_path_builder_rel_move_to (GskPathBuilder *builder, + float x, + float y); +GDK_AVAILABLE_IN_ALL void gsk_path_builder_line_to (GskPathBuilder *builder, float x, float y); GDK_AVAILABLE_IN_ALL +void gsk_path_builder_rel_line_to (GskPathBuilder *builder, + float x, + float y); +GDK_AVAILABLE_IN_ALL void gsk_path_builder_curve_to (GskPathBuilder *builder, float x1, float y1, @@ -73,6 +84,14 @@ void gsk_path_builder_curve_to (GskPathBuilder float x3, float y3); GDK_AVAILABLE_IN_ALL +void gsk_path_builder_rel_curve_to (GskPathBuilder *builder, + float x1, + float y1, + float x2, + float y2, + float x3, + float y3); +GDK_AVAILABLE_IN_ALL void gsk_path_builder_close (GskPathBuilder *builder); G_END_DECLS