[gtk/matthiasc/for-master] testupload: Test more formats




commit 593907f7b0ae5b573138b5de8fc1542d7b0c4b30
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Sep 26 17:26:12 2020 -0400

    testupload: Test more formats
    
    Copy the format conversion code from GdkMemoryTexture
    so we can produce all formats, and test them all.
    
    The upload fast paths assume that the stride is a
    multiple of four, so some of the padding values cause
    it to fail. Apart from that, things seem to work for
    all combinations.

 tests/testupload.c | 560 ++++++++++++++++++++++++++++++++---------------------
 1 file changed, 341 insertions(+), 219 deletions(-)
---
diff --git a/tests/testupload.c b/tests/testupload.c
index 747c94211f..93cacfe696 100644
--- a/tests/testupload.c
+++ b/tests/testupload.c
@@ -1,272 +1,394 @@
 #include <gtk/gtk.h>
 
-static void
-add_to_grid (GtkWidget *grid,
-             int        left,
-             int        top,
-             int        n_channels,
-             gboolean   premul,
-             int        width,
-             int        height,
-             int        stride,
-             GtkWidget *picture)
+static const char *format_name[] = {
+  "BGRAp", "ARGBp", "RGBAp",
+  "BGRA", "ARGB", "RGBA", "ABGR",
+  "RGB", "BGR",
+};
+
+static const char *
+format_to_string (GdkMemoryFormat format)
 {
-  char *text;
+  if (format < GDK_MEMORY_N_FORMATS)
+    return format_name[format];
+  else
+    return "ERROR";
+}
 
-  gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Channels"), left, top, 1, 1);
-  gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Width"), left, top + 1, 1, 1);
-  gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Height"), left, top + 2, 1, 1);
-  gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Stride"), left, top + 3, 1, 1);
+/* Copied from gdkmemorytexture.c */
 
-  text = g_strdup_printf ("%d%s", n_channels, premul ? " (premul)" : "");
-  gtk_grid_attach (GTK_GRID (grid), gtk_label_new (text), left + 1, top, 1, 1);
-  g_free (text);
-  text = g_strdup_printf ("%d", width);
-  gtk_grid_attach (GTK_GRID (grid), gtk_label_new (text), left + 1, top + 1, 1, 1);
-  g_free (text);
-  text = g_strdup_printf ("%d", height);
-  gtk_grid_attach (GTK_GRID (grid), gtk_label_new (text), left + 1, top + 2, 1, 1);
-  g_free (text);
-  text = g_strdup_printf ("%d", stride);
-  gtk_grid_attach (GTK_GRID (grid), gtk_label_new (text), left + 1, top + 3, 1, 1);
-  g_free (text);
+static void
+convert_memcpy (guchar       *dest_data,
+                gsize         dest_stride,
+                const guchar *src_data,
+                gsize         src_stride,
+                gsize         width,
+                gsize         height)
+{
+  gsize y;
 
-  gtk_grid_attach (GTK_GRID (grid), picture, left + 2, top + 0, 1, 4);
+  for (y = 0; y < height; y++)
+    memcpy (dest_data + y * dest_stride, src_data + y * src_stride, 4 * width);
 }
 
-int
-main (int argc, char *argv[])
+static void
+convert_memcpy3 (guchar       *dest_data,
+                 gsize         dest_stride,
+                 const guchar *src_data,
+                 gsize         src_stride,
+                 gsize         width,
+                 gsize         height)
 {
-  GtkWidget *window, *grid;
-  GdkPixbuf *source, *pb, *pb2;
-  GError *error = NULL;
-  cairo_t *cr;
-  cairo_surface_t *surface;
-  GBytes *bytes;
-  GdkTexture *texture;
-
-  gtk_init ();
+  gsize y;
 
-  window = gtk_window_new ();
-  grid = gtk_grid_new ();
-  gtk_widget_set_margin_top (grid, 10);
-  gtk_widget_set_margin_bottom (grid, 10);
-  gtk_widget_set_margin_start (grid, 10);
-  gtk_widget_set_margin_end (grid, 10);
-  gtk_grid_set_row_spacing (GTK_GRID (grid), 10);
-  gtk_grid_set_column_spacing (GTK_GRID (grid), 10);
-  gtk_window_set_child (GTK_WINDOW (window), grid);
-
-  source = gdk_pixbuf_new_from_file_at_scale ("tests/portland-rose.jpg",
-                                              200, 200, TRUE,
-                                              &error);
-  if (!source)
-    g_error ("%s", error->message);
+  for (y = 0; y < height; y++)
+    memcpy (dest_data + y * dest_stride, src_data + y * src_stride, 3 * width);
+}
 
