diff options
author | Benjamin Otte <otte@redhat.com> | 2016-12-19 04:39:33 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2016-12-20 18:01:12 +0100 |
commit | 4fc64ae3dd5dde99b0a47e184b9428635012825c (patch) | |
tree | a1c67fde2d573b91198d867493d017fc33c0ceb1 | |
parent | 2480e0d57530b72a8efa4fefeff98971b61e16da (diff) | |
download | gtk+-4fc64ae3dd5dde99b0a47e184b9428635012825c.tar.gz |
gsk: Add contains/intersect functions for GskRoundedRect
... and use them.
-rw-r--r-- | docs/reference/gsk/gsk4-sections.txt | 3 | ||||
-rw-r--r-- | gsk/gskroundedrect.c | 120 | ||||
-rw-r--r-- | gsk/gskroundedrect.h | 11 | ||||
-rw-r--r-- | gtk/gtkcssshadowvalue.c | 4 | ||||
-rw-r--r-- | gtk/gtkroundedbox.c | 47 | ||||
-rw-r--r-- | gtk/gtkroundedboxprivate.h | 10 |
6 files changed, 134 insertions, 61 deletions
diff --git a/docs/reference/gsk/gsk4-sections.txt b/docs/reference/gsk/gsk4-sections.txt index 20785e7ff7..8afc232452 100644 --- a/docs/reference/gsk/gsk4-sections.txt +++ b/docs/reference/gsk/gsk4-sections.txt @@ -77,4 +77,7 @@ gsk_rounded_rect_normalize gsk_rounded_rect_offset gsk_rounded_rect_shrink gsk_rounded_rect_is_rectilinear +gsk_rounded_rect_contains_point +gsk_rounded_rect_contains_rect +gsk_rounded_rect_intersects_rect </SECTION> diff --git a/gsk/gskroundedrect.c b/gsk/gskroundedrect.c index f1ecc2b4ec..a38b96e58c 100644 --- a/gsk/gskroundedrect.c +++ b/gsk/gskroundedrect.c @@ -290,7 +290,7 @@ gsk_rounded_rect_shrink (GskRoundedRect *self, * Returns: %TRUE if the rectangle is rectilinear **/ gboolean -gsk_rounded_rect_is_rectilinear (GskRoundedRect *self) +gsk_rounded_rect_is_rectilinear (const GskRoundedRect *self) { guint i; @@ -304,6 +304,124 @@ gsk_rounded_rect_is_rectilinear (GskRoundedRect *self) return TRUE; } +gboolean +ellipsis_contains_point (const graphene_size_t *ellipsis, + const graphene_point_t *point) +{ + return (point->x * point->x) / (ellipsis->width * ellipsis->width) + + (point->y * point->y) / (ellipsis->height * ellipsis->height) <= 1; +} + +/** + * gsk_rounded_rect_contains_point: + * @self: a #GskRoundedRect + * @point: the point to check + * + * Checks if the given @point is inside the rounded rectangle. This function + * returns %FALSE if the point is in the rounded corner areas. + * + * Returns: %TRUE if the @point is inside the rounded rectangle + **/ +gboolean +gsk_rounded_rect_contains_point (const GskRoundedRect *self, + const graphene_point_t *point) +{ + if (!graphene_rect_contains_point (&self->bounds, point)) + return FALSE; + + if (self->bounds.origin.x + self->corner[GSK_CORNER_TOP_LEFT].width > point->x && + self->bounds.origin.y + self->corner[GSK_CORNER_TOP_LEFT].height > point->y && + !ellipsis_contains_point (&self->corner[GSK_CORNER_TOP_LEFT], + &GRAPHENE_POINT_INIT ( + self->bounds.origin.x + self->corner[GSK_CORNER_TOP_LEFT].width - point->x, + self->bounds.origin.y + self->corner[GSK_CORNER_TOP_LEFT].height- point->y + ))) + return FALSE; + + if (self->bounds.origin.x + self->bounds.size.width - self->corner[GSK_CORNER_TOP_RIGHT].width < point->x && + self->bounds.origin.y + self->corner[GSK_CORNER_TOP_RIGHT].height > point->y && + !ellipsis_contains_point (&self->corner[GSK_CORNER_TOP_RIGHT], + &GRAPHENE_POINT_INIT ( + self->bounds.origin.x + self->bounds.size.width - self->corner[GSK_CORNER_TOP_RIGHT].width - point->x, + self->bounds.origin.y + self->corner[GSK_CORNER_TOP_RIGHT].height- point->y + ))) + return FALSE; + + if (self->bounds.origin.x + self->corner[GSK_CORNER_BOTTOM_LEFT].width > point->x && + self->bounds.origin.y + self->bounds.size.height - self->corner[GSK_CORNER_BOTTOM_LEFT].height > point->y && + !ellipsis_contains_point (&self->corner[GSK_CORNER_BOTTOM_LEFT], + &GRAPHENE_POINT_INIT ( + self->bounds.origin.x + self->corner[GSK_CORNER_BOTTOM_LEFT].width - point->x, + self->bounds.origin.y + self->bounds.size.height - self->corner[GSK_CORNER_BOTTOM_LEFT].height- point->y + ))) + return FALSE; + + if (self->bounds.origin.x + self->bounds.size.width - self->corner[GSK_CORNER_BOTTOM_RIGHT].width < point->x && + self->bounds.origin.y + self->bounds.size.height - self->corner[GSK_CORNER_BOTTOM_RIGHT].height > point->y && + !ellipsis_contains_point (&self->corner[GSK_CORNER_BOTTOM_RIGHT], + &GRAPHENE_POINT_INIT ( + self->bounds.origin.x + self->bounds.size.width - self->corner[GSK_CORNER_BOTTOM_RIGHT].width - point->x, + self->bounds.origin.y + self->bounds.size.height - self->corner[GSK_CORNER_BOTTOM_RIGHT].height- point->y + ))) + return FALSE; + + return TRUE; +} + +/** + * gsk_rounded_rect_contains_rect: + * @self: a #GskRoundedRect + * @rect: the rectangle to check + * + * Checks if the given @rect is contained inside the rounded rectangle. + * This function returns %FALSE if @rect extends into one of the rounded + * corner areas. + * + * Returns: %TRUE if the @rect is fully contained inside the rounded rectangle + **/ +gboolean +gsk_rounded_rect_contains_rect (const GskRoundedRect *self, + const graphene_rect_t *rect) +{ + if (!graphene_rect_contains_rect (&self->bounds, rect)) + return FALSE; + + if (!gsk_rounded_rect_contains_point (self, &rect->origin) || + !gsk_rounded_rect_contains_point (self, &GRAPHENE_POINT_INIT (rect->origin.x + rect->size.width, rect->origin.y)) || + !gsk_rounded_rect_contains_point (self, &GRAPHENE_POINT_INIT (rect->origin.x, rect->origin.y + rect->size.height)) || + !gsk_rounded_rect_contains_point (self, &GRAPHENE_POINT_INIT (rect->origin.x + rect->size.width, rect->origin.y + rect->size.height))) + return FALSE; + + return TRUE; +} + +/** + * gsk_rounded_rect_intersects_rect: + * @self: a #GskRoundedRect + * @rect: the rectangle to check + * + * Checks if part of the given @rect is contained inside the rounded rectangle. + * This function returns %FALSE if @rect only extends into one of the rounded + * corner areas but not into the rounded rectangle itself. + * + * Returns: %TRUE if the @rect intersects with the rounded rectangle + **/ +gboolean +gsk_rounded_rect_intersects_rect (const GskRoundedRect *self, + const graphene_rect_t *rect) +{ + if (!graphene_rect_intersection (&self->bounds, rect, NULL)) + return FALSE; + + if (!gsk_rounded_rect_contains_point (self, &rect->origin) && + !gsk_rounded_rect_contains_point (self, &GRAPHENE_POINT_INIT (rect->origin.x + rect->size.width, rect->origin.y)) && + !gsk_rounded_rect_contains_point (self, &GRAPHENE_POINT_INIT (rect->origin.x, rect->origin.y + rect->size.height)) && + !gsk_rounded_rect_contains_point (self, &GRAPHENE_POINT_INIT (rect->origin.x + rect->size.width, rect->origin.y + rect->size.height))) + return FALSE; + + return TRUE; +} + static void append_arc (cairo_t *cr, double angle1, double angle2, gboolean negative) { diff --git a/gsk/gskroundedrect.h b/gsk/gskroundedrect.h index 9a3d33eb01..98819e4ea3 100644 --- a/gsk/gskroundedrect.h +++ b/gsk/gskroundedrect.h @@ -95,7 +95,16 @@ GskRoundedRect * gsk_rounded_rect_shrink (GskRoundedRect float left); GDK_AVAILABLE_IN_3_90 -gboolean gsk_rounded_rect_is_rectilinear (GskRoundedRect *self); +gboolean gsk_rounded_rect_is_rectilinear (const GskRoundedRect *self); +GDK_AVAILABLE_IN_3_90 +gboolean gsk_rounded_rect_contains_point (const GskRoundedRect *self, + const graphene_point_t *point); +GDK_AVAILABLE_IN_3_90 +gboolean gsk_rounded_rect_contains_rect (const GskRoundedRect *self, + const graphene_rect_t *rect); +GDK_AVAILABLE_IN_3_90 +gboolean gsk_rounded_rect_intersects_rect (const GskRoundedRect *self, + const graphene_rect_t *rect); G_END_DECLS diff --git a/gtk/gtkcssshadowvalue.c b/gtk/gtkcssshadowvalue.c index c0cccd7835..f132bfc990 100644 --- a/gtk/gtkcssshadowvalue.c +++ b/gtk/gtkcssshadowvalue.c @@ -913,8 +913,8 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow, return; cairo_clip_extents (cr, &x1c, &y1c, &x2c, &y2c); - if ((shadow->inset && !_gtk_rounded_box_intersects_rectangle (padding_box, x1c, y1c, x2c, y2c)) || - (!shadow->inset && _gtk_rounded_box_contains_rectangle (padding_box, x1c, y1c, x2c, y2c))) + if ((shadow->inset && !gsk_rounded_rect_intersects_rect (padding_box, &GRAPHENE_RECT_INIT (x1c, y1c, x2c - x1c, y2c - y1c))) || + (!shadow->inset && gsk_rounded_rect_contains_rect (padding_box, &GRAPHENE_RECT_INIT (x1c, y1c, x2c - x1c, y2c - y1c)))) return; cairo_save (cr); diff --git a/gtk/gtkroundedbox.c b/gtk/gtkroundedbox.c index 5dafd63d25..e51722f6a6 100644 --- a/gtk/gtkroundedbox.c +++ b/gtk/gtkroundedbox.c @@ -592,50 +592,3 @@ _gtk_rounded_box_clip_path (const GskRoundedRect *box, box->bounds.size.width, box->bounds.size.height); } -gboolean -_gtk_rounded_box_intersects_rectangle (const GskRoundedRect *box, - gdouble x1, - gdouble y1, - gdouble x2, - gdouble y2) -{ - if (x2 < box->bounds.origin.x || - y2 < box->bounds.origin.y || - x1 >= box->bounds.origin.x + box->bounds.size.width || - y1 >= box->bounds.origin.y + box->bounds.size.height) - return FALSE; - - return TRUE; -} - -gboolean -_gtk_rounded_box_contains_rectangle (const GskRoundedRect *box, - gdouble x1, - gdouble y1, - gdouble x2, - gdouble y2) -{ - if (x1 < box->bounds.origin.x || - y1 < box->bounds.origin.y || - x2 > box->bounds.origin.x + box->bounds.size.width || - y2 > box->bounds.origin.y + box->bounds.size.height) - return FALSE; - - if (x1 < box->bounds.origin.x + box->corner[GSK_CORNER_TOP_LEFT].width && - y1 < box->bounds.origin.y + box->corner[GSK_CORNER_TOP_LEFT].height) - return FALSE; - - if (x2 > box->bounds.origin.x + box->bounds.size.width - box->corner[GSK_CORNER_TOP_RIGHT].width && - y1 < box->bounds.origin.y + box->corner[GSK_CORNER_TOP_RIGHT].height) - return FALSE; - - if (x2 > box->bounds.origin.x + box->bounds.size.width - box->corner[GSK_CORNER_BOTTOM_RIGHT].width && - y2 > box->bounds.origin.y + box->bounds.size.height - box->corner[GSK_CORNER_BOTTOM_RIGHT].height) - return FALSE; - - if (x1 < box->bounds.origin.x + box->corner[GSK_CORNER_BOTTOM_LEFT].width && - y2 > box->bounds.origin.y + box->bounds.size.height - box->corner[GSK_CORNER_BOTTOM_LEFT].height) - return FALSE; - - return TRUE; -} diff --git a/gtk/gtkroundedboxprivate.h b/gtk/gtkroundedboxprivate.h index 474c56cc79..98ebec0d9e 100644 --- a/gtk/gtkroundedboxprivate.h +++ b/gtk/gtkroundedboxprivate.h @@ -62,16 +62,6 @@ void _gtk_rounded_box_path_left (const GskRounde cairo_t *cr); void _gtk_rounded_box_clip_path (const GskRoundedRect *box, cairo_t *cr); -gboolean _gtk_rounded_box_intersects_rectangle (const GskRoundedRect *box, - gdouble x1, - gdouble y1, - gdouble x2, - gdouble y2); -gboolean _gtk_rounded_box_contains_rectangle (const GskRoundedRect *box, - gdouble x1, - gdouble y1, - gdouble x2, - gdouble y2); G_END_DECLS |