Move demos around

The pixbuf-demo gets its own subdirectory, the other small
tests move from demos/ to tests/.
This commit is contained in:
Matthias Clasen
2011-05-26 00:32:31 -04:00
parent 6499d89a6e
commit cf86c7c9bb
17 changed files with 64 additions and 56 deletions

View File

@ -89,7 +89,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \
testtreecolumns \
testtreecolumnsizing \
testtreesort \
testverticalcells \
testverticalcells \
treestoretest \
testxinerama \
testwindows \
@ -110,7 +110,11 @@ noinst_PROGRAMS = $(TEST_PROGS) \
testnoscreen \
testtreepos \
testsensitive \
testtextview
testtextview \
testanimation \
testpixbuf-save \
testpixbuf-color \
testpixbuf-scale
if USE_X11
noinst_PROGRAMS += testerrors
@ -211,6 +215,10 @@ testnoscreen_DEPENDENCIES = $(TEST_DEPS)
testtreepos_DEPENDENCIES = $(TEST_DEPS)
testsensitive_DEPENDENCIES = $(TEST_DEPS)
testtextview_DEPENDENCIES = $(TEST_DEPS)
testanimation_DEPENDENCIES = $(TEST_DEPS)
testpixbuf_save_DEPENDENCIES = $(TEST_DEPS)
testpixbuf_color_DEPENDENCIES = $(TEST_DEPS)
testpixbuf_scale_DEPENDENCIES = $(TEST_DEPS)
flicker_LDADD = $(LDADDS)
simple_LDADD = $(LDADDS)
@ -297,6 +305,10 @@ testnoscreen_LDADD = $(LDADDS)
testtreepos_LDADD = $(LDADDS)
testsensitive_LDADD = $(LDADDS)
testtextview_LDADD = $(LDADDS)
testanimation_LDADD = $(LDADDS)
testpixbuf_save_LDADD = $(LDADDS)
testpixbuf_color_LDADD = $(LDADDS)
testpixbuf_scale_LDADD = $(LDADDS)
testentrycompletion_SOURCES = \
@ -444,6 +456,14 @@ testtoplevelembed_SOURCES = testtoplevelembed.c
testtextview_SOURCES = testtextview.c
testanimation_SOURCES = testanimation.c
testpixbuf_scale_SOURCES = testpixbuf-scale.c
testpixbuf_color_SOURCES = testpixbuf-color.c
testpixbuf_save_SOURCES = testpixbuf-save.c
EXTRA_DIST += \
gradient1.png \

444
tests/testanimation.c Normal file
View File