-  add_to_grid (grid, 0, 0,
-               gdk_pixbuf_get_n_channels (source),
-               FALSE,
-               gdk_pixbuf_get_width (source),
-               gdk_pixbuf_get_height (source),
-               gdk_pixbuf_get_rowstride (source),
-               gtk_picture_new_for_pixbuf (source));
+#define SWIZZLE3(R,G,B) \
+static void \
+convert_swizzle ## R ## G ## B (guchar       *dest_data, \
+                                gsize         dest_stride, \
+                                const guchar *src_data, \
+                                gsize         src_stride, \
+                                gsize         width, \
+                                gsize         height) \
+{ \
+  gsize x, y; \
+\
+  for (y = 0; y < height; y++) \
+    { \
+      for (x = 0; x < width; x++) \
+        { \
+          dest_data[3 * x + R] = src_data[3 * x + 0]; \
+          dest_data[3 * x + G] = src_data[3 * x + 1]; \
+          dest_data[3 * x + B] = src_data[3 * x + 2]; \
+        } \
+\
+      dest_data += dest_stride; \
+      src_data += src_stride; \
+    } \
+}
 
-  g_object_unref (source);
+SWIZZLE3(2,1,0)
+
+#define SWIZZLE(A,R,G,B) \
+static void \
+convert_swizzle ## A ## R ## G ## B (guchar       *dest_data, \
+                                     gsize         dest_stride, \
+                                     const guchar *src_data, \
+                                     gsize         src_stride, \
+                                     gsize         width, \
+                                     gsize         height) \
+{ \
+  gsize x, y; \
+\
+  for (y = 0; y < height; y++) \
+    { \
+      for (x = 0; x < width; x++) \
+        { \
+          dest_data[4 * x + A] = src_data[4 * x + 0]; \
+          dest_data[4 * x + R] = src_data[4 * x + 1]; \
+          dest_data[4 * x + G] = src_data[4 * x + 2]; \
+          dest_data[4 * x + B] = src_data[4 * x + 3]; \
+        } \
+\
+      dest_data += dest_stride; \
+      src_data += src_stride; \
+    } \
+}
 
-  source = gdk_pixbuf_new_from_file_at_scale ("tests/portland-rose.jpg",
-                                              199, 199, TRUE,
-                                              &error);
-  if (!source)
-    g_error ("%s", error->message);
+SWIZZLE(3,2,1,0)
+SWIZZLE(2,1,0,3)
+SWIZZLE(3,0,1,2)
+SWIZZLE(1,2,3,0)
+
+#define SWIZZLE_OPAQUE(A,R,G,B) \
+static void \
+convert_swizzle_opaque_## A ## R ## G ## B (guchar       *dest_data, \
+                                            gsize         dest_stride, \
+                                            const guchar *src_data, \
+                                            gsize         src_stride, \
+                                            gsize         width, \
+                                            gsize         height) \
+{ \
+  gsize x, y; \
+\
+  for (y = 0; y < height; y++) \
+    { \
+      for (x = 0; x < width; x++) \
+        { \
+          dest_data[4 * x + A] = 0xFF; \
+          dest_data[4 * x + R] = src_data[3 * x + 0]; \
+          dest_data[4 * x + G] = src_data[3 * x + 1]; \
+          dest_data[4 * x + B] = src_data[3 * x + 2]; \
+        } \
+\
+      dest_data += dest_stride; \
+      src_data += src_stride; \
+    } \
+}
 
