path: Allow limiting curve types in foreach

This is useful if your rendering system can't
handle certain kinds of curves, such as conics.
This commit is contained in:
Matthias Clasen
2020-12-09 19:07:37 -05:00
parent 3d06f5c1f2
commit 0a2ec0e050
2 changed files with 59 additions and 13 deletions

View File

@@ -421,6 +421,18 @@ gsk_path_foreach_trampoline_add_line (const graphene_point_t *from,
trampoline->user_data);
}
static gboolean
gsk_path_foreach_trampoline_add_curve (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer data)
{
GskPathForeachTrampoline *trampoline = data;
return trampoline->func (op, pts, n_pts, weight, trampoline->user_data);
}
static gboolean
gsk_path_foreach_trampoline (GskPathOperation op,
const graphene_point_t *pts,
@@ -431,22 +443,43 @@ gsk_path_foreach_trampoline (GskPathOperation op,
GskPathForeachTrampoline *trampoline = data;
switch (op)
{
{
case GSK_PATH_MOVE:
case GSK_PATH_CLOSE:
case GSK_PATH_LINE:
return trampoline->func (op, pts, n_pts, weight, trampoline->user_data);
case GSK_PATH_QUAD:
{
GskCurve curve;
if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_QUAD)
return trampoline->func (op, pts, n_pts, weight, trampoline->user_data);
gsk_curve_init (&curve, gsk_pathop_encode (GSK_PATH_QUAD, pts));
return gsk_curve_decompose (&curve,
trampoline->tolerance,
gsk_path_foreach_trampoline_add_line,
trampoline);
}
case GSK_PATH_CUBIC:
{
GskCurve curve;
if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_CUBIC)
return trampoline->func (op, pts, n_pts, weight, trampoline->user_data);
gsk_curve_init (&curve, gsk_pathop_encode (GSK_PATH_CUBIC, pts));
return gsk_curve_decompose (&curve,
if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_QUAD)
return gsk_curve_decompose_curve (&curve,
trampoline->flags,
trampoline->tolerance,
gsk_path_foreach_trampoline_add_curve,
trampoline);
return gsk_curve_decompose (&curve,
trampoline->tolerance,
gsk_path_foreach_trampoline_add_line,
trampoline);
@@ -454,14 +487,21 @@ gsk_path_foreach_trampoline (GskPathOperation op,
case GSK_PATH_CONIC:
{
GskCurve curve;
GskCurve curve;
if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_CONIC)
return trampoline->func (op, pts, n_pts, weight, trampoline->user_data);
/* XXX: decompose into curves if allowed */
gsk_curve_init (&curve, gsk_pathop_encode (GSK_PATH_CONIC, (graphene_point_t[4]) { pts[0], pts[1], { weight, }, pts[2] } ));
return gsk_curve_decompose (&curve,
if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_QUAD)
return gsk_curve_decompose_curve (&curve,
trampoline->flags,
trampoline->tolerance,
gsk_path_foreach_trampoline_add_curve,
trampoline);
return gsk_curve_decompose (&curve,
trampoline->tolerance,
gsk_path_foreach_trampoline_add_line,
trampoline);
@@ -471,9 +511,13 @@ gsk_path_foreach_trampoline (GskPathOperation op,
default:
g_assert_not_reached ();
return FALSE;
}
}
}
#define ALLOW_ANY (GSK_PATH_FOREACH_ALLOW_QUAD| \
GSK_PATH_FOREACH_ALLOW_CUBIC| \
GSK_PATH_FOREACH_ALLOW_CONIC)
gboolean
gsk_path_foreach_with_tolerance (GskPath *self,
GskPathForeachFlags flags,
@@ -485,7 +529,7 @@ gsk_path_foreach_with_tolerance (GskPath *self,
gsize i;
/* If we need to massage the data, set up a trampoline here */
if (flags != (GSK_PATH_FOREACH_ALLOW_CUBIC | GSK_PATH_FOREACH_ALLOW_CONIC))
if ((flags & ALLOW_ANY) != ALLOW_ANY)
{
trampoline = (GskPathForeachTrampoline) { flags, tolerance, func, user_data };
func = gsk_path_foreach_trampoline;

View File

@@ -31,10 +31,11 @@ G_BEGIN_DECLS
/**
* GskPathForeachFlags:
* @GSK_PATH_FOREACH_ALLOW_QUAD: Allow emission of %GSK_PATH_QUAD
* @GSK_PATH_FOREACH_ALLOW_CUBIC: Allow emission of %GSK_PATH_CUBIC
* operations.
* @GSK_PATH_FOREACH_ALLOW_CONIC: Allow emission of %GSK_PATH_CONIC
* operations.
* and %GSK_PATH_QUAD operations.
* @GSK_PATH_FOREACH_ALLOW_CONIC: Allow emission of %GSK_PATH_CONIC,
* %GSK_PATH_CUBIC and %GSK_PATH_QUAD operations.
*
* Flags that can be passed to gsk_path_foreach() to enable additional
* features.
@@ -45,8 +46,9 @@ G_BEGIN_DECLS
*/
typedef enum
{
GSK_PATH_FOREACH_ALLOW_CUBIC = (1 << 0),
GSK_PATH_FOREACH_ALLOW_CONIC = (1 << 1)
GSK_PATH_FOREACH_ALLOW_QUAD = (1 << 0),
GSK_PATH_FOREACH_ALLOW_CUBIC = (1 << 1),
GSK_PATH_FOREACH_ALLOW_CONIC = (1 << 2)
} GskPathForeachFlags;
/**