@ -0,0 +1,444 @@
/* testpixbuf -- test program for gdk-pixbuf code
* Copyright (C) 1999 Mark Crichton, Larry Ewing
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <gtk/gtk.h>
typedef struct _LoadContext LoadContext;
struct _LoadContext
{
gchar *filename;
GtkWidget *window;
GdkPixbufLoader *pixbuf_loader;
guint load_timeout;
FILE* image_stream;
};
static void
destroy_context (gpointer data)
{
LoadContext *lc = data;
g_free (lc->filename);
if (lc->load_timeout)
g_source_remove (lc->load_timeout);
if (lc->image_stream)
fclose (lc->image_stream);
if (lc->pixbuf_loader)
{
gdk_pixbuf_loader_close (lc->pixbuf_loader, NULL);
g_object_unref (lc->pixbuf_loader);
}
g_free (lc);
}
static LoadContext*
get_load_context (GtkWidget *image)
{
LoadContext *lc;
lc = g_object_get_data (G_OBJECT (image), "lc");
if (lc == NULL)
{
lc = g_new0 (LoadContext, 1);
g_object_set_data_full (G_OBJECT (image),
"lc",
lc,
destroy_context);
}
return lc;
}
static void
progressive_prepared_callback (GdkPixbufLoader* loader,
gpointer data)
{
GdkPixbuf* pixbuf;
GtkWidget* image;
image = GTK_WIDGET (data);
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
/* Avoid displaying random memory contents, since the pixbuf
* isn't filled in yet.
*/
gdk_pixbuf_fill (pixbuf, 0xaaaaaaff);
/* Could set the pixbuf instead, if we only wanted to display
* static images.
*/
gtk_image_set_from_animation (GTK_IMAGE (image),
gdk_pixbuf_loader_get_animation (loader));
}
static void
progressive_updated_callback (GdkPixbufLoader* loader,
gint x, gint y, gint width, gint height,
gpointer data)
{
GtkWidget* image;
image = GTK_WIDGET (data);
/* We know the pixbuf inside the GtkImage has changed, but the image
* itself doesn't know this; so queue a redraw. If we wanted to be
* really efficient, we could use a drawing area or something
* instead of a GtkImage, so we could control the exact position of
* the pixbuf on the display, then we could queue a draw for only
* the updated area of the image.
*/
/* We only really need to redraw if the image's animation iterator
* is gdk_pixbuf_animation_iter_on_currently_loading_frame(), but
* who cares.
*/
gtk_widget_queue_draw (image);
}
static gint
progressive_timeout (gpointer data)
{
GtkWidget *image;
LoadContext *lc;
image = GTK_WIDGET (data);
lc = get_load_context (image);
/* This shows off fully-paranoid error handling, so looks scary.
* You could factor out the error handling code into a nice separate
* function to make things nicer.
*/
if (lc->image_stream)
{
size_t bytes_read;
guchar buf[256];
GError *error = NULL;
bytes_read = fread (buf, 1, 256, lc->image_stream);
if (ferror (lc->image_stream))
{
GtkWidget *dialog;
dialog = gtk_message_dialog_new (GTK_WINDOW (lc->window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Failure reading image file 'alphatest.png': %s",
g_strerror (errno));
g_signal_connect (dialog, "response",
G_CALLBACK (gtk_widget_destroy), NULL);
fclose (lc->image_stream);
lc->image_stream = NULL;
gtk_widget_show (dialog);
lc->load_timeout = 0;
return FALSE; /* uninstall the timeout */
}
if (!gdk_pixbuf_loader_write (lc->pixbuf_loader,
buf, bytes_read,
&error))
{
GtkWidget *dialog;
dialog = gtk_message_dialog_new (GTK_WINDOW (lc->window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Failed to load image: %s",
error->message);
g_error_free (error);
g_signal_connect (dialog, "response",
G_CALLBACK (gtk_widget_destroy), NULL);
fclose (lc->image_stream);
lc->image_stream = NULL;
gtk_widget_show (dialog);
lc->load_timeout = 0;
return FALSE; /* uninstall the timeout */
}
if (feof (lc->image_stream))
{
fclose (lc->image_stream);
lc->image_stream = NULL;
/* Errors can happen on close, e.g. if the image
* file was truncated we'll know on close that
* it was incomplete.
*/
error = NULL;
if (!gdk_pixbuf_loader_close (lc->pixbuf_loader,
&error))
{
GtkWidget *dialog;
dialog = gtk_message_dialog_new (GTK_WINDOW (lc->window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Failed to load image: %s",
error->message);
g_error_free (error);
g_signal_connect (dialog, "response",
G_CALLBACK (gtk_widget_destroy), NULL);
gtk_widget_show (dialog);
g_object_unref (lc->pixbuf_loader);
lc->pixbuf_loader = NULL;
lc->load_timeout = 0;
return FALSE; /* uninstall the timeout */
}
g_object_unref (lc->pixbuf_loader);
lc->pixbuf_loader = NULL;
}
}
else
{
lc->image_stream = fopen (lc->filename, "r");
if (lc->image_stream == NULL)
{
GtkWidget *dialog;
dialog = gtk_message_dialog_new (GTK_WINDOW (lc->window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Unable to open image file '%s': %s",
lc->filename,
g_strerror (errno));
g_signal_connect (dialog, "response",
G_CALLBACK (gtk_widget_destroy), NULL);
gtk_widget_show (dialog);
lc->load_timeout = 0;
return FALSE; /* uninstall the timeout */
}
if (lc->pixbuf_loader)
{
gdk_pixbuf_loader_close (lc->pixbuf_loader, NULL);
g_object_unref (lc->pixbuf_loader);
lc->pixbuf_loader = NULL;
}
lc->pixbuf_loader = gdk_pixbuf_loader_new ();
g_signal_connect (lc->pixbuf_loader, "area_prepared",
G_CALLBACK (progressive_prepared_callback), image);
g_signal_connect (lc->pixbuf_loader, "area_updated",
G_CALLBACK (progressive_updated_callback), image);
}
/* leave timeout installed */
return TRUE;
}
static void
start_progressive_loading (GtkWidget *image)
{
LoadContext *lc;
lc = get_load_context (image);
/* This is obviously totally contrived (we slow down loading
* on purpose to show how incremental loading works).
* The real purpose of incremental loading is the case where
* you are reading data from a slow source such as the network.
* The timeout simply simulates a slow data source by inserting
* pauses in the reading process.
*/
lc->load_timeout = gdk_threads_add_timeout (100,
progressive_timeout,
image);
}
static GtkWidget *
do_image (const char *filename)
{
GtkWidget *frame;
GtkWidget *vbox;
GtkWidget *image;
GtkWidget *label;
GtkWidget *align;
GtkWidget *window;
gchar *str, *escaped;
LoadContext *lc;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Image Loading");
gtk_container_set_border_width (GTK_CONTAINER (window), 8);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
gtk_container_add (GTK_CONTAINER (window), vbox);
label = gtk_label_new (NULL);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
escaped = g_markup_escape_text (filename, -1);
str = g_strdup_printf ("Progressively loading: <b>%s</b>", escaped);
gtk_label_set_markup (GTK_LABEL (label),
str);
g_free (escaped);
g_free (str);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
/* The alignment keeps the frame from growing when users resize
* the window
*/
align = gtk_alignment_new (0.5, 0.5, 0, 0);
gtk_container_add (GTK_CONTAINER (align), frame);
gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
image = gtk_image_new_from_pixbuf (NULL);
gtk_container_add (GTK_CONTAINER (frame), image);
lc = get_load_context (image);
lc->window = window;
lc->filename = g_strdup (filename);
start_progressive_loading (image);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (window, "delete_event",
G_CALLBACK (gtk_main_quit), NULL);
gtk_widget_show_all (window);
return window;
}
static void
do_nonprogressive (const gchar *filename)
{
GtkWidget *frame;
GtkWidget *vbox;
GtkWidget *image;
GtkWidget *label;
GtkWidget *align;
GtkWidget *window;
gchar *str, *escaped;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Animation");
gtk_container_set_border_width (GTK_CONTAINER (window), 8);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
gtk_container_add (GTK_CONTAINER (window), vbox);
label = gtk_label_new (NULL);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
escaped = g_markup_escape_text (filename, -1);
str = g_strdup_printf ("Loaded from file: <b>%s</b>", escaped);
gtk_label_set_markup (GTK_LABEL (label),
str);
g_free (escaped);
g_free (str);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
/* The alignment keeps the frame from growing when users resize
* the window
*/
align = gtk_alignment_new (0.5, 0.5, 0, 0);
gtk_container_add (GTK_CONTAINER (align), frame);
gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
image = gtk_image_new_from_file (filename);
gtk_container_add (GTK_CONTAINER (frame), image);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (window, "delete_event",
G_CALLBACK (gtk_main_quit), NULL);
gtk_widget_show_all (window);
}
int
main (int argc,
char **argv)
{
gint i;
gtk_init (&argc, &argv);
i = 1;
while (i < argc)
{
do_image (argv[i]);
do_nonprogressive (argv[i]);
++i;
}
gtk_main ();
return 0;
}

159
tests/testpixbuf-color.c Normal file
View File

@ -0,0 +1,159 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>
#define ICC_PROFILE "/usr/share/color/icc/bluish.icc"
#define ICC_PROFILE_SIZE 3966
static gboolean
save_image_png (const gchar *filename, GdkPixbuf *pixbuf, GError **error)
{
gchar *contents = NULL;
gchar *contents_encode = NULL;
gsize length;
gboolean ret;
gint len;
/* get icc file */
ret = g_file_get_contents (ICC_PROFILE, &contents, &length, error);
if (!ret)
goto out;
contents_encode = g_base64_encode ((const guchar *) contents, length);
ret = gdk_pixbuf_save (pixbuf, filename, "png", error,
"tEXt::Software", "Hello my name is dave",
"icc-profile", contents_encode,
NULL);
len = strlen (contents_encode);
g_debug ("ICC profile was %i bytes", len);
out:
g_free (contents);
g_free (contents_encode);
return ret;
}
static gboolean
save_image_tiff (const gchar *filename, GdkPixbuf *pixbuf, GError **error)
{
gchar *contents = NULL;
gchar *contents_encode = NULL;
gsize length;
gboolean ret;
gint len;
/* get icc file */
ret = g_file_get_contents (ICC_PROFILE, &contents, &length, error);
if (!ret)
goto out;
contents_encode = g_base64_encode ((const guchar *) contents, length);
ret = gdk_pixbuf_save (pixbuf, filename, "tiff", error,
"icc-profile", contents_encode,
NULL);
len = strlen (contents_encode);
g_debug ("ICC profile was %i bytes", len);
out:
g_free (contents);
g_free (contents_encode);
return ret;
}
static gboolean
save_image_verify (const gchar *filename, GError **error)
{
gboolean ret = FALSE;
GdkPixbuf *pixbuf = NULL;
const gchar *option;
gchar *icc_profile = NULL;
gsize len = 0;
/* load */
pixbuf = gdk_pixbuf_new_from_file (filename, error);
if (pixbuf == NULL)
goto out;
/* check values */
option = gdk_pixbuf_get_option (pixbuf, "icc-profile");
if (option == NULL) {
*error = g_error_new (1, 0, "no profile set");
goto out;
}
/* decode base64 */
icc_profile = (gchar *) g_base64_decode (option, &len);
if (len != ICC_PROFILE_SIZE) {
*error = g_error_new (1, 0,
"profile length invalid, got %" G_GSIZE_FORMAT,
len);
g_file_set_contents ("error.icc", icc_profile, len, NULL);
goto out;
}
/* success */
ret = TRUE;
out:
if (pixbuf != NULL)
g_object_unref (pixbuf);
g_free (icc_profile);
return ret;
}
int
main (int argc, char **argv)
{
GdkWindow *root;
GdkPixbuf *pixbuf;
gboolean ret;
gint retval = 1;
GError *error = NULL;
gtk_init (&argc, &argv);
root = gdk_get_default_root_window ();
pixbuf = gdk_pixbuf_get_from_window (root,
0, 0, 150, 160);
/* PASS */
g_debug ("try to save PNG with a profile");
ret = save_image_png ("icc-profile.png", pixbuf, &error);
if (!ret) {
g_warning ("FAILED: did not save image: %s", error->message);
g_error_free (error);
goto out;
}
/* PASS */
g_debug ("try to save TIFF with a profile");
ret = save_image_tiff ("icc-profile.tiff", pixbuf, &error);
if (!ret) {
g_warning ("FAILED: did not save image: %s", error->message);
g_error_free (error);
goto out;
}
/* PASS */
g_debug ("try to load PNG and get color attributes");
ret = save_image_verify ("icc-profile.png", &error);
if (!ret) {
g_warning ("FAILED: did not load image: %s", error->message);
g_error_free (error);
goto out;
}
/* PASS */
g_debug ("try to load TIFF and get color attributes");
ret = save_image_verify ("icc-profile.tiff", &error);
if (!ret) {
g_warning ("FAILED: did not load image: %s", error->message);
g_error_free (error);
goto out;
}
/* success */
retval = 0;
g_debug ("ALL OKAY!");
out:
return retval;
}

389
tests/testpixbuf-save.c Normal file
View File

@ -0,0 +1,389 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
#include "config.h"
#include <stdio.h>
#include <gtk/gtk.h>
static void
compare_pixbufs (GdkPixbuf *pixbuf, GdkPixbuf *compare, const gchar *file_type)
{
if ((gdk_pixbuf_get_width (pixbuf) !=
gdk_pixbuf_get_width (compare)) ||
(gdk_pixbuf_get_height (pixbuf) !=
gdk_pixbuf_get_height (compare)) ||
(gdk_pixbuf_get_n_channels (pixbuf) !=
gdk_pixbuf_get_n_channels (compare)) ||
(gdk_pixbuf_get_has_alpha (pixbuf) !=
gdk_pixbuf_get_has_alpha (compare)) ||
(gdk_pixbuf_get_bits_per_sample (pixbuf) !=
gdk_pixbuf_get_bits_per_sample (compare))) {
fprintf (stderr,
"saved %s file differs from copy in memory\n",
file_type);
} else {
guchar *orig_pixels;
guchar *compare_pixels;
gint orig_rowstride;
gint compare_rowstride;
gint width;
gint height;
gint bytes_per_pixel;
gint x, y;
guchar *p1, *p2;
gint count = 0;
orig_pixels = gdk_pixbuf_get_pixels (pixbuf);
compare_pixels = gdk_pixbuf_get_pixels (compare);
orig_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
compare_rowstride = gdk_pixbuf_get_rowstride (compare);
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
/* well... */
bytes_per_pixel = gdk_pixbuf_get_n_channels (pixbuf);
p1 = orig_pixels;
p2 = compare_pixels;
for (y = 0; y < height; y++) {
for (x = 0; x < width * bytes_per_pixel; x++)
count += (*p1++ != *p2++);
orig_pixels += orig_rowstride;
compare_pixels += compare_rowstride;
p1 = orig_pixels;
p2 = compare_pixels;
}
if (count > 0) {
fprintf (stderr,
"saved %s file differs from copy in memory\n",
file_type);
}
}
}
static gboolean
save_to_loader (const gchar *buf, gsize count, GError **err, gpointer data)
{
GdkPixbufLoader *loader = data;
return gdk_pixbuf_loader_write (loader, (const guchar *)buf, count, err);
}
static GdkPixbuf *
buffer_to_pixbuf (const gchar *buf, gsize count, GError **err)
{
GdkPixbufLoader *loader;
GdkPixbuf *pixbuf;
loader = gdk_pixbuf_loader_new ();
if (gdk_pixbuf_loader_write (loader, (const guchar *)buf, count, err) &&
gdk_pixbuf_loader_close (loader, err)) {
pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader));
g_object_unref (loader);
return pixbuf;
} else {
return NULL;
}
}
static void
do_compare (GdkPixbuf *pixbuf, GdkPixbuf *compare, GError *err)
{
if (compare == NULL) {
fprintf (stderr, "%s", err->message);
g_error_free (err);
} else {
compare_pixbufs (pixbuf, compare, "jpeg");
g_object_unref (compare);
}
}
static void
keypress_check (GtkWidget *widget, GdkEventKey *evt, gpointer data)
{
GdkPixbuf *pixbuf;
GtkDrawingArea *da = (GtkDrawingArea*)data;
GError *err = NULL;
gchar *buffer;
gsize count;
GdkPixbufLoader *loader;
pixbuf = (GdkPixbuf *) g_object_get_data (G_OBJECT (da), "pixbuf");
if (evt->keyval == 'q')
gtk_main_quit ();
if (evt->keyval == 's' && (evt->state & GDK_CONTROL_MASK)) {
/* save to callback */
if (pixbuf == NULL) {
fprintf (stderr, "PIXBUF NULL\n");
return;
}
loader = gdk_pixbuf_loader_new ();
if (!gdk_pixbuf_save_to_callback (pixbuf, save_to_loader, loader, "jpeg",
&err,
"quality", "100",
NULL) ||
!gdk_pixbuf_loader_close (loader, &err)) {
fprintf (stderr, "%s", err->message);
g_error_free (err);
} else {
do_compare (pixbuf,
g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)),
err);
g_object_unref (loader);
}
}
else if (evt->keyval == 'S') {
/* save to buffer */
if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &count, "jpeg",
&err,
"quality", "100",
NULL)) {
fprintf (stderr, "%s", err->message);
g_error_free (err);
} else {
do_compare (pixbuf,
buffer_to_pixbuf (buffer, count, &err),
err);
}
}
else if (evt->keyval == 's') {
/* save normally */
if (pixbuf == NULL) {
fprintf (stderr, "PIXBUF NULL\n");
return;
}
if (!gdk_pixbuf_save (pixbuf, "foo.jpg", "jpeg",
&err,
"quality", "100",
NULL)) {
fprintf (stderr, "%s", err->message);
g_error_free (err);
} else {
do_compare (pixbuf,
gdk_pixbuf_new_from_file ("foo.jpg", &err),
err);
}
}
if (evt->keyval == 'p' && (evt->state & GDK_CONTROL_MASK)) {
/* save to callback */
if (pixbuf == NULL) {
fprintf (stderr, "PIXBUF NULL\n");
return;
}
loader = gdk_pixbuf_loader_new ();
if (!gdk_pixbuf_save_to_callback (pixbuf, save_to_loader, loader, "png",
&err,
"tEXt::Software", "testpixbuf-save",
NULL)
|| !gdk_pixbuf_loader_close (loader, &err)) {
fprintf (stderr, "%s", err->message);
g_error_free (err);
} else {
do_compare (pixbuf,
g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)),
err);
g_object_unref (loader);
}
}
else if (evt->keyval == 'P') {
/* save to buffer */
if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &count, "png",
&err,
"tEXt::Software", "testpixbuf-save",
NULL)) {
fprintf (stderr, "%s", err->message);
g_error_free (err);
} else {
do_compare (pixbuf,
buffer_to_pixbuf (buffer, count, &err),
err);
}
}
else if (evt->keyval == 'p') {
if (pixbuf == NULL) {
fprintf (stderr, "PIXBUF NULL\n");
return;
}
if (!gdk_pixbuf_save (pixbuf, "foo.png", "png",
&err,
"tEXt::Software", "testpixbuf-save",
NULL)) {
fprintf (stderr, "%s", err->message);
g_error_free (err);
} else {
do_compare(pixbuf,
gdk_pixbuf_new_from_file ("foo.png", &err),
err);
}
}
if (evt->keyval == 'i' && (evt->state & GDK_CONTROL_MASK)) {
/* save to callback */
if (pixbuf == NULL) {
fprintf (stderr, "PIXBUF NULL\n");
return;
}
loader = gdk_pixbuf_loader_new ();
if (!gdk_pixbuf_save_to_callback (pixbuf, save_to_loader, loader, "ico",
&err,
NULL)
|| !gdk_pixbuf_loader_close (loader, &err)) {
fprintf (stderr, "%s", err->message);
g_error_free (err);
} else {
do_compare (pixbuf,
g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)),
err);
g_object_unref (loader);
}
}
else if (evt->keyval == 'I') {
/* save to buffer */
if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &count, "ico",
&err,
NULL)) {
fprintf (stderr, "%s", err->message);
g_error_free (err);
} else {
do_compare (pixbuf,
buffer_to_pixbuf (buffer, count, &err),
err);
}
}
else if (evt->keyval == 'i') {
if (pixbuf == NULL) {
fprintf (stderr, "PIXBUF NULL\n");
return;
}
if (!gdk_pixbuf_save (pixbuf, "foo.ico", "ico",
&err,
NULL)) {
fprintf (stderr, "%s", err->message);
g_error_free (err);
} else {
do_compare(pixbuf,
gdk_pixbuf_new_from_file ("foo.ico", &err),
err);
}
}
if (evt->keyval == 'a') {
if (pixbuf == NULL) {
fprintf (stderr, "PIXBUF NULL\n");
return;
} else {
GdkPixbuf *alpha_buf;
alpha_buf = gdk_pixbuf_add_alpha (pixbuf,
FALSE, 0, 0, 0);
g_object_set_data_full (G_OBJECT (da),
"pixbuf", alpha_buf,
(GDestroyNotify) g_object_unref);
}
}
}
static int
close_app (GtkWidget *widget, gpointer data)
{
gtk_main_quit ();
return TRUE;
}
static gboolean
draw_cb (GtkWidget *drawing_area, cairo_t *cr, gpointer data)
{
GdkPixbuf *pixbuf;
pixbuf = (GdkPixbuf *) g_object_get_data (G_OBJECT (drawing_area),
"pixbuf");
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
cairo_paint (cr);
return FALSE;
}
static int
configure_cb (GtkWidget *drawing_area, GdkEventConfigure *evt, gpointer data)
{
GdkPixbuf *pixbuf;
pixbuf = (GdkPixbuf *) g_object_get_data (G_OBJECT (drawing_area),
"pixbuf");
g_print ("X:%d Y:%d\n", evt->width, evt->height);
if (evt->width != gdk_pixbuf_get_width (pixbuf) || evt->height != gdk_pixbuf_get_height (pixbuf)) {
GdkWindow *root;
GdkPixbuf *new_pixbuf;
root = gdk_get_default_root_window ();
new_pixbuf = gdk_pixbuf_get_from_window (root,
0, 0, evt->width, evt->height);
g_object_set_data_full (G_OBJECT (drawing_area), "pixbuf", new_pixbuf,
(GDestroyNotify) g_object_unref);
}
return FALSE;
}
int
main (int argc, char **argv)
{
GdkWindow *root;
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *drawing_area;
GdkPixbuf *pixbuf;
gtk_init (&argc, &argv);
root = gdk_get_default_root_window ();
pixbuf = gdk_pixbuf_get_from_window (root,
0, 0, 150, 160);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (window, "delete_event",
G_CALLBACK (close_app), NULL);
g_signal_connect (window, "destroy",
G_CALLBACK (close_app), NULL);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
drawing_area = gtk_drawing_area_new ();
gtk_widget_set_size_request (GTK_WIDGET (drawing_area),
gdk_pixbuf_get_width (pixbuf),
gdk_pixbuf_get_height (pixbuf));
g_signal_connect (drawing_area, "draw",
G_CALLBACK (draw_cb), NULL);
g_signal_connect (drawing_area, "configure_event",
G_CALLBACK (configure_cb), NULL);
g_signal_connect (window, "key_press_event",
G_CALLBACK (keypress_check), drawing_area);
g_object_set_data_full (G_OBJECT (drawing_area), "pixbuf", pixbuf,
(GDestroyNotify) g_object_unref);
gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}