-  add_to_grid (grid, 4, 0,
-               gdk_pixbuf_get_n_channels (source),
-               FALSE,
-               gdk_pixbuf_get_width (source),
-               gdk_pixbuf_get_height (source),
-               gdk_pixbuf_get_rowstride (source),
-               gtk_picture_new_for_pixbuf (source));
+SWIZZLE_OPAQUE(3,2,1,0)
+SWIZZLE_OPAQUE(3,0,1,2)
+SWIZZLE_OPAQUE(0,1,2,3)
+SWIZZLE_OPAQUE(0,3,2,1)
+
+#define PREMULTIPLY(d,c,a) G_STMT_START { guint t = c * a + 0x80; d = ((t >> 8) + t) >> 8; } G_STMT_END
+#define SWIZZLE_PREMULTIPLY(A,R,G,B, A2,R2,G2,B2) \
+static void \
+convert_swizzle_premultiply_ ## A ## R ## G ## B ## _ ## A2 ## R2 ## G2 ## B2 \
+                                    (guchar       *dest_data, \
+                                     gsize         dest_stride, \
+                                     const guchar *src_data, \
+                                     gsize         src_stride, \
+                                     gsize         width, \
+                                     gsize         height) \
+{ \
+  gsize x, y; \
+\
+  for (y = 0; y < height; y++) \
+    { \
+      for (x = 0; x < width; x++) \
+        { \
+          dest_data[4 * x + A] = src_data[4 * x + A2]; \
+          PREMULTIPLY(dest_data[4 * x + R], src_data[4 * x + R2], src_data[4 * x + A2]); \
+          PREMULTIPLY(dest_data[4 * x + G], src_data[4 * x + G2], src_data[4 * x + A2]); \
+          PREMULTIPLY(dest_data[4 * x + B], src_data[4 * x + B2], src_data[4 * x + A2]); \
+        } \
+\
+      dest_data += dest_stride; \
+      src_data += src_stride; \
+    } \
+}
 
-  g_object_unref (source);
+SWIZZLE_PREMULTIPLY (3,2,1,0, 3,2,1,0)
+SWIZZLE_PREMULTIPLY (0,1,2,3, 3,2,1,0)
+SWIZZLE_PREMULTIPLY (3,2,1,0, 0,1,2,3)
+SWIZZLE_PREMULTIPLY (0,1,2,3, 0,1,2,3)
+SWIZZLE_PREMULTIPLY (3,2,1,0, 3,0,1,2)
+SWIZZLE_PREMULTIPLY (0,1,2,3, 3,0,1,2)
+SWIZZLE_PREMULTIPLY (3,2,1,0, 0,3,2,1)
+SWIZZLE_PREMULTIPLY (0,1,2,3, 0,3,2,1)
+SWIZZLE_PREMULTIPLY (3,0,1,2, 3,2,1,0)
+SWIZZLE_PREMULTIPLY (3,0,1,2, 0,1,2,3)
+SWIZZLE_PREMULTIPLY (3,0,1,2, 3,0,1,2)
+SWIZZLE_PREMULTIPLY (3,0,1,2, 0,3,2,1)
+
+typedef void (* ConversionFunc) (guchar       *dest_data,
+                                 gsize         dest_stride,
+                                 const guchar *src_data,
+                                 gsize         src_stride,
+                                 gsize         width,
+                                 gsize         height);
+
+static ConversionFunc converters[GDK_MEMORY_N_FORMATS][GDK_MEMORY_N_FORMATS] =
+{
+  { convert_memcpy, convert_swizzle3210, convert_swizzle2103, NULL, NULL, NULL, NULL, NULL, NULL },
+  { convert_swizzle3210, convert_memcpy, convert_swizzle3012, NULL, NULL, NULL, NULL, NULL, NULL },
+  { convert_swizzle2103, convert_swizzle1230, convert_memcpy, NULL, NULL, NULL, NULL, NULL, NULL },
+  { convert_swizzle_premultiply_3210_3210, convert_swizzle_premultiply_0123_3210, 
convert_swizzle_premultiply_3012_3210, convert_memcpy, NULL, NULL, NULL, NULL, NULL },
+  { convert_swizzle_premultiply_3210_0123, convert_swizzle_premultiply_0123_0123, 
convert_swizzle_premultiply_3012_0123, NULL, convert_memcpy, NULL, NULL, NULL, NULL },
+  { convert_swizzle_premultiply_3210_3012, convert_swizzle_premultiply_0123_3012, 
convert_swizzle_premultiply_3012_3012, convert_swizzle2103, convert_swizzle1230, convert_memcpy, 
convert_swizzle3210, NULL, NULL },
+  { convert_swizzle_premultiply_3210_0321, convert_swizzle_premultiply_0123_0321, 
convert_swizzle_premultiply_3012_0321, NULL, NULL, NULL, convert_memcpy, NULL, NULL },
+  { convert_swizzle_opaque_3210, convert_swizzle_opaque_0123, convert_swizzle_opaque_3012, NULL, NULL, NULL, 
NULL, convert_memcpy3, convert_swizzle210 },
+  { convert_swizzle_opaque_3012, convert_swizzle_opaque_0321, convert_swizzle_opaque_3210, NULL, NULL, NULL, 
NULL, convert_swizzle210, convert_memcpy3 },
+};
 
