gboolean gsk_vulkan_clip_intersect_rect (GskVulkanClip *dest, const GskVulkanClip *src, const graphene_rect_t *rect) { if (graphene_rect_contains_rect (rect, &src->rect.bounds)) { gsk_vulkan_clip_init_copy (dest, src); return TRUE; } if (!graphene_rect_intersection (rect, &src->rect.bounds, NULL)) { dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED; return TRUE; } switch (src->type) { case GSK_VULKAN_CLIP_ALL_CLIPPED: dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED; break; case GSK_VULKAN_CLIP_NONE: gsk_vulkan_clip_init_copy (dest, src); if (graphene_rect_intersection (&dest->rect.bounds, rect, &dest->rect.bounds)) dest->type = GSK_VULKAN_CLIP_RECT; else dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED; break; case GSK_VULKAN_CLIP_RECT: gsk_vulkan_clip_init_copy (dest, src); if (!graphene_rect_intersection (&dest->rect.bounds, rect, &dest->rect.bounds)) dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED; break; case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR: case GSK_VULKAN_CLIP_ROUNDED: if (gsk_rounded_rect_contains_rect (&src->rect, rect)) { dest->type = GSK_VULKAN_CLIP_RECT; gsk_rounded_rect_init_from_rect (&dest->rect, rect, 0); } else { /* some points of rect are inside src's rounded rect, * some are outside. */ /* XXX: If the 2 rects don't intersect on rounded corners, * we could actually compute a new clip here. */ return FALSE; } default: g_assert_not_reached (); return FALSE; } return TRUE; }
void graphene_matrix_untransform_bounds (const graphene_matrix_t *m, const graphene_rect_t *r, const graphene_rect_t *bounds, graphene_rect_t *res) { graphene_matrix_t inverse; graphene_rect_t bounds_t; graphene_rect_t rect; g_return_if_fail (m != NULL && r != NULL); g_return_if_fail (bounds != NULL); g_return_if_fail (res != NULL); if (graphene_matrix_is_2d (m)) { graphene_matrix_inverse (m, &inverse); graphene_matrix_transform_bounds (&inverse, r, res); return; } graphene_matrix_transform_bounds (m, bounds, &bounds_t); if (!graphene_rect_intersection (r, &bounds_t, &rect)) { graphene_rect_init (res, 0.f, 0.f, 0.f, 0.f); return; } graphene_matrix_inverse (m, &inverse); graphene_matrix_project_rect_bounds (&inverse, &rect, res); }
gboolean gsk_vulkan_clip_intersect_rounded_rect (GskVulkanClip *dest, const GskVulkanClip *src, const GskRoundedRect *rounded) { if (gsk_rounded_rect_contains_rect (rounded, &src->rect.bounds)) { gsk_vulkan_clip_init_copy (dest, src); return TRUE; } if (!graphene_rect_intersection (&rounded->bounds, &src->rect.bounds, NULL)) { dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED; return TRUE; } switch (src->type) { case GSK_VULKAN_CLIP_ALL_CLIPPED: dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED; break; case GSK_VULKAN_CLIP_NONE: dest->type = gsk_rounded_rect_is_circular (&dest->rect) ? GSK_VULKAN_CLIP_ROUNDED_CIRCULAR : GSK_VULKAN_CLIP_ROUNDED; gsk_rounded_rect_init_copy (&dest->rect, rounded); break; case GSK_VULKAN_CLIP_RECT: if (graphene_rect_contains_rect (&src->rect.bounds, &rounded->bounds)) { dest->type = gsk_rounded_rect_is_circular (&dest->rect) ? GSK_VULKAN_CLIP_ROUNDED_CIRCULAR : GSK_VULKAN_CLIP_ROUNDED; gsk_rounded_rect_init_copy (&dest->rect, rounded); return TRUE; } /* some points of rect are inside src's rounded rect, * some are outside. */ /* XXX: If the 2 rects don't intersect on rounded corners, * we could actually compute a new clip here. */ return FALSE; case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR: case GSK_VULKAN_CLIP_ROUNDED: /* XXX: improve */ return FALSE; default: g_assert_not_reached (); return FALSE; } return TRUE; }