mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 13:41:07 +00:00
contour: Optimize bounds
Cache the bounds in the contour, and compute the stroke bounds based on it as well.
This commit is contained in:
parent
08c064d79a
commit
0c39890e0f
@ -119,6 +119,8 @@ struct _GskStandardContour
|
||||
|
||||
GskPathFlags flags;
|
||||
|
||||
GskBoundingBox bounds;
|
||||
|
||||
gsize n_ops;
|
||||
gsize n_points;
|
||||
graphene_point_t *points;
|
||||
@ -254,7 +256,7 @@ gsk_standard_contour_print (const GskContour *contour,
|
||||
const graphene_point_t *pt = gsk_pathop_points (self->ops[i]);
|
||||
|
||||
switch (gsk_pathop_op (self->ops[i]))
|
||||
{
|
||||
{
|
||||
case GSK_PATH_MOVE:
|
||||
g_string_append (string, "M ");
|
||||
_g_string_append_point (string, &pt[0]);
|
||||
@ -288,7 +290,7 @@ gsk_standard_contour_print (const GskContour *contour,
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -297,68 +299,32 @@ gsk_standard_contour_get_bounds (const GskContour *contour,
|
||||
GskBoundingBox *bounds)
|
||||
{
|
||||
const GskStandardContour *self = (const GskStandardContour *) contour;
|
||||
gsize i;
|
||||
|
||||
if (self->n_points == 0)
|
||||
return FALSE;
|
||||
|
||||
gsk_bounding_box_init (bounds, &self->points[0], &self->points[0]);
|
||||
for (i = 1; i < self->n_points; i ++)
|
||||
gsk_bounding_box_expand (bounds, &self->points[i]);
|
||||
*bounds = self->bounds;
|
||||
|
||||
return bounds->max.x > bounds->min.x && bounds->max.y > bounds->min.y;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_stroke_bounds (GskPathOperation op,
|
||||
const graphene_point_t *pts,
|
||||
gsize n_pts,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct {
|
||||
GskBoundingBox *bounds;
|
||||
float lw;
|
||||
float mw;
|
||||
} *data = user_data;
|
||||
GskBoundingBox bounds;
|
||||
|
||||
for (int i = 1; i < n_pts - 1; i++)
|
||||
{
|
||||
gsk_bounding_box_init (&bounds,
|
||||
&GRAPHENE_POINT_INIT (pts[i].x - data->lw/2, pts[i].y - data->lw/2),
|
||||
&GRAPHENE_POINT_INIT (pts[i].x + data->lw/2, pts[i].y + data->lw/2));
|
||||
gsk_bounding_box_union (&bounds, data->bounds, data->bounds);
|
||||
}
|
||||
|
||||
gsk_bounding_box_init (&bounds,
|
||||
&GRAPHENE_POINT_INIT (pts[n_pts - 1].x - data->mw/2, pts[n_pts - 1].y - data->mw/2),
|
||||
&GRAPHENE_POINT_INIT (pts[n_pts - 1].x + data->mw/2, pts[n_pts - 1].y + data->mw/2));
|
||||
gsk_bounding_box_union (&bounds, data->bounds, data->bounds);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_standard_contour_get_stroke_bounds (const GskContour *contour,
|
||||
const GskStroke *stroke,
|
||||
GskBoundingBox *bounds)
|
||||
{
|
||||
GskStandardContour *self = (GskStandardContour *) contour;
|
||||
struct {
|
||||
GskBoundingBox *bounds;
|
||||
float lw;
|
||||
float mw;
|
||||
} data;
|
||||
float extra;
|
||||
|
||||
data.bounds = bounds;
|
||||
data.lw = stroke->line_width;
|
||||
data.mw = gsk_stroke_get_join_width (stroke);
|
||||
if (self->n_points == 0)
|
||||
return FALSE;
|
||||
|
||||
gsk_bounding_box_init (bounds,
|
||||
&GRAPHENE_POINT_INIT (self->points[0].x - data.mw/2, self->points[0].y - data.mw/2),
|
||||
&GRAPHENE_POINT_INIT (self->points[0].x + data.mw/2, self->points[0].y + data.mw/2));
|
||||
extra = MAX (stroke->line_width / 2, gsk_stroke_get_join_width (stroke) / 2);
|
||||
|
||||
gsk_standard_contour_foreach (contour, GSK_PATH_TOLERANCE_DEFAULT, add_stroke_bounds, &data);
|
||||
gsk_bounding_box_init (bounds, &GRAPHENE_POINT_INIT (self->bounds.min.x - extra,
|
||||
self->bounds.min.y - extra),
|
||||
&GRAPHENE_POINT_INIT (self->bounds.max.x + extra,
|
||||
self->bounds.max.y + extra));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -384,6 +350,9 @@ gsk_standard_contour_get_winding (const GskContour *contour,
|
||||
GskStandardContour *self = (GskStandardContour *) contour;
|
||||
int winding = 0;
|
||||
|
||||
if (!gsk_bounding_box_contains_point (&self->bounds, point))
|
||||
return 0;
|
||||
|
||||
for (gsize i = 0; i < self->n_ops; i ++)
|
||||
{
|
||||
GskCurve c;
|
||||
@ -669,7 +638,6 @@ gsk_standard_contour_init (GskContour *contour,
|
||||
|
||||
{
|
||||
GskStandardContour *self = (GskStandardContour *) contour;
|
||||
gsize i;
|
||||
|
||||
self->contour.klass = &GSK_STANDARD_CONTOUR_CLASS;
|
||||
|
||||
@ -680,11 +648,13 @@ gsk_standard_contour_init (GskContour *contour,
|
||||
memcpy (self->points, points, sizeof (graphene_point_t) * n_points);
|
||||
|
||||
offset += self->points - points;
|
||||
for (i = 0; i < n_ops; i++)
|
||||
{
|
||||
self->ops[i] = gsk_pathop_encode (gsk_pathop_op (ops[i]),
|
||||
gsk_pathop_points (ops[i]) + offset);
|
||||
}
|
||||
for (gsize i = 0; i < n_ops; i++)
|
||||
self->ops[i] = gsk_pathop_encode (gsk_pathop_op (ops[i]),
|
||||
gsk_pathop_points (ops[i]) + offset);
|
||||
|
||||
gsk_bounding_box_init (&self->bounds, &self->points[0], &self->points[0]);
|
||||
for (gsize i = 1; i < self->n_points; i ++)
|
||||
gsk_bounding_box_expand (&self->bounds, &self->points[i]);
|
||||
}
|
||||
|
||||
GskContour *
|
||||
|
Loading…
Reference in New Issue
Block a user