-  source = gdk_pixbuf_new_from_file_at_scale ("tests/portland-rose.jpg",
-                                              201, 201, TRUE,
-                                              &error);
+static void
+gdk_memory_convert (guchar          *dest_data,
+                    gsize            dest_stride,
+                    GdkMemoryFormat  dest_format,
+                    const guchar    *src_data,
+                    gsize            src_stride,
+                    GdkMemoryFormat  src_format,
+                    gsize            width,
+                    gsize            height)
+{
+  g_assert (dest_format < GDK_MEMORY_N_FORMATS);
+  g_assert (src_format < GDK_MEMORY_N_FORMATS);
 
-  if (!source)
-    g_error ("%s", error->message);
+  if (converters[src_format][dest_format] == NULL)
+    g_error ("Conversion from %s to %s not supported", format_to_string (src_format), format_to_string 
(dest_format));
 
-  pb = gdk_pixbuf_new_subpixbuf (source, 0, 0, 200, 200);
+  converters[src_format][dest_format] (dest_data, dest_stride, src_data, src_stride, width, height);
+}
 
-  add_to_grid (grid, 8, 0,
-               gdk_pixbuf_get_n_channels (pb),
-               FALSE,
-               gdk_pixbuf_get_width (pb),
-               gdk_pixbuf_get_height (pb),
-               gdk_pixbuf_get_rowstride (pb),
-               gtk_picture_new_for_pixbuf (pb));
+/* End of copied code */
 
-  g_object_unref (source);
-  g_object_unref (pb);
+static GdkTexture *
+make_texture (GdkMemoryFormat  format,
+              int              padding,
+              int             *out_stride,
+              int             *out_bpp)
+{
+  GdkPixbuf *source;
+  GdkMemoryFormat source_format;
+  int width, height, stride, bpp;
+  guchar *data;
+  GBytes *bytes;
+  GdkTexture *texture;
+  GError *error = NULL;
 
+  width = height = 200;
 
   source = gdk_pixbuf_new_from_file_at_scale ("tests/portland-rose.jpg",
-                                              200, 200, TRUE,
+                                              width, height, TRUE,
                                               &error);
   if (!source)
     g_error ("%s", error->message);
 
-  pb = gdk_pixbuf_add_alpha (source, FALSE, 0, 0, 0);
+  source_format = GDK_MEMORY_R8G8B8;
+  bpp = 3;
 
-  add_to_grid (grid, 0, 5,
-               gdk_pixbuf_get_n_channels (pb),
-               FALSE,
-               gdk_pixbuf_get_width (pb),
-               gdk_pixbuf_get_height (pb),
-               gdk_pixbuf_get_rowstride (pb),
-               gtk_picture_new_for_pixbuf (pb));
+  if (format != GDK_MEMORY_R8G8B8 && format != GDK_MEMORY_B8G8R8)
+    {
+      bpp = 4;
 
-  g_object_unref (source);
-  g_object_unref (pb);
+      /* add an alpha channel with 50% alpha */
+      GdkPixbuf *pb = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height);
+      gdk_pixbuf_composite (source, pb, 0, 0, width, height, 0, 0, 1, 1, GDK_INTERP_BILINEAR, 128);
+      g_object_unref (source);
+      source = pb;
 
-  source = gdk_pixbuf_new_from_file_at_scale ("tests/portland-rose.jpg",
-                                              199, 199, TRUE,
-                                              &error);
-  if (!source)
-    g_error ("%s", error->message);
+      source_format = GDK_MEMORY_R8G8B8A8;
+    }
 
