From 5dc0cbc20f0de92e18cd0cdef33fa56882afaaa0 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 24 Aug 2023 14:32:38 -0400 Subject: [PATCH] Expand the path docs a bit --- docs/reference/gsk/paths.md | 16 ++++++++++++++++ gsk/gskpath.c | 17 ++++++++++++----- gsk/gskpath.h | 25 +++++++++++++++++-------- 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/docs/reference/gsk/paths.md b/docs/reference/gsk/paths.md index 0cf5fdb9f1..dd672f888b 100644 --- a/docs/reference/gsk/paths.md +++ b/docs/reference/gsk/paths.md @@ -132,3 +132,19 @@ To obtain a `GskPathPoint`, use [method@Gsk.Path.get_closest_point], [method@Gsk To query properties of the path at a point, use [method@Gsk.PathPoint.get_position], [method@Gsk.PathPoint.get_tangent], [method@Gsk.PathPoint.get_rotation] and [method@Gsk.PathPoint.get_curvature]. + +## Going beyond GskPath + +Lots of powerful functionality can be implemented for paths: + +- Finding intersections +- Offsetting curves +- Molding curves (making them pass through a given point) + +GSK does not provide API for all of these, but it does offer a way to get at +the underlying Bézier curves, so you can implement such functionality yourself. +You can use [method@Gsk.Path.foreach] to iterate over the operations of the +path, and get the points needed to reconstruct or modify the path piece by piece. + +See e.g. the [Primer on Bézier curves](https://pomax.github.io/bezierinfo/) +for inspiration of useful things to explore. diff --git a/gsk/gskpath.c b/gsk/gskpath.c index 1f8d5059d7..8d4c5994f5 100644 --- a/gsk/gskpath.c +++ b/gsk/gskpath.c @@ -367,7 +367,7 @@ gsk_path_is_closed (GskPath *self) * If the path is empty, `FALSE` is returned and @bounds are set to * graphene_rect_zero(). This is different from the case where the path * is a single point at the origin, where the @bounds will also be set to - * the zero rectangle but 0 will be returned. + * the zero rectangle but `TRUE` will be returned. * * Returns: `TRUE` if the path has bounds, `FALSE` if the path is known * to be empty and have no bounds. @@ -616,10 +616,17 @@ gsk_path_get_closest_point (GskPath *self, * * Calls @func for every operation of the path. * - * Note that this only approximates @self, because paths can contain - * optimizations for various specialized contours, and depending on - * the @flags, the path may be decomposed into simpler curves than - * the ones that it contained originally. + * Note that this may only approximate @self, because paths can contain + * optimizations for various specialized contours, and depending on the + * @flags, the path may be decomposed into simpler curves than the ones + * that it contained originally. + * + * This function serves two purposes: + * + * - When the @flags allow everything, it provides access to the raw, + * unmodified data of the path. + * - When the @flags disallow certain operations, it provides + * an approximation of the path using just the allowed operations. * * Returns: `FALSE` if @func returned FALSE`, `TRUE` otherwise. * diff --git a/gsk/gskpath.h b/gsk/gskpath.h index 5ea38c29e2..b386984e96 100644 --- a/gsk/gskpath.h +++ b/gsk/gskpath.h @@ -35,12 +35,13 @@ G_BEGIN_DECLS * @GSK_PATH_FOREACH_ALLOW_CUBIC: Allow emission of `GSK_PATH_CUBIC` operations. * @GSK_PATH_FOREACH_ALLOW_ARC: Allow emission of `GSK_PATH_ARC` operations. * - * Flags that can be passed to gsk_path_foreach() to enable additional - * features. + * Flags that can be passed to gsk_path_foreach() to influence what + * kinds of operations the path is decomposed into. * - * By default, [method@Gsk.Path.foreach] will only emit a path with all operations - * flattened to straight lines to allow for maximum compatibility. The only - * operations emitted will be `GSK_PATH_MOVE`, `GSK_PATH_LINE` and `GSK_PATH_CLOSE`. + * By default, [method@Gsk.Path.foreach] will only emit a path with all + * operations flattened to straight lines to allow for maximum compatibility. + * The only operations emitted will be `GSK_PATH_MOVE`, `GSK_PATH_LINE` and + * `GSK_PATH_CLOSE`. * * Since: 4.14 */ @@ -54,15 +55,23 @@ typedef enum /** * GskPathForeachFunc: - * @op: The operation to perform + * @op: The operation * @pts: The points of the operation * @n_pts: The number of points * @user_data: The user data provided with the function * - * Prototype of the callback to iterate throught the operations of + * Prototype of the callback to iterate through the operations of * a path. * - * Returns: %TRUE to continue evaluating the path, %FALSE to + * For each operation, the callback is given the @op itself, + * and the points that the operation is applied to in @pts. The + * @n_pts argument is somewhat redundant, since the number of points + * can be inferred from the operation. + * + * Each contour of the path starts with a @GSK_PATH_MOVE operation. + * Closed contours end with a @GSK_PATH_CLOSE operation. + * + * Returns: %TRUE to continue iterating the path, %FALSE to * immediately abort and not call the function again. */ typedef gboolean (* GskPathForeachFunc) (GskPathOperation op,