[gtk+/wip/otte/rendernode: 20/30] gsk: Add contains/intersect functions for GskRoundedRect
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/rendernode: 20/30] gsk: Add contains/intersect functions for GskRoundedRect
- Date: Mon, 19 Dec 2016 18:49:05 +0000 (UTC)
commit 83c621dca76e5585cb22c90ff270ef0ed5242173
Author: Benjamin Otte <otte redhat com>
Date: Mon Dec 19 04:39:33 2016 +0100
gsk: Add contains/intersect functions for GskRoundedRect
... and use them.
docs/reference/gsk/gsk4-sections.txt | 3 +
gsk/gskroundedrect.c | 120 +++++++++++++++++++++++++++++++++-
gsk/gskroundedrect.h | 11 +++-
gtk/gtkcssshadowvalue.c | 4 +-
gtk/gtkroundedbox.c | 47 -------------
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 20785e7..8afc232 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 f1ecc2b..a38b96e 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 9a3d33e..98819e4 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 c0cccd7..f132bfc 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 5dafd63..e51722f 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 474c56c..98ebec0 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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]