gtk/tests/gtkclipper.c
Matthias Clasen 70380661fe testdmabuf: Test dmabuf viewports
Allow specifying padding via --padding. The argument to --padding
is a string of up to 4 comma-separated numbers, for the left, right,
top, bottom padding. If less numbers are given, the remaining ones
are set to zero.

This commit also includes an image that can be used for testing with

testdmabuf --padding 20,20,20,20 NV12 padded.png
2024-02-11 21:49:34 -05:00

158 lines
4.5 KiB
C

#include "gtk/gtk.h"
#include "gtkclipperprivate.h"
struct _GtkClipper
{
GObject parent_instance;
GdkPaintable *paintable;
graphene_rect_t clip;
};
struct _GtkClipperClass
{
GObjectClass parent_class;
};
static void
gtk_clipper_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GtkClipper *self = GTK_CLIPPER (paintable);
float sx, sy;
gtk_snapshot_save (snapshot);
sx = gdk_paintable_get_intrinsic_width (self->paintable) / self->clip.size.width;
sy = gdk_paintable_get_intrinsic_height (self->paintable) / self->clip.size.height;
gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- self->clip.origin.x * width / self->clip.size.width,
- self->clip.origin.y * height / self->clip.size.height));
gdk_paintable_snapshot (self->paintable, snapshot, width * sx, height * sy);
gtk_snapshot_pop (snapshot);
gtk_snapshot_restore (snapshot);
}
static GdkPaintable *
gtk_clipper_paintable_get_current_image (GdkPaintable *paintable)
{
GtkClipper *self = GTK_CLIPPER (paintable);
GdkPaintable *current_paintable, *current_self;
current_paintable = gdk_paintable_get_current_image (self->paintable);
current_self = gtk_clipper_new (current_paintable, &self->clip);
g_object_unref (current_paintable);
return current_self;
}
static GdkPaintableFlags
gtk_clipper_paintable_get_flags (GdkPaintable *paintable)
{
GtkClipper *self = GTK_CLIPPER (paintable);
return gdk_paintable_get_flags (self->paintable);
}
static int
gtk_clipper_paintable_get_intrinsic_width (GdkPaintable *paintable)
{
GtkClipper *self = GTK_CLIPPER (paintable);
return self->clip.size.width;
}
static int
gtk_clipper_paintable_get_intrinsic_height (GdkPaintable *paintable)
{
GtkClipper *self = GTK_CLIPPER (paintable);
return self->clip.size.height;
}
static double gtk_clipper_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
{
GtkClipper *self = GTK_CLIPPER (paintable);
return self->clip.size.width / (double) self->clip.size.height;
};
static void
gtk_clipper_paintable_init (GdkPaintableInterface *iface)
{
iface->snapshot = gtk_clipper_paintable_snapshot;
iface->get_current_image = gtk_clipper_paintable_get_current_image;
iface->get_flags = gtk_clipper_paintable_get_flags;
iface->get_intrinsic_width = gtk_clipper_paintable_get_intrinsic_width;
iface->get_intrinsic_height = gtk_clipper_paintable_get_intrinsic_height;
iface->get_intrinsic_aspect_ratio = gtk_clipper_paintable_get_intrinsic_aspect_ratio;
}
G_DEFINE_TYPE_EXTENDED (GtkClipper, gtk_clipper, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_clipper_paintable_init))
static void
gtk_clipper_dispose (GObject *object)
{
GtkClipper *self = GTK_CLIPPER (object);
if (self->paintable)
{
const guint flags = gdk_paintable_get_flags (self->paintable);
if ((flags & GDK_PAINTABLE_STATIC_CONTENTS) == 0)
g_signal_handlers_disconnect_by_func (self->paintable, gdk_paintable_invalidate_contents, self);
if ((flags & GDK_PAINTABLE_STATIC_SIZE) == 0)
g_signal_handlers_disconnect_by_func (self->paintable, gdk_paintable_invalidate_size, self);
g_clear_object (&self->paintable);
}
G_OBJECT_CLASS (gtk_clipper_parent_class)->dispose (object);
}
static void
gtk_clipper_class_init (GtkClipperClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = gtk_clipper_dispose;
}
static void
gtk_clipper_init (GtkClipper *self)
{
}
GdkPaintable *
gtk_clipper_new (GdkPaintable *paintable,
const graphene_rect_t *clip)
{
GtkClipper *self;
guint flags;
g_return_val_if_fail (GDK_IS_PAINTABLE (paintable), NULL);
g_return_val_if_fail (clip != NULL, NULL);
self = g_object_new (GTK_TYPE_CLIPPER, NULL);
self->paintable = g_object_ref (paintable);
flags = gdk_paintable_get_flags (paintable);
if ((flags & GDK_PAINTABLE_STATIC_CONTENTS) == 0)
g_signal_connect_swapped (paintable, "invalidate-contents", G_CALLBACK (gdk_paintable_invalidate_contents), self);
if ((flags & GDK_PAINTABLE_STATIC_SIZE) == 0)
g_signal_connect_swapped (paintable, "invalidate-size", G_CALLBACK (gdk_paintable_invalidate_size), self);
self->clip = *clip;
return GDK_PAINTABLE (self);
}