From f33c5218364377ac41a6bbaf36e1a8a98412a368 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 8 May 2022 13:53:04 -0400 Subject: [PATCH 1/2] Fixes for gdk_memory_texture_new_subtexture There were several mistakes here. The width of subtextures was set to the width of the main texture, the data size wasn't properly calculated, and the preconditions were inverted. Yay us! --- gdk/gdkmemorytexture.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gdk/gdkmemorytexture.c b/gdk/gdkmemorytexture.c index c9aecd5cea..e241ebd0a3 100644 --- a/gdk/gdkmemorytexture.c +++ b/gdk/gdkmemorytexture.c @@ -178,19 +178,19 @@ gdk_memory_texture_new_subtexture (GdkMemoryTexture *source, GBytes *bytes; g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE (source), NULL); - g_return_val_if_fail (x < 0 || x >= GDK_TEXTURE (source)->width, NULL); - g_return_val_if_fail (y < 0 || y >= GDK_TEXTURE (source)->height, NULL); - g_return_val_if_fail (width <= 0 || x + width > GDK_TEXTURE (source)->width, NULL); - g_return_val_if_fail (height <= 0 || y + height > GDK_TEXTURE (source)->height, NULL); + g_return_val_if_fail (x >= 0 || x < GDK_TEXTURE (source)->width, NULL); + g_return_val_if_fail (y >= 0 || y < GDK_TEXTURE (source)->height, NULL); + g_return_val_if_fail (width > 0 || x + width <= GDK_TEXTURE (source)->width, NULL); + g_return_val_if_fail (height > 0 || y + height <= GDK_TEXTURE (source)->height, NULL); texture = GDK_TEXTURE (source); bpp = gdk_memory_format_bytes_per_pixel (texture->format); offset = y * source->stride + x * bpp; - size = source->stride * (height - 1) + x * bpp; + size = source->stride * (height - 1) + width * bpp; bytes = g_bytes_new_from_bytes (source->bytes, offset, size); - result = gdk_memory_texture_new (texture->width, - texture->height, + result = gdk_memory_texture_new (width, + height, texture->format, bytes, source->stride); From 6164908bd3dbc8d864dc4b8f02393f4066c948a8 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 13 May 2022 09:31:40 -0400 Subject: [PATCH 2/2] Add tests for gdk_memory_texture_new_subtexture This checks the fixes in the previous commit. --- testsuite/gdk/meson.build | 4 +-- testsuite/gdk/texture.c | 53 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/testsuite/gdk/meson.build b/testsuite/gdk/meson.build index 3de704fc64..03528a3905 100644 --- a/testsuite/gdk/meson.build +++ b/testsuite/gdk/meson.build @@ -26,7 +26,6 @@ tests = [ { 'name': 'rectangle' }, { 'name': 'rgba' }, { 'name': 'seat' }, - { 'name': 'texture' }, { 'name': 'texture-threads' }, ] @@ -54,7 +53,8 @@ foreach t : tests endforeach internal_tests = [ - 'image' + 'image', + 'texture', ] foreach t : internal_tests diff --git a/testsuite/gdk/texture.c b/testsuite/gdk/texture.c index 1a218ddd4a..76112b2449 100644 --- a/testsuite/gdk/texture.c +++ b/testsuite/gdk/texture.c @@ -1,5 +1,7 @@ #include +#include "gdk/gdkmemorytextureprivate.h" + static void compare_pixels (int width, int height, @@ -108,6 +110,56 @@ test_texture_save_to_png (void) g_object_unref (texture2); } +static void +test_texture_subtexture (void) +{ + cairo_t *cr; + cairo_surface_t *surface; + cairo_pattern_t *pattern; + GdkTexture *texture, *subtexture; + guchar *data, *subdata; + gsize stride, substride; + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 64, 64); + cr = cairo_create (surface); + + pattern = cairo_pattern_create_linear (0, 0, 64, 64); + cairo_pattern_add_color_stop_rgba (pattern, 0, 1, 0, 0, 0.2); + cairo_pattern_add_color_stop_rgba (pattern, 1, 1, 0, 1, 1); + + cairo_set_source (cr, pattern); + cairo_paint (cr); + + texture = gdk_texture_new_for_surface (surface); + + cairo_pattern_destroy (pattern); + cairo_destroy (cr); + cairo_surface_destroy (surface); + + subtexture = gdk_memory_texture_new_subtexture (GDK_MEMORY_TEXTURE (texture), 0, 0, 32, 32); + + g_assert_cmpint (gdk_texture_get_width (subtexture), ==, 32); + g_assert_cmpint (gdk_texture_get_height (subtexture), ==, 32); + + data = g_new0 (guchar, 64 * 64 * 4); + stride = 64 * 4; + gdk_texture_download (texture, data, stride); + + subdata = g_new0 (guchar, 32 * 32 * 4); + substride = 32 * 4; + gdk_texture_download (subtexture, subdata, substride); + + compare_pixels (32, 32, + data, stride, + subdata, substride); + + g_free (data); + g_free (subdata); + + g_object_unref (subtexture); + g_object_unref (texture); +} + int main (int argc, char *argv[]) { @@ -117,6 +169,7 @@ main (int argc, char *argv[]) g_test_add_func ("/texture/from-pixbuf", test_texture_from_pixbuf); g_test_add_func ("/texture/from-resource", test_texture_from_resource); g_test_add_func ("/texture/save-to-png", test_texture_save_to_png); + g_test_add_func ("/texture/subtexture", test_texture_subtexture); return g_test_run (); }