API: Add gsk_path_reverse
This is a natural operation, and useful for debugging things.
This commit is contained in:
@@ -97,6 +97,7 @@ struct _GskContourClass
|
||||
float distance,
|
||||
GskLineJoin line_join,
|
||||
float miter_limit);
|
||||
GskContour * (* reverse) (const GskContour *contour);
|
||||
};
|
||||
|
||||
static gsize
|
||||
@@ -557,6 +558,17 @@ gsk_rect_contour_offset (const GskContour *contour,
|
||||
gsk_contour_default_offset (contour, builder, distance, line_join, miter_limit);
|
||||
}
|
||||
|
||||
static GskContour *
|
||||
gsk_rect_contour_reverse (const GskContour *contour)
|
||||
{
|
||||
const GskRectContour *self = (const GskRectContour *) contour;
|
||||
|
||||
return gsk_rect_contour_new (&GRAPHENE_RECT_INIT (self->x + self->width,
|
||||
self->y,
|
||||
- self->width,
|
||||
self->height));
|
||||
}
|
||||
|
||||
static const GskContourClass GSK_RECT_CONTOUR_CLASS =
|
||||
{
|
||||
sizeof (GskRectContour),
|
||||
@@ -578,6 +590,7 @@ static const GskContourClass GSK_RECT_CONTOUR_CLASS =
|
||||
gsk_rect_contour_get_stroke_bounds,
|
||||
gsk_rect_contour_add_stroke,
|
||||
gsk_rect_contour_offset,
|
||||
gsk_rect_contour_reverse,
|
||||
};
|
||||
|
||||
GskContour *
|
||||
@@ -979,6 +992,17 @@ gsk_circle_contour_offset (const GskContour *contour,
|
||||
gsk_contour_default_offset (contour, builder, distance, line_join, miter_limit);
|
||||
}
|
||||
|
||||
static GskContour *
|
||||
gsk_circle_contour_reverse (const GskContour *contour)
|
||||
{
|
||||
const GskCircleContour *self = (const GskCircleContour *) contour;
|
||||
|
||||
return gsk_circle_contour_new (&self->center,
|
||||
self->radius,
|
||||
self->end_angle,
|
||||
self->start_angle);
|
||||
}
|
||||
|
||||
static const GskContourClass GSK_CIRCLE_CONTOUR_CLASS =
|
||||
{
|
||||
sizeof (GskCircleContour),
|
||||
@@ -1000,6 +1024,7 @@ static const GskContourClass GSK_CIRCLE_CONTOUR_CLASS =
|
||||
gsk_circle_contour_get_stroke_bounds,
|
||||
gsk_circle_contour_add_stroke,
|
||||
gsk_circle_contour_offset,
|
||||
gsk_circle_contour_reverse,
|
||||
};
|
||||
|
||||
GskContour *
|
||||
@@ -1642,7 +1667,7 @@ gsk_standard_contour_add_segment (const GskContour *contour,
|
||||
gsk_curve_builder_to (&cut, builder);
|
||||
i = start_measure->op + 1;
|
||||
}
|
||||
else
|
||||
else
|
||||
i = emit_move_to ? 0 : 1;
|
||||
|
||||
for (; i < (end_measure ? end_measure->op : self->n_ops - 1); i++)
|
||||
@@ -1802,6 +1827,59 @@ gsk_standard_contour_offset (const GskContour *contour,
|
||||
gsk_contour_default_offset (contour, builder, distance, line_join, miter_limit);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_reverse (GskPathOperation op,
|
||||
const graphene_point_t *pts,
|
||||
gsize n_pts,
|
||||
float weight,
|
||||
gpointer user_data)
|
||||
{
|
||||
GskPathBuilder *builder = user_data;
|
||||
GskCurve c, r;
|
||||
|
||||
if (op == GSK_PATH_MOVE)
|
||||
return TRUE;
|
||||
|
||||
if (op == GSK_PATH_CLOSE)
|
||||
op = GSK_PATH_LINE;
|
||||
|
||||
gsk_curve_init_foreach (&c, op, pts, n_pts, weight);
|
||||
gsk_curve_reverse (&c, &r);
|
||||
gsk_curve_builder_to (&r, builder);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GskContour *
|
||||
gsk_standard_contour_reverse (const GskContour *contour)
|
||||
{
|
||||
const GskStandardContour *self = (const GskStandardContour *) contour;
|
||||
GskPathBuilder *builder;
|
||||
GskPath *path;
|
||||
GskContour *res;
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
|
||||
gsk_path_builder_move_to (builder, self->points[self->n_points - 1].x,
|
||||
self->points[self->n_points - 1].y);
|
||||
|
||||
for (int i = self->n_ops - 1; i >= 0; i--)
|
||||
gsk_pathop_foreach (self->ops[i], add_reverse, builder);
|
||||
|
||||
if (self->flags & GSK_PATH_CLOSED)
|
||||
gsk_path_builder_close (builder);
|
||||
|
||||
path = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
g_assert (gsk_path_get_n_contours (path) == 1);
|
||||
|
||||
res = gsk_contour_dup (gsk_path_get_contour (path, 0));
|
||||
|
||||
gsk_path_unref (path);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static const GskContourClass GSK_STANDARD_CONTOUR_CLASS =
|
||||
{
|
||||
sizeof (GskStandardContour),
|
||||
@@ -1823,6 +1901,7 @@ static const GskContourClass GSK_STANDARD_CONTOUR_CLASS =
|
||||
gsk_standard_contour_get_stroke_bounds,
|
||||
gsk_standard_contour_add_stroke,
|
||||
gsk_standard_contour_offset,
|
||||
gsk_standard_contour_reverse,
|
||||
};
|
||||
|
||||
/* You must ensure the contour has enough size allocated,
|
||||
@@ -2038,3 +2117,8 @@ gsk_contour_dup (const GskContour *src)
|
||||
return copy;
|
||||
}
|
||||
|
||||
GskContour *
|
||||
gsk_contour_reverse (const GskContour *src)
|
||||
{
|
||||
return src->klass->reverse (src);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,8 @@ void gsk_contour_copy (GskContour *
|
||||
const GskContour *src);
|
||||
GskContour * gsk_contour_dup (const GskContour *src);
|
||||
|
||||
GskContour * gsk_contour_reverse (const GskContour *src);
|
||||
|
||||
gsize gsk_contour_get_size (const GskContour *self);
|
||||
GskPathFlags gsk_contour_get_flags (const GskContour *self);
|
||||
void gsk_contour_print (const GskContour *self,
|
||||
|
||||
@@ -1238,6 +1238,28 @@ gsk_path_get_stroke_bounds (GskPath *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_path_reverse:
|
||||
* @self: a `GskPath`
|
||||
*
|
||||
* Creates a path that traverses the same contours as
|
||||
* @self, in the opposite direction.
|
||||
*
|
||||
* Returns: the reverse of @self
|
||||
*/
|
||||
GskPath *
|
||||
gsk_path_reverse (GskPath *self)
|
||||
{
|
||||
GskPathBuilder *builder;
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
|
||||
for (int i = self->n_contours - 1; i >= 0; i--)
|
||||
gsk_path_builder_add_contour (builder, gsk_contour_reverse (gsk_path_get_contour (self, i)));
|
||||
|
||||
return gsk_path_builder_free_to_path (builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_path_stroke:
|
||||
* @self: a `GskPath`
|
||||
|
||||
@@ -110,6 +110,9 @@ gboolean gsk_path_foreach (GskPath
|
||||
GskPathForeachFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskPath * gsk_path_reverse (GskPath *self);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskPath * gsk_path_stroke (GskPath *self,
|
||||
GskStroke *stroke);
|
||||
|
||||
Reference in New Issue
Block a user