-  pb = gdk_pixbuf_add_alpha (source, FALSE, 0, 0, 0);
+  stride = bpp * width + padding;
+  data = g_new0 (guchar, stride * height);
 
-  add_to_grid (grid, 4, 5,
-               gdk_pixbuf_get_n_channels (pb),
-               FALSE,
-               gdk_pixbuf_get_width (pb),
-               gdk_pixbuf_get_height (pb),
-               gdk_pixbuf_get_rowstride (pb),
-               gtk_picture_new_for_pixbuf (pb));
+  gdk_memory_convert (data, stride, format,
+                      gdk_pixbuf_get_pixels (source),
+                      gdk_pixbuf_get_rowstride (source),
+                      source_format,
+                      width, height);
 
   g_object_unref (source);
-  g_object_unref (pb);
 
-  source = gdk_pixbuf_new_from_file_at_scale ("tests/portland-rose.jpg",
-                                              201, 201, TRUE,
-                                              &error);
-  if (!source)
-    g_error ("%s", error->message);
+  bytes = g_bytes_new_take (data, stride * height);
+  texture = gdk_memory_texture_new (width, height, format, bytes, stride);
+  g_bytes_unref (bytes);
 
-  pb = gdk_pixbuf_add_alpha (source, FALSE, 0, 0, 0);
-  pb2 = gdk_pixbuf_new_subpixbuf (pb, 0, 0, 200, 200);
+  *out_stride = stride;
+  *out_bpp = bpp;
 
-  add_to_grid (grid, 8, 5,
-               gdk_pixbuf_get_n_channels (pb2),
-               FALSE,
-               gdk_pixbuf_get_width (pb2),
-               gdk_pixbuf_get_height (pb2),
-               gdk_pixbuf_get_rowstride (pb2),
-               gtk_picture_new_for_pixbuf (pb2));
+  return texture;
+}
 
-  g_object_unref (source);
-  g_object_unref (pb);
-  g_object_unref (pb2);
+static void
+update_picture (GtkWidget *picture)
+{
+  GdkMemoryFormat format;
+  int padding;
+  GdkTexture *texture;
+  GtkLabel *label;
+  char *text;
+  int stride;
+  int bpp;
 
-  source = gdk_pixbuf_new_from_file_at_scale ("tests/portland-rose.jpg",
-                                              200, 200, TRUE,
-                                              &error);
-  if (!source)
-    g_error ("%s", error->message);
+  format = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (picture), "format"));
+  padding = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (picture), "padding"));
 
-  pb = gdk_pixbuf_add_alpha (source, FALSE, 0, 0, 0);
-  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, gdk_pixbuf_get_width (pb), 
gdk_pixbuf_get_height (pb));
-  cr = cairo_create (surface);
-  gdk_cairo_set_source_pixbuf (cr, pb, 0, 0);
-  cairo_paint (cr);
-  cairo_destroy (cr);
-  bytes = g_bytes_new (cairo_image_surface_get_data (surface),
-                       cairo_image_surface_get_stride (surface) *
-                       cairo_image_surface_get_height (surface));
-  texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface),
-                                    cairo_image_surface_get_height (surface),
-                                    GDK_MEMORY_DEFAULT,
-                                    bytes,
-                                    cairo_image_surface_get_stride (surface));
-  g_bytes_unref (bytes);
+  texture = make_texture (format, padding, &stride, &bpp);
+  gtk_picture_set_paintable (GTK_PICTURE (picture), GDK_PAINTABLE (texture));
 
