From 72f5c6d9310253f4d573fbb79965a1ada3d831ba Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 27 Dec 2020 20:07:45 +0100 Subject: [PATCH] API: Add gtk_picture_add_paintable_bounds() Allows a caller to see where a picture has placed a paintable. --- docs/reference/gtk/gtk4-sections.txt | 1 + gtk/gtkpicture.c | 96 ++++++++++++++++++---------- gtk/gtkpicture.h | 3 + 3 files changed, 67 insertions(+), 33 deletions(-) diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index ad134ee06f..5d0e11331b 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -2209,6 +2209,7 @@ gtk_picture_set_can_shrink gtk_picture_get_can_shrink gtk_picture_set_alternative_text gtk_picture_get_alternative_text +gtk_picture_get_paintable_bounds GTK_PICTURE GTK_IS_PICTURE diff --git a/gtk/gtkpicture.c b/gtk/gtkpicture.c index 6f0eb83240..9174302653 100644 --- a/gtk/gtkpicture.c +++ b/gtk/gtkpicture.c @@ -114,44 +114,20 @@ gtk_picture_snapshot (GtkWidget *widget, GtkSnapshot *snapshot) { GtkPicture *self = GTK_PICTURE (widget); - double ratio; - int x, y, width, height; - double w, h; + graphene_rect_t bounds; if (self->paintable == NULL) return; - width = gtk_widget_get_width (widget); - height = gtk_widget_get_height (widget); - ratio = gdk_paintable_get_intrinsic_aspect_ratio (self->paintable); + gtk_picture_get_paintable_bounds (self, &bounds); - if (!self->keep_aspect_ratio || ratio == 0) - { - gdk_paintable_snapshot (self->paintable, snapshot, width, height); - } - else - { - double picture_ratio = (double) width / height; - - if (ratio > picture_ratio) - { - w = width; - h = width / ratio; - } - else - { - w = height * ratio; - h = height; - } - - x = (width - ceil (w)) / 2; - y = floor(height - ceil (h)) / 2; - - gtk_snapshot_save (snapshot); - gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y)); - gdk_paintable_snapshot (self->paintable, snapshot, w, h); - gtk_snapshot_restore (snapshot); - } + gtk_snapshot_save (snapshot); + gtk_snapshot_translate (snapshot, &bounds.origin); + gdk_paintable_snapshot (self->paintable, + snapshot, + bounds.size.width, + bounds.size.height); + gtk_snapshot_restore (snapshot); } static GtkSizeRequestMode @@ -1007,3 +983,57 @@ gtk_picture_get_alternative_text (GtkPicture *self) return self->alternative_text; } +/** + * gtk_picture_get_paintable_bounds: + * @self: a #GtkPicture + * @bounds: (out) (caller-allocates): Set to the bounds of the + * paintable + * + * Gets the area inside @self that the paintable will be drawn + * to. This can be used to map coordinates of gestures back to + * the paintable. + * + * If @self contains no paintable, the empty rect is returned. + **/ +void +gtk_picture_get_paintable_bounds (GtkPicture *self, + graphene_rect_t *bounds) +{ + double ratio, picture_ratio; + int x, y, width, height; + double w, h; + + if (self->paintable == NULL) + { + graphene_rect_init (bounds, 0, 0, 0, 0); + return; + } + + width = gtk_widget_get_width (GTK_WIDGET (self)); + height = gtk_widget_get_height (GTK_WIDGET (self)); + ratio = gdk_paintable_get_intrinsic_aspect_ratio (self->paintable); + + if (!self->keep_aspect_ratio || ratio == 0) + { + graphene_rect_init (bounds, 0, 0, width, height); + return; + } + + picture_ratio = (double) width / height; + if (ratio > picture_ratio) + { + w = width; + h = width / ratio; + } + else + { + w = height * ratio; + h = height; + } + + x = (width - ceil (w)) / 2; + y = floor(height - ceil (h)) / 2; + + graphene_rect_init (bounds, x, y, w, h); +} + diff --git a/gtk/gtkpicture.h b/gtk/gtkpicture.h index 80f0334f0e..2b0c4a0ec5 100644 --- a/gtk/gtkpicture.h +++ b/gtk/gtkpicture.h @@ -86,6 +86,9 @@ void gtk_picture_set_alternative_text (GtkPicture GDK_AVAILABLE_IN_ALL const char * gtk_picture_get_alternative_text (GtkPicture *self); +GDK_AVAILABLE_IN_ALL +void gtk_picture_get_paintable_bounds (GtkPicture *self, + graphene_rect_t *bounds); G_END_DECLS