From ba405bfbf13f468f4ef1b1fc810cc729afc59025 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 21 Mar 2022 15:35:34 -0400 Subject: [PATCH] Add a bounding box type graphene_rect_t does not quite work for this purpose. --- gsk/gskboundingbox.c | 80 +++++++++++++++++++++++++++++++++++++ gsk/gskboundingboxprivate.h | 44 ++++++++++++++++++++ gsk/meson.build | 1 + 3 files changed, 125 insertions(+) create mode 100644 gsk/gskboundingbox.c create mode 100644 gsk/gskboundingboxprivate.h diff --git a/gsk/gskboundingbox.c b/gsk/gskboundingbox.c new file mode 100644 index 0000000000..d0f4aa8a18 --- /dev/null +++ b/gsk/gskboundingbox.c @@ -0,0 +1,80 @@ +#include "config.h" + +#include "gskboundingboxprivate.h" + +GskBoundingBox * +gsk_bounding_box_init (GskBoundingBox *self, + const graphene_point_t *a, + const graphene_point_t *b) +{ + self->min.x = MIN (a->x, b->x); + self->min.y = MIN (a->y, b->y); + self->max.x = MAX (a->x, b->x); + self->max.y = MAX (a->y, b->y); + return self; +} + +GskBoundingBox * +gsk_bounding_box_init_copy (GskBoundingBox *self, + const GskBoundingBox *src) +{ + self->min = src->min; + self->max = src->max; + return self; +} + +GskBoundingBox * +gsk_bounding_box_init_from_rect (GskBoundingBox *self, + const graphene_rect_t *bounds) +{ + self->min = bounds->origin; + self->max.x = bounds->origin.x + bounds->size.width; + self->max.y = bounds->origin.y + bounds->size.height; + return self; +} + +void +gsk_bounding_box_expand (GskBoundingBox *self, + const graphene_point_t *p) +{ + self->min.x = MIN (self->min.x, p->x); + self->min.y = MIN (self->min.y, p->y); + self->max.x = MAX (self->max.x, p->x); + self->max.y = MAX (self->max.y, p->y); +} + +graphene_rect_t * +gsk_bounding_box_to_rect (const GskBoundingBox *self, + graphene_rect_t *rect) +{ + rect->origin = self->min; + rect->size.width = self->max.x - self->min.x; + rect->size.height = self->max.y - self->min.y; + return rect; +} + +gboolean +gsk_bounding_box_contains_point (const GskBoundingBox *self, + const graphene_point_t *p) +{ + return self->min.x <= p->x && p->x <= self->max.x && + self->min.y <= p->y && p->y <= self->max.y; +} + +gboolean +gsk_bounding_box_intersection (const GskBoundingBox *a, + const GskBoundingBox *b, + GskBoundingBox *res) +{ + graphene_point_t min, max; + + min.x = MAX (a->min.x, b->min.x); + min.y = MAX (a->min.y, b->min.y); + max.x = MIN (a->max.x, b->max.x); + max.y = MIN (a->max.y, b->max.y); + + if (res) + gsk_bounding_box_init (res, &min, &max); + + return min.x <= max.x && min.y <= max.y; +} diff --git a/gsk/gskboundingboxprivate.h b/gsk/gskboundingboxprivate.h new file mode 100644 index 0000000000..f0199f2ea6 --- /dev/null +++ b/gsk/gskboundingboxprivate.h @@ -0,0 +1,44 @@ +#pragma once + +#include + +G_BEGIN_DECLS + +typedef struct _GskBoundingBox GskBoundingBox; + +struct _GskBoundingBox { + graphene_point_t min; + graphene_point_t max; +}; + +GDK_AVAILABLE_IN_ALL +GskBoundingBox * gsk_bounding_box_init (GskBoundingBox *self, + const graphene_point_t *a, + const graphene_point_t *b); + +GDK_AVAILABLE_IN_ALL +GskBoundingBox * gsk_bounding_box_init_copy (GskBoundingBox *self, + const GskBoundingBox *src); + +GDK_AVAILABLE_IN_ALL +GskBoundingBox * gsk_bounding_box_init_from_rect (GskBoundingBox *self, + const graphene_rect_t *bounds); + +GDK_AVAILABLE_IN_ALL +void gsk_bounding_box_expand (GskBoundingBox *self, + const graphene_point_t *p); + +GDK_AVAILABLE_IN_ALL +graphene_rect_t *gsk_bounding_box_to_rect (const GskBoundingBox *self, + graphene_rect_t *rect); + +GDK_AVAILABLE_IN_ALL +gboolean gsk_bounding_box_contains_point (const GskBoundingBox *self, + const graphene_point_t *p); + +GDK_AVAILABLE_IN_ALL +gboolean gsk_bounding_box_intersection (const GskBoundingBox *a, + const GskBoundingBox *b, + GskBoundingBox *res); + +G_END_DECLS diff --git a/gsk/meson.build b/gsk/meson.build index 757a0314a1..cf255c88c4 100644 --- a/gsk/meson.build +++ b/gsk/meson.build @@ -41,6 +41,7 @@ gsk_public_sources = files([ ]) gsk_private_sources = files([ + 'gskboundingbox.c', 'gskcairoblur.c', 'gskcontour.c', 'gskcurve.c',