-  add_to_grid (grid, 0, 10,
-               4, TRUE,
-               cairo_image_surface_get_width (surface),
-               cairo_image_surface_get_height (surface),
-               cairo_image_surface_get_stride (surface),
-               gtk_picture_new_for_paintable (GDK_PAINTABLE (texture)));
+  label = GTK_LABEL (g_object_get_data (G_OBJECT (picture), "size_label"));
+  text = g_strdup_printf ("%d x %d @ %d",
+                          gdk_texture_get_width (texture),
+                          gdk_texture_get_height (texture),
+                          bpp);
+  gtk_label_set_label (label, text);
+  g_free (text);
 
-  g_object_unref (source);
-  g_object_unref (pb);
-  cairo_surface_destroy (surface);
+  label = GTK_LABEL (g_object_get_data (G_OBJECT (picture), "stride_label"));
+  text = g_strdup_printf ("%d", stride);
+  gtk_label_set_label (label, text);
+  g_free (text);
 
-  source = gdk_pixbuf_new_from_file_at_scale ("tests/portland-rose.jpg",
-                                              199, 199, TRUE,
-                                              &error);
-  if (!source)
-    g_error ("%s", error->message);
+  g_object_unref (texture);
+}
 
-  pb = gdk_pixbuf_add_alpha (source, FALSE, 0, 0, 0);
-  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, gdk_pixbuf_get_width (pb), 
gdk_pixbuf_get_height (pb));
-  cr = cairo_create (surface);
-  gdk_cairo_set_source_pixbuf (cr, pb, 0, 0);
-  cairo_paint (cr);
-  cairo_destroy (cr);
-  bytes = g_bytes_new (cairo_image_surface_get_data (surface),
-                       cairo_image_surface_get_stride (surface) *
-                       cairo_image_surface_get_height (surface));
-  texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface),
-                                    cairo_image_surface_get_height (surface),
-                                    GDK_MEMORY_DEFAULT,
-                                    bytes,
-                                    cairo_image_surface_get_stride (surface));
-  g_bytes_unref (bytes);
+static void
+update_format (GtkDropDown *dropdown,
+               GParamSpec  *pspec,
+               GtkWidget   *picture)
+{
+  g_object_set_data (G_OBJECT (picture), "format", GINT_TO_POINTER (gtk_drop_down_get_selected (dropdown)));
+  update_picture (picture);
+}
 
-  add_to_grid (grid, 4, 10,
-               4, TRUE,
-               cairo_image_surface_get_width (surface),
-               cairo_image_surface_get_height (surface),
-               cairo_image_surface_get_stride (surface),
-               gtk_picture_new_for_paintable (GDK_PAINTABLE (texture)));
+static void
+update_padding (GtkSpinButton *spinbutton,
+                GParamSpec    *pspec,
+                GtkWidget     *picture)
+{
+  g_object_set_data (G_OBJECT (picture), "padding", GINT_TO_POINTER (gtk_spin_button_get_value_as_int 
(spinbutton)));
+  update_picture (picture);
+}
 
