gtk2/gsk/gskvulkanclip.c
Benjamin Otte 43c212ac28 build: Enable -Wswitch-enum and -Wswitch-default
This patch makes that work using 1 of 2 options:

1. Add all missing enums to the switch statement
  or
2. Cast the switch argument to a uint to avoid having to do that (mostly
   for GdkEventType).

I even found a bug while doing that: clearing a GtkImage with a surface
did not notify thae surface property.

The reason for enabling this flag even though it is tedious at times is
that it is very useful when adding values to an enum, because it makes
GTK immediately warn about all the switch statements where this enum is
relevant.
And I expect changes to enums to be frequent during the GTK4 development
cycle.
2017-10-06 21:23:39 +02:00

188 lines
5.1 KiB
C

#include "config.h"
#include "gskvulkanclipprivate.h"
#include "gskroundedrectprivate.h"
void
gsk_vulkan_clip_init_empty (GskVulkanClip *clip,
const graphene_rect_t *rect)
{
clip->type = GSK_VULKAN_CLIP_NONE;
gsk_rounded_rect_init_from_rect (&clip->rect, rect, 0);
}
static void
gsk_vulkan_clip_init_copy (GskVulkanClip *self,
const GskVulkanClip *src)
{
self->type = src->type;
gsk_rounded_rect_init_copy (&self->rect, &src->rect);
}
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;
}
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;
}
gboolean
gsk_vulkan_clip_transform (GskVulkanClip *dest,
const GskVulkanClip *src,
const graphene_matrix_t *transform,
const graphene_rect_t *viewport)
{
switch (src->type)
{
default:
g_assert_not_reached();
return FALSE;
case GSK_VULKAN_CLIP_ALL_CLIPPED:
gsk_vulkan_clip_init_copy (dest, src);
return TRUE;
case GSK_VULKAN_CLIP_NONE:
gsk_vulkan_clip_init_empty (dest, viewport);
return TRUE;
case GSK_VULKAN_CLIP_RECT:
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
case GSK_VULKAN_CLIP_ROUNDED:
/* FIXME: Handle 2D operations, in particular transform and scale */
return FALSE;
}
}
gboolean
gsk_vulkan_clip_contains_rect (const GskVulkanClip *self,
const graphene_rect_t *rect)
{
switch (self->type)
{
default:
g_assert_not_reached();
case GSK_VULKAN_CLIP_ALL_CLIPPED:
return FALSE;
case GSK_VULKAN_CLIP_NONE:
return TRUE;
case GSK_VULKAN_CLIP_RECT:
return graphene_rect_contains_rect (&self->rect.bounds, rect);
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
case GSK_VULKAN_CLIP_ROUNDED:
return gsk_rounded_rect_contains_rect (&self->rect, rect);
}
}