diff --git a/retro-gtk/meson.build b/retro-gtk/meson.build index 12914a24c4d595d69179a2d4f20a5575ae2056b4..96d979f48f314754544c0cadd22a5c0ebf384767 100644 --- a/retro-gtk/meson.build +++ b/retro-gtk/meson.build @@ -33,6 +33,7 @@ retro_gtk_sources = [ 'retro-option.c', 'retro-option-iterator.c', 'retro-pa-player.c', + 'retro-pixbuf.c', 'retro-pixdata.c', 'retro-pixel-format.c', 'retro-rumble-effect.c', @@ -59,6 +60,7 @@ retro_gtk_headers = [ 'retro-module-query.h', 'retro-option.h', 'retro-option-iterator.h', + 'retro-pixbuf.h', 'retro-pixdata.h', 'retro-rumble-effect.h', 'retro-video-filter.h', diff --git a/retro-gtk/retro-cairo-display.c b/retro-gtk/retro-cairo-display.c index 379f52ac6a540ae3f91a156559efdf123f9f4712..1fb637b67d52e3d67ac4ed42f7b470e0325adb18 100644 --- a/retro-gtk/retro-cairo-display.c +++ b/retro-gtk/retro-cairo-display.c @@ -2,6 +2,7 @@ #include "retro-cairo-display.h" +#include "retro-pixbuf.h" #include "retro-pixdata.h" struct _RetroCairoDisplay @@ -312,11 +313,16 @@ retro_cairo_display_get_pixbuf (RetroCairoDisplay *self) * @pixbuf: a #GdkPixbuf * * Sets @pixbuf as the currently displayed video frame. + * + * retro_pixbuf_set_aspect_ratio() can be used to specify the aspect ratio for + * the pixbuf. Otherwise the core's aspect ratio will be used. */ void retro_cairo_display_set_pixbuf (RetroCairoDisplay *self, GdkPixbuf *pixbuf) { + gfloat aspect_ratio; + g_return_if_fail (self != NULL); if (self->pixbuf == pixbuf) @@ -327,6 +333,10 @@ retro_cairo_display_set_pixbuf (RetroCairoDisplay *self, if (pixbuf != NULL) self->pixbuf = g_object_ref (pixbuf); + aspect_ratio = retro_pixbuf_get_aspect_ratio (pixbuf); + if (aspect_ratio != 0.f) + self->aspect_ratio = aspect_ratio; + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PIXBUF]); } diff --git a/retro-gtk/retro-core-view.c b/retro-gtk/retro-core-view.c index 2866082700b4f4327bb69f8df82609df47bf495a..682c9f990c5c1a3aeb9aca664a6384770e65846a 100644 --- a/retro-gtk/retro-core-view.c +++ b/retro-gtk/retro-core-view.c @@ -537,6 +537,9 @@ retro_core_view_set_core (RetroCoreView *self, * @pixbuf: a #GdkPixbuf * * Sets @pixbuf as the currently displayed video frame. + * + * retro_pixbuf_set_aspect_ratio() can be used to specify the aspect ratio for + * the pixbuf. Otherwise the core's aspect ratio will be used. */ void retro_core_view_set_pixbuf (RetroCoreView *self, diff --git a/retro-gtk/retro-gl-display.c b/retro-gtk/retro-gl-display.c index d511f61d7c15ab45e963f75476f978493b9e5926..d8f563d78324aefecb7084e8ec60c301e4ee8a3a 100644 --- a/retro-gtk/retro-gl-display.c +++ b/retro-gtk/retro-gl-display.c @@ -4,6 +4,7 @@ #include #include "retro-glsl-filter.h" +#include "retro-pixbuf.h" #include "retro-pixdata.h" struct _RetroGLDisplay @@ -492,11 +493,16 @@ retro_gl_display_get_pixbuf (RetroGLDisplay *self) * @pixbuf: a #GdkPixbuf * * Sets @pixbuf as the currently displayed video frame. + * + * retro_pixbuf_set_aspect_ratio() can be used to specify the aspect ratio for + * the pixbuf. Otherwise the core's aspect ratio will be used. */ void retro_gl_display_set_pixbuf (RetroGLDisplay *self, GdkPixbuf *pixbuf) { + gfloat aspect_ratio; + g_return_if_fail (RETRO_IS_GL_DISPLAY (self)); if (self->pixbuf == pixbuf) @@ -507,6 +513,10 @@ retro_gl_display_set_pixbuf (RetroGLDisplay *self, if (pixbuf != NULL) self->pixbuf = g_object_ref (pixbuf); + aspect_ratio = retro_pixbuf_get_aspect_ratio (pixbuf); + if (aspect_ratio != 0.f) + self->aspect_ratio = aspect_ratio; + gtk_widget_queue_draw (GTK_WIDGET (self)); } diff --git a/retro-gtk/retro-gtk.h b/retro-gtk/retro-gtk.h index bcbb8188a3dea0866455063502655f3cec16ee7c..9cb91cdb20baade7e331df2ad3603a7293286950 100644 --- a/retro-gtk/retro-gtk.h +++ b/retro-gtk/retro-gtk.h @@ -25,6 +25,7 @@ #include "retro-module-query.h" #include "retro-option.h" #include "retro-option-iterator.h" +#include "retro-pixbuf.h" #include "retro-pixdata.h" #include "retro-video-filter.h" diff --git a/retro-gtk/retro-pixbuf.c b/retro-gtk/retro-pixbuf.c new file mode 100644 index 0000000000000000000000000000000000000000..900417d7f000e08bcd3453315afb52d3dd2e1a5f --- /dev/null +++ b/retro-gtk/retro-pixbuf.c @@ -0,0 +1,54 @@ +// This file is part of retro-gtk. License: GPL-3.0+. + +#include "retro-pixbuf.h" +#include + +/** + * retro_pixbuf_get_aspect_ratio: + * @pixbuf: a #GdkPixbuf + * + * Gets the aspect ratio of @pixbuf by reading the 'aspect-ratio' pixbuf option. + * + * Returns: the aspect ratio, or 0 if the option is not set or its value is invalid. + */ +gfloat +retro_pixbuf_get_aspect_ratio (GdkPixbuf *pixbuf) +{ + const gchar *aspect_ratio_str; + gfloat result = 0.f; + + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), 0.f); + + aspect_ratio_str = gdk_pixbuf_get_option (pixbuf, "aspect-ratio"); + + if (!aspect_ratio_str) + return 0.f; + + sscanf (aspect_ratio_str, "%g", &result); + + return result; +} + +/** + * retro_pixbuf_set_aspect_ratio: + * @pixbuf: a #GdkPixbuf + * @aspect_ratio: the aspect ratio value + * + * Sets the aspect ratio of @pixbuf by setting the 'aspect-ratio' pixbuf option. + * Use retro_pixbuf_get_aspect_ratio() to retrieve it. + */ +void +retro_pixbuf_set_aspect_ratio (GdkPixbuf *pixbuf, + gfloat aspect_ratio) +{ + g_autofree gchar *aspect_ratio_string = NULL; + + g_return_if_fail (GDK_IS_PIXBUF (pixbuf)); + g_return_if_fail (aspect_ratio > 0.f); + + aspect_ratio_string = g_strdup_printf ("%g", aspect_ratio); + + gdk_pixbuf_remove_option (pixbuf, "aspect-ratio"); + + gdk_pixbuf_set_option (pixbuf, "aspect-ratio", aspect_ratio_string); +} diff --git a/retro-gtk/retro-pixbuf.h b/retro-gtk/retro-pixbuf.h new file mode 100644 index 0000000000000000000000000000000000000000..fa3d53e858d65ebb3e3336cac87c7f894e57b3b8 --- /dev/null +++ b/retro-gtk/retro-pixbuf.h @@ -0,0 +1,21 @@ +// This file is part of retro-gtk. License: GPL-3.0+. + +#ifndef RETRO_PIXBUF_H +#define RETRO_PIXBUF_H + +#if !defined(__RETRO_GTK_INSIDE__) && !defined(RETRO_GTK_COMPILATION) +# error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +gfloat retro_pixbuf_get_aspect_ratio (GdkPixbuf *pixbuf); +void retro_pixbuf_set_aspect_ratio (GdkPixbuf *pixbuf, + gfloat aspect_ratio); + +G_END_DECLS + +#endif /* RETRO_PIXBUF_H */ diff --git a/retro-gtk/retro-pixdata.c b/retro-gtk/retro-pixdata.c index b46c7faea3f995c9da630b3eb8afc82a5aa0088e..b2208d8f1f0bd4ecd4796684966256527c3d0698 100644 --- a/retro-gtk/retro-pixdata.c +++ b/retro-gtk/retro-pixdata.c @@ -3,6 +3,7 @@ #include "retro-pixdata-private.h" #include +#include "retro-pixbuf.h" G_DEFINE_BOXED_TYPE (RetroPixdata, retro_pixdata, retro_pixdata_copy, retro_pixdata_free) @@ -319,8 +320,8 @@ retro_pixdata_to_pixbuf (RetroPixdata *self) rgba8888 *rgba8888_data; GdkPixbuf *pixbuf; gfloat x_dpi; - gchar *x_dpi_string; - gchar *y_dpi_string; + g_autofree gchar *x_dpi_string = NULL; + g_autofree gchar *y_dpi_string = NULL; g_return_val_if_fail (self != NULL, NULL); @@ -343,13 +344,15 @@ retro_pixdata_to_pixbuf (RetroPixdata *self) self->width * sizeof (rgba8888), pixels_free, NULL); + /* x-dpi and y-dpi are deprecated, retro_pixbuf_get_aspect_ratio() and + * retro_pixbuf_set_aspect_ratio() should be used instead. */ x_dpi = self->aspect_ratio * RETRO_CAIRO_DISPLAY_Y_DPI; x_dpi_string = g_strdup_printf ("%g", x_dpi); y_dpi_string = g_strdup_printf ("%g", RETRO_CAIRO_DISPLAY_Y_DPI); gdk_pixbuf_set_option (pixbuf, "x-dpi", x_dpi_string); gdk_pixbuf_set_option (pixbuf, "y-dpi", y_dpi_string); - g_free (y_dpi_string); - g_free (x_dpi_string); + + retro_pixbuf_set_aspect_ratio (pixbuf, self->aspect_ratio); return pixbuf; }