-  g_object_unref (source);
-  g_object_unref (pb);
-  cairo_surface_destroy (surface);
+static void
+add_to_grid (GtkWidget      *grid,
+             int             left,
+             int             top,
+             GdkMemoryFormat format,
+             int             padding)
+{
+  GtkWidget *dropdown, *spin, *picture, *label;
 
-  source = gdk_pixbuf_new_from_file_at_scale ("tests/portland-rose.jpg",
-                                              201, 201, TRUE,
-                                              &error);
-  if (!source)
-    g_error ("%s", error->message);
+  picture = gtk_picture_new ();
+  gtk_grid_attach (GTK_GRID (grid), picture, left + 2, top + 0, 1, 4);
 
-  pb = gdk_pixbuf_add_alpha (source, FALSE, 0, 0, 0);
-  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, gdk_pixbuf_get_width (pb), 
gdk_pixbuf_get_height (pb));
-  cr = cairo_create (surface);
-  gdk_cairo_set_source_pixbuf (cr, pb, 0, 0);
-  cairo_paint (cr);
-  cairo_destroy (cr);
-  bytes = g_bytes_new (cairo_image_surface_get_data (surface),
-                       cairo_image_surface_get_stride (surface) *
-                       cairo_image_surface_get_height (surface));
-  texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface) - 1,
-                                    cairo_image_surface_get_height (surface) - 1,
-                                    GDK_MEMORY_DEFAULT,
-                                    bytes,
-                                    cairo_image_surface_get_stride (surface));
-  g_bytes_unref (bytes);
+  g_object_set_data (G_OBJECT (picture), "format", GINT_TO_POINTER (format));
+  g_object_set_data (G_OBJECT (picture), "padding", GINT_TO_POINTER (padding));
+
+  dropdown = gtk_drop_down_new_from_strings (format_name);
+  gtk_widget_set_valign (dropdown, GTK_ALIGN_CENTER);
+  gtk_drop_down_set_selected (GTK_DROP_DOWN (dropdown), format);
+  g_signal_connect (dropdown, "notify::selected", G_CALLBACK (update_format), picture);
+
+  gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Format"), left, top, 1, 1);
+  gtk_grid_attach (GTK_GRID (grid), dropdown, left + 1, top, 1, 1);
+
+  spin = gtk_spin_button_new_with_range (0, 10, 1);
+  gtk_widget_set_valign (spin, GTK_ALIGN_CENTER);
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), padding);
+  g_signal_connect (spin, "notify::value", G_CALLBACK (update_padding), picture);
+
+  gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Padding"), left, top + 1, 1, 1);
+  gtk_grid_attach (GTK_GRID (grid), spin, left + 1, top + 1, 1, 1);
+
+  label = gtk_label_new ("");
+  gtk_label_set_xalign (GTK_LABEL (label), 0);
+  g_object_set_data (G_OBJECT (picture), "size_label", label);
+  gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Size"), left, top + 2, 1, 1);
+  gtk_grid_attach (GTK_GRID (grid), label, left + 1, top + 2, 1, 1);
+  label = gtk_label_new ("");
+  gtk_label_set_xalign (GTK_LABEL (label), 0);
+  g_object_set_data (G_OBJECT (picture), "stride_label", label);
+  gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Stride"), left, top + 3, 1, 1);
+  gtk_grid_attach (GTK_GRID (grid), label, left + 1, top + 3, 1, 1);
 
-  add_to_grid (grid, 8, 10,
-               4, TRUE,
-               gdk_texture_get_width (texture),
-               gdk_texture_get_height (texture),
-               cairo_image_surface_get_stride (surface),
-               gtk_picture_new_for_paintable (GDK_PAINTABLE (texture)));
+  update_picture (picture);
+}
 
-  g_object_unref (source);
-  g_object_unref (pb);
-  cairo_surface_destroy (surface);
+int
+main (int argc, char *argv[])
+{
+  GtkWidget *window, *grid;
+
+  gtk_init ();
+
+  window = gtk_window_new ();
+  grid = gtk_grid_new ();
+  gtk_widget_set_margin_top (grid, 10);
+  gtk_widget_set_margin_bottom (grid, 10);
+  gtk_widget_set_margin_start (grid, 10);
+  gtk_widget_set_margin_end (grid, 10);
+  gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
+  gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
+  gtk_window_set_child (GTK_WINDOW (window), grid);
+
+  add_to_grid (grid, 0, 0, GDK_MEMORY_R8G8B8, 0);
 
   gtk_window_present (GTK_WINDOW (window));
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]