152
tests/testpixbuf-scale.c Normal file
View File

@ -0,0 +1,152 @@
#include "config.h"
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
GdkInterpType interp_type = GDK_INTERP_BILINEAR;
int overall_alpha = 255;
GdkPixbuf *pixbuf;
GtkWidget *darea;
void
set_interp_type (GtkWidget *widget, gpointer data)
{
guint types[] = { GDK_INTERP_NEAREST,
GDK_INTERP_BILINEAR,
GDK_INTERP_TILES,
GDK_INTERP_HYPER };
interp_type = types[gtk_combo_box_get_active (GTK_COMBO_BOX (widget))];
gtk_widget_queue_draw (darea);
}
void
overall_changed_cb (GtkAdjustment *adjustment, gpointer data)
{
if (gtk_adjustment_get_value (adjustment) != overall_alpha)
{
overall_alpha = gtk_adjustment_get_value (adjustment);
gtk_widget_queue_draw (darea);
}
}
gboolean
draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data)
{
GdkPixbuf *dest;
int width, height;
width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget);
dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
gdk_pixbuf_composite_color (pixbuf, dest,
0, 0, width, height,
0, 0,
(double) width / gdk_pixbuf_get_width (pixbuf),
(double) height / gdk_pixbuf_get_height (pixbuf),
interp_type, overall_alpha,
0, 0, 16, 0xaaaaaa, 0x555555);
gdk_cairo_set_source_pixbuf (cr, dest, 0, 0);
cairo_paint (cr);
g_object_unref (dest);
return TRUE;
}
int
main(int argc, char **argv)
{
GtkWidget *window, *vbox;
GtkWidget *combo_box;
GtkWidget *alignment;
GtkWidget *hbox, *label, *hscale;
GtkAdjustment *adjustment;
GtkRequisition scratch_requisition;
const gchar *creator;
GError *error;
gtk_init (&argc, &argv);
if (argc != 2) {
fprintf (stderr, "Usage: testpixbuf-scale FILE\n");
exit (1);
}
error = NULL;
pixbuf = gdk_pixbuf_new_from_file (argv[1], &error);
if (!pixbuf) {
fprintf (stderr, "Cannot load image: %s\n",
error->message);
g_error_free (error);
exit(1);
}
creator = gdk_pixbuf_get_option (pixbuf, "tEXt::Software");
if (creator)
g_print ("%s was created by '%s'\n", argv[1], creator);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_main_quit), NULL);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
combo_box = gtk_combo_box_text_new ();
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), "NEAREST");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), "BILINEAR");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), "TILES");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), "HYPER");
gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 1);
g_signal_connect (combo_box, "changed",
G_CALLBACK (set_interp_type),
NULL);
alignment = gtk_alignment_new (0.0, 0.0, 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new ("Overall Alpha:");
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
adjustment = gtk_adjustment_new (overall_alpha, 0, 255, 1, 10, 0);
g_signal_connect (adjustment, "value_changed",
G_CALLBACK (overall_changed_cb), NULL);
hscale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
gtk_scale_set_digits (GTK_SCALE (hscale), 0);
gtk_box_pack_start (GTK_BOX (hbox), hscale, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (alignment), combo_box);
gtk_widget_show_all (vbox);
/* Compute the size without the drawing area, so we know how big to make the default size */
gtk_widget_get_preferred_size ( (vbox),
&scratch_requisition, NULL);
darea = gtk_drawing_area_new ();
gtk_box_pack_start (GTK_BOX (vbox), darea, TRUE, TRUE, 0);
g_signal_connect (darea, "draw",
G_CALLBACK (draw_cb), NULL);
gtk_window_set_default_size (GTK_WINDOW (window),
gdk_pixbuf_get_width (pixbuf),
scratch_requisition.height + gdk_pixbuf_get_height (pixbuf));
gtk_widget_show_all (window);
gtk_main ();
return 0;
}