pathbuilder: Redo semantics for starting curves
We now always have a "current point" which is either the last point an operation was made to, or (0, 0) if no drawing operation has been made yet. Adding a contour of any kind to the builder will always update the current point to that contour's end point.
This commit is contained in:
committed by
Matthias Clasen
parent
e8750af295
commit
924f036667
@@ -44,6 +44,9 @@ struct _GskContourClass
|
|||||||
GString *string);
|
GString *string);
|
||||||
gboolean (* get_bounds) (const GskContour *contour,
|
gboolean (* get_bounds) (const GskContour *contour,
|
||||||
graphene_rect_t *bounds);
|
graphene_rect_t *bounds);
|
||||||
|
void (* get_start_end) (const GskContour *self,
|
||||||
|
graphene_point_t *start,
|
||||||
|
graphene_point_t *end);
|
||||||
gboolean (* foreach) (const GskContour *contour,
|
gboolean (* foreach) (const GskContour *contour,
|
||||||
float tolerance,
|
float tolerance,
|
||||||
GskPathForeachFunc func,
|
GskPathForeachFunc func,
|
||||||
@@ -211,6 +214,20 @@ gsk_rect_contour_get_bounds (const GskContour *contour,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsk_rect_contour_get_start_end (const GskContour *contour,
|
||||||
|
graphene_point_t *start,
|
||||||
|
graphene_point_t *end)
|
||||||
|
{
|
||||||
|
const GskRectContour *self = (const GskRectContour *) contour;
|
||||||
|
|
||||||
|
if (start)
|
||||||
|
*start = GRAPHENE_POINT_INIT (self->x, self->y);
|
||||||
|
|
||||||
|
if (end)
|
||||||
|
*end = GRAPHENE_POINT_INIT (self->x, self->y);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gsk_rect_contour_foreach (const GskContour *contour,
|
gsk_rect_contour_foreach (const GskContour *contour,
|
||||||
float tolerance,
|
float tolerance,
|
||||||
@@ -469,6 +486,7 @@ static const GskContourClass GSK_RECT_CONTOUR_CLASS =
|
|||||||
gsk_rect_contour_get_flags,
|
gsk_rect_contour_get_flags,
|
||||||
gsk_rect_contour_print,
|
gsk_rect_contour_print,
|
||||||
gsk_rect_contour_get_bounds,
|
gsk_rect_contour_get_bounds,
|
||||||
|
gsk_rect_contour_get_start_end,
|
||||||
gsk_rect_contour_foreach,
|
gsk_rect_contour_foreach,
|
||||||
gsk_rect_contour_init_measure,
|
gsk_rect_contour_init_measure,
|
||||||
gsk_rect_contour_free_measure,
|
gsk_rect_contour_free_measure,
|
||||||
@@ -561,6 +579,20 @@ gsk_circle_contour_get_bounds (const GskContour *contour,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsk_circle_contour_get_start_end (const GskContour *contour,
|
||||||
|
graphene_point_t *start,
|
||||||
|
graphene_point_t *end)
|
||||||
|
{
|
||||||
|
const GskCircleContour *self = (const GskCircleContour *) contour;
|
||||||
|
|
||||||
|
if (start)
|
||||||
|
*start = GSK_CIRCLE_POINT_INIT (self, self->start_angle);
|
||||||
|
|
||||||
|
if (end)
|
||||||
|
*end = GSK_CIRCLE_POINT_INIT (self, self->end_angle);
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GskPathForeachFunc func;
|
GskPathForeachFunc func;
|
||||||
@@ -755,6 +787,7 @@ static const GskContourClass GSK_CIRCLE_CONTOUR_CLASS =
|
|||||||
gsk_circle_contour_get_flags,
|
gsk_circle_contour_get_flags,
|
||||||
gsk_circle_contour_print,
|
gsk_circle_contour_print,
|
||||||
gsk_circle_contour_get_bounds,
|
gsk_circle_contour_get_bounds,
|
||||||
|
gsk_circle_contour_get_start_end,
|
||||||
gsk_circle_contour_foreach,
|
gsk_circle_contour_foreach,
|
||||||
gsk_circle_contour_init_measure,
|
gsk_circle_contour_init_measure,
|
||||||
gsk_circle_contour_free_measure,
|
gsk_circle_contour_free_measure,
|
||||||
@@ -941,6 +974,20 @@ gsk_standard_contour_get_bounds (const GskContour *contour,
|
|||||||
return bounds->size.width > 0 && bounds->size.height > 0;
|
return bounds->size.width > 0 && bounds->size.height > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsk_standard_contour_get_start_end (const GskContour *contour,
|
||||||
|
graphene_point_t *start,
|
||||||
|
graphene_point_t *end)
|
||||||
|
{
|
||||||
|
const GskStandardContour *self = (const GskStandardContour *) contour;
|
||||||
|
|
||||||
|
if (start)
|
||||||
|
*start = self->points[0];
|
||||||
|
|
||||||
|
if (end)
|
||||||
|
*end = self->points[self->n_points - 1];
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
float start;
|
float start;
|
||||||
@@ -1395,6 +1442,7 @@ static const GskContourClass GSK_STANDARD_CONTOUR_CLASS =
|
|||||||
gsk_standard_contour_get_flags,
|
gsk_standard_contour_get_flags,
|
||||||
gsk_standard_contour_print,
|
gsk_standard_contour_print,
|
||||||
gsk_standard_contour_get_bounds,
|
gsk_standard_contour_get_bounds,
|
||||||
|
gsk_standard_contour_get_start_end,
|
||||||
gsk_standard_contour_foreach,
|
gsk_standard_contour_foreach,
|
||||||
gsk_standard_contour_init_measure,
|
gsk_standard_contour_init_measure,
|
||||||
gsk_standard_contour_free_measure,
|
gsk_standard_contour_free_measure,
|
||||||
@@ -1481,6 +1529,14 @@ gsk_contour_free_measure (GskPath *path,
|
|||||||
self->klass->free_measure (self, data);
|
self->klass->free_measure (self, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gsk_contour_get_start_end (const GskContour *self,
|
||||||
|
graphene_point_t *start,
|
||||||
|
graphene_point_t *end)
|
||||||
|
{
|
||||||
|
self->klass->get_start_end (self, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_contour_get_point (GskPath *path,
|
gsk_contour_get_point (GskPath *path,
|
||||||
gsize i,
|
gsize i,
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ struct _GskPathBuilder
|
|||||||
GSList *contours; /* (reverse) list of already recorded contours */
|
GSList *contours; /* (reverse) list of already recorded contours */
|
||||||
|
|
||||||
GskPathFlags flags; /* flags for the current path */
|
GskPathFlags flags; /* flags for the current path */
|
||||||
|
graphene_point_t current_point; /* the point all drawing ops start from */
|
||||||
GArray *ops; /* operations for current contour - size == 0 means no current contour */
|
GArray *ops; /* operations for current contour - size == 0 means no current contour */
|
||||||
GArray *points; /* points for the operations */
|
GArray *points; /* points for the operations */
|
||||||
};
|
};
|
||||||
@@ -97,6 +98,10 @@ gsk_path_builder_new (void)
|
|||||||
|
|
||||||
builder->ops = g_array_new (FALSE, FALSE, sizeof (GskStandardOperation));
|
builder->ops = g_array_new (FALSE, FALSE, sizeof (GskStandardOperation));
|
||||||
builder->points = g_array_new (FALSE, FALSE, sizeof (graphene_point_t));
|
builder->points = g_array_new (FALSE, FALSE, sizeof (graphene_point_t));
|
||||||
|
|
||||||
|
/* Be explicit here */
|
||||||
|
builder->current_point = GRAPHENE_POINT_INIT (0, 0);
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,18 +128,29 @@ gsk_path_builder_ref (GskPathBuilder *builder)
|
|||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsk_path_builder_ensure_current (GskPathBuilder *builder)
|
||||||
|
{
|
||||||
|
if (builder->ops->len != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
builder->flags = GSK_PATH_FLAT;
|
||||||
|
g_array_append_vals (builder->ops, &(GskStandardOperation) { GSK_PATH_MOVE, 0 }, 1);
|
||||||
|
g_array_append_val (builder->points, builder->current_point);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_path_builder_append_current (GskPathBuilder *builder,
|
gsk_path_builder_append_current (GskPathBuilder *builder,
|
||||||
GskPathOperation op,
|
GskPathOperation op,
|
||||||
gsize n_points,
|
gsize n_points,
|
||||||
const graphene_point_t *points)
|
const graphene_point_t *points)
|
||||||
{
|
{
|
||||||
g_assert (builder->ops->len > 0);
|
gsk_path_builder_ensure_current (builder);
|
||||||
g_assert (builder->points->len > 0);
|
|
||||||
g_assert (n_points > 0);
|
|
||||||
|
|
||||||
g_array_append_vals (builder->ops, &(GskStandardOperation) { op, builder->points->len - 1 }, 1);
|
g_array_append_vals (builder->ops, &(GskStandardOperation) { op, builder->points->len - 1 }, 1);
|
||||||
g_array_append_vals (builder->points, points, n_points);
|
g_array_append_vals (builder->points, points, n_points);
|
||||||
|
|
||||||
|
builder->current_point = points[n_points - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -303,6 +319,8 @@ gsk_path_builder_add_rect (GskPathBuilder *builder,
|
|||||||
|
|
||||||
contour = gsk_rect_contour_new (rect);
|
contour = gsk_rect_contour_new (rect);
|
||||||
gsk_path_builder_add_contour (builder, contour);
|
gsk_path_builder_add_contour (builder, contour);
|
||||||
|
|
||||||
|
gsk_contour_get_start_end (contour, NULL, &builder->current_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -349,9 +367,9 @@ gsk_path_builder_move_to (GskPathBuilder *builder,
|
|||||||
|
|
||||||
gsk_path_builder_end_current (builder);
|
gsk_path_builder_end_current (builder);
|
||||||
|
|
||||||
builder->flags = GSK_PATH_FLAT;
|
builder->current_point = GRAPHENE_POINT_INIT(x, y);
|
||||||
g_array_append_vals (builder->ops, &(GskStandardOperation) { GSK_PATH_MOVE, 0 }, 1);
|
|
||||||
g_array_append_val (builder->points, GRAPHENE_POINT_INIT(x, y));
|
gsk_path_builder_ensure_current (builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -370,14 +388,8 @@ gsk_path_builder_line_to (GskPathBuilder *builder,
|
|||||||
{
|
{
|
||||||
g_return_if_fail (builder != NULL);
|
g_return_if_fail (builder != NULL);
|
||||||
|
|
||||||
if (builder->ops->len == 0)
|
|
||||||
{
|
|
||||||
gsk_path_builder_move_to (builder, x, y);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* skip the line if it goes to the same point */
|
/* skip the line if it goes to the same point */
|
||||||
if (graphene_point_equal (&g_array_index (builder->points, graphene_point_t, builder->points->len - 1),
|
if (graphene_point_equal (&builder->current_point,
|
||||||
&GRAPHENE_POINT_INIT (x, y)))
|
&GRAPHENE_POINT_INIT (x, y)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -413,9 +425,6 @@ gsk_path_builder_curve_to (GskPathBuilder *builder,
|
|||||||
{
|
{
|
||||||
g_return_if_fail (builder != NULL);
|
g_return_if_fail (builder != NULL);
|
||||||
|
|
||||||
if (builder->ops->len == 0)
|
|
||||||
gsk_path_builder_move_to (builder, x1, y1);
|
|
||||||
|
|
||||||
builder->flags &= ~GSK_PATH_FLAT;
|
builder->flags &= ~GSK_PATH_FLAT;
|
||||||
gsk_path_builder_append_current (builder,
|
gsk_path_builder_append_current (builder,
|
||||||
GSK_PATH_CURVE,
|
GSK_PATH_CURVE,
|
||||||
|
|||||||
@@ -73,6 +73,9 @@ gpointer gsk_contour_init_measure (GskPath
|
|||||||
void gsk_contour_free_measure (GskPath *path,
|
void gsk_contour_free_measure (GskPath *path,
|
||||||
gsize i,
|
gsize i,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
void gsk_contour_get_start_end (const GskContour *self,
|
||||||
|
graphene_point_t *start,
|
||||||
|
graphene_point_t *end);
|
||||||
void gsk_contour_get_point (GskPath *path,
|
void gsk_contour_get_point (GskPath *path,
|
||||||
gsize i,
|
gsize i,
|
||||||
gpointer measure_data,
|
gpointer measure_data,
|
||||||
|
|||||||
Reference in New Issue
Block a user