mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 21:51:08 +00:00
70380661fe
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
158 lines
4.5 KiB
C
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);
|
|
}
|