mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-08 17:50:10 +00:00
Add gsk_path_get_stroke_bounds
This is a helper to compute the bounds for stroke nodes. We keep it private for now.
This commit is contained in:
parent
db71c07f8f
commit
c37c29422a
@ -26,6 +26,7 @@
|
|||||||
#include "gskpathprivate.h"
|
#include "gskpathprivate.h"
|
||||||
#include "gskpathpointprivate.h"
|
#include "gskpathpointprivate.h"
|
||||||
#include "gsksplineprivate.h"
|
#include "gsksplineprivate.h"
|
||||||
|
#include "gskstrokeprivate.h"
|
||||||
|
|
||||||
typedef struct _GskContourClass GskContourClass;
|
typedef struct _GskContourClass GskContourClass;
|
||||||
|
|
||||||
@ -47,6 +48,9 @@ struct _GskContourClass
|
|||||||
GString *string);
|
GString *string);
|
||||||
gboolean (* get_bounds) (const GskContour *contour,
|
gboolean (* get_bounds) (const GskContour *contour,
|
||||||
GskBoundingBox *bounds);
|
GskBoundingBox *bounds);
|
||||||
|
gboolean (* get_stroke_bounds) (const GskContour *contour,
|
||||||
|
const GskStroke *stroke,
|
||||||
|
GskBoundingBox *bounds);
|
||||||
void (* get_start_end) (const GskContour *self,
|
void (* get_start_end) (const GskContour *self,
|
||||||
graphene_point_t *start,
|
graphene_point_t *start,
|
||||||
graphene_point_t *end);
|
graphene_point_t *end);
|
||||||
@ -295,6 +299,60 @@ gsk_standard_contour_get_bounds (const GskContour *contour,
|
|||||||
return bounds->max.x > bounds->min.x && bounds->max.y > bounds->min.y;
|
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;
|
||||||
|
|
||||||
|
data.bounds = bounds;
|
||||||
|
data.lw = stroke->line_width;
|
||||||
|
data.mw = gsk_stroke_get_join_width (stroke);
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
gsk_standard_contour_foreach (contour, GSK_PATH_TOLERANCE_DEFAULT, add_stroke_bounds, &data);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_standard_contour_get_start_end (const GskContour *contour,
|
gsk_standard_contour_get_start_end (const GskContour *contour,
|
||||||
graphene_point_t *start,
|
graphene_point_t *start,
|
||||||
@ -493,6 +551,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_stroke_bounds,
|
||||||
gsk_standard_contour_get_start_end,
|
gsk_standard_contour_get_start_end,
|
||||||
gsk_standard_contour_foreach,
|
gsk_standard_contour_foreach,
|
||||||
gsk_standard_contour_reverse,
|
gsk_standard_contour_reverse,
|
||||||
@ -605,6 +664,14 @@ gsk_contour_get_bounds (const GskContour *self,
|
|||||||
return self->klass->get_bounds (self, bounds);
|
return self->klass->get_bounds (self, bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gsk_contour_get_stroke_bounds (const GskContour *self,
|
||||||
|
const GskStroke *stroke,
|
||||||
|
GskBoundingBox *bounds)
|
||||||
|
{
|
||||||
|
return self->klass->get_stroke_bounds (self, stroke, bounds);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gsk_contour_foreach (const GskContour *self,
|
gsk_contour_foreach (const GskContour *self,
|
||||||
float tolerance,
|
float tolerance,
|
||||||
|
@ -45,6 +45,9 @@ void gsk_contour_print (const GskContou
|
|||||||
GString *string);
|
GString *string);
|
||||||
gboolean gsk_contour_get_bounds (const GskContour *self,
|
gboolean gsk_contour_get_bounds (const GskContour *self,
|
||||||
GskBoundingBox *bounds);
|
GskBoundingBox *bounds);
|
||||||
|
gboolean gsk_contour_get_stroke_bounds (const GskContour *self,
|
||||||
|
const GskStroke *stroke,
|
||||||
|
GskBoundingBox *bounds);
|
||||||
gboolean gsk_contour_foreach (const GskContour *self,
|
gboolean gsk_contour_foreach (const GskContour *self,
|
||||||
float tolerance,
|
float tolerance,
|
||||||
GskPathForeachFunc func,
|
GskPathForeachFunc func,
|
||||||
|
@ -379,7 +379,6 @@ gsk_path_get_bounds (GskPath *self,
|
|||||||
graphene_rect_t *bounds)
|
graphene_rect_t *bounds)
|
||||||
{
|
{
|
||||||
GskBoundingBox b;
|
GskBoundingBox b;
|
||||||
gsize i;
|
|
||||||
|
|
||||||
g_return_val_if_fail (self != NULL, FALSE);
|
g_return_val_if_fail (self != NULL, FALSE);
|
||||||
g_return_val_if_fail (bounds != NULL, FALSE);
|
g_return_val_if_fail (bounds != NULL, FALSE);
|
||||||
@ -392,12 +391,60 @@ gsk_path_get_bounds (GskPath *self,
|
|||||||
|
|
||||||
gsk_contour_get_bounds (self->contours[0], &b);
|
gsk_contour_get_bounds (self->contours[0], &b);
|
||||||
|
|
||||||
for (i = 1; i < self->n_contours; i++)
|
for (gsize i = 1; i < self->n_contours; i++)
|
||||||
{
|
{
|
||||||
GskBoundingBox bb;
|
GskBoundingBox tmp;
|
||||||
|
|
||||||
gsk_contour_get_bounds (self->contours[i], &bb);
|
gsk_contour_get_bounds (self->contours[i], &tmp);
|
||||||
gsk_bounding_box_union (&b, &bb, &b);
|
gsk_bounding_box_union (&b, &tmp, &b);
|
||||||
|
}
|
||||||
|
|
||||||
|
gsk_bounding_box_to_rect (&b, bounds);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gsk_path_get_stroke_bounds:
|
||||||
|
* @self: a #GtkPath
|
||||||
|
* @stroke: stroke parameters
|
||||||
|
* @bounds: (out caller-allocates): the bounds to fill in
|
||||||
|
*
|
||||||
|
* Computes the bounds for stroking the given path with the
|
||||||
|
* parameters in @stroke.
|
||||||
|
*
|
||||||
|
* The returned bounds may be larger than necessary, because this
|
||||||
|
* function aims to be fast, not accurate. The bounds are guaranteed
|
||||||
|
* to contain the area affected by the stroke, including protrusions
|
||||||
|
* like miters.
|
||||||
|
*
|
||||||
|
* Returns: `TRUE` if the path has bounds, `FALSE` if the path is known
|
||||||
|
* to be empty and have no bounds.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gsk_path_get_stroke_bounds (GskPath *self,
|
||||||
|
const GskStroke *stroke,
|
||||||
|
graphene_rect_t *bounds)
|
||||||
|
{
|
||||||
|
GskBoundingBox b;
|
||||||
|
|
||||||
|
g_return_val_if_fail (self != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (bounds != NULL, FALSE);
|
||||||
|
|
||||||
|
if (self->n_contours == 0)
|
||||||
|
{
|
||||||
|
graphene_rect_init_from_rect (bounds, graphene_rect_zero ());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gsk_contour_get_stroke_bounds (self->contours[0], stroke, &b);
|
||||||
|
|
||||||
|
for (gsize i = 1; i < self->n_contours; i++)
|
||||||
|
{
|
||||||
|
GskBoundingBox tmp;
|
||||||
|
|
||||||
|
if (gsk_contour_get_stroke_bounds (self->contours[i], stroke, &tmp))
|
||||||
|
gsk_bounding_box_union (&b, &tmp, &b);
|
||||||
}
|
}
|
||||||
|
|
||||||
gsk_bounding_box_to_rect (&b, bounds);
|
gsk_bounding_box_to_rect (&b, bounds);
|
||||||
|
@ -100,6 +100,11 @@ GDK_AVAILABLE_IN_4_14
|
|||||||
gboolean gsk_path_get_bounds (GskPath *self,
|
gboolean gsk_path_get_bounds (GskPath *self,
|
||||||
graphene_rect_t *bounds);
|
graphene_rect_t *bounds);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_4_14
|
||||||
|
gboolean gsk_path_get_stroke_bounds (GskPath *self,
|
||||||
|
const GskStroke *stroke,
|
||||||
|
graphene_rect_t *bounds);
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_4_14
|
GDK_AVAILABLE_IN_4_14
|
||||||
gboolean gsk_path_in_fill (GskPath *self,
|
gboolean gsk_path_in_fill (GskPath *self,
|
||||||
const graphene_point_t *point,
|
const graphene_point_t *point,
|
||||||
|
@ -498,7 +498,7 @@ gsk_stroke_get_dash_offset (const GskStroke *self)
|
|||||||
* Returns: the join width
|
* Returns: the join width
|
||||||
*/
|
*/
|
||||||
float
|
float
|
||||||
gsk_stroke_get_join_width (GskStroke *stroke)
|
gsk_stroke_get_join_width (const GskStroke *stroke)
|
||||||
{
|
{
|
||||||
float width;
|
float width;
|
||||||
|
|
||||||
|
@ -53,6 +53,6 @@ gsk_stroke_clear (GskStroke *stroke)
|
|||||||
stroke->n_dash = 0; /* better safe than sorry */
|
stroke->n_dash = 0; /* better safe than sorry */
|
||||||
}
|
}
|
||||||
|
|
||||||
float gsk_stroke_get_join_width (GskStroke);
|
float gsk_stroke_get_join_width (const GskStroke *stroke);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
Loading…
Reference in New Issue
Block a user