forked from AuroraMiddleware/gtk
fix some shell typos
2001-05-04 Havoc Pennington <hp@redhat.com> * configure.in: fix some shell typos * gtk/gtkcolorsel.c (gtk_color_selection_destroy): warning fix * gtk/gtkimage.c: handle animations * gtk/gtkcheckbutton.c (gtk_check_button_size_request): request border_width * 2, not just border_width * gtk/gtkscale.c: add "format_value" signal to allow people to override the way values are drawn. (gtk_scale_get_value_size): fix width/height mistake, and compute size from actual displayed text, not from made-up text. * gtk/gtktexttag.c (gtk_text_tag_class_init): fix return type in signal registration * tests/testtext.c: Add "Remove all tags" menu item for testing * gtk/gtktextbuffer.c (gtk_text_buffer_remove_all_tags): implement * demos/gtk-demo/main.c (main): add hack so we can find modules without installing gtk * demos/gtk-demo/textview.c (insert_text): demo font scaling * gtk/gtkcellrenderertext.c: Add "scale" property (font scaling factor) (gtk_cell_renderer_text_set_property): remove some bogus g_object_notify * gtk/gtktexttag.c: add "scale" property which is a font scaling factor * gtk/gtktextlayout.c (add_text_attrs): add font scale attribute to layout * gtk/gtktextiter.c (gtk_text_iter_is_start): rename from gtk_text_iter_is_first 2001-05-04 Havoc Pennington <hp@redhat.com> * pixops/pixops.c (pixops_process): merge fix from stable: Patch from hoshem@mel.comcen.com.au to fix nonzero X offsets. Fixes bug #50371. * gdk-pixbuf/pixops/pixops.c (pixops_composite_nearest): merge from stable: Patch from OKADA Mitsuru <m-okada@fjb.co.jp> to fix confusion of using "src" instead of "p". (pixops_composite_color_nearest): Use a more accurate (and correct, to begin with) compositing method. This cures checks showing through on images with no alpha. * gdk-pixbuf.c (gdk_pixbuf_fill): fix bug that left some trailing bytes unfilled. * gdk-pixbuf-io.h: fix UpdatedNotifyFunc to use signed ints * gdk-pixbuf-loader.h (struct _GdkPixbufLoaderClass): Change area_updated signal to use signed ints. Removed animation-related signals. * io-gif.c, io-gif-animation.h, io-gif-animation.c: Massive rewrite action * gdk-pixbuf-animation.c: Add GdkPixbufAnimationIter to abstract all the pesky details. Remove old frame-based API. Make GdkPixbufAnimation an abstract base class, derived by the loaders.
This commit is contained in:
parent
607ac1e1b3
commit
b4e4a0ed9d
43
ChangeLog
43
ChangeLog
@ -1,3 +1,46 @@
|
|||||||
|
2001-05-04 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* configure.in: fix some shell typos
|
||||||
|
|
||||||
|
* gtk/gtkcolorsel.c (gtk_color_selection_destroy): warning fix
|
||||||
|
|
||||||
|
* gtk/gtkimage.c: handle animations
|
||||||
|
|
||||||
|
* gtk/gtkcheckbutton.c (gtk_check_button_size_request): request
|
||||||
|
border_width * 2, not just border_width
|
||||||
|
|
||||||
|
* gtk/gtkscale.c: add "format_value" signal to allow people
|
||||||
|
to override the way values are drawn.
|
||||||
|
(gtk_scale_get_value_size): fix width/height mistake,
|
||||||
|
and compute size from actual displayed text, not
|
||||||
|
from made-up text.
|
||||||
|
|
||||||
|
* gtk/gtktexttag.c (gtk_text_tag_class_init): fix return type in
|
||||||
|
signal registration
|
||||||
|
|
||||||
|
* tests/testtext.c: Add "Remove all tags" menu item for testing
|
||||||
|
|
||||||
|
* gtk/gtktextbuffer.c (gtk_text_buffer_remove_all_tags): implement
|
||||||
|
|
||||||
|
* demos/gtk-demo/main.c (main): add hack so we can find modules
|
||||||
|
without installing gtk
|
||||||
|
|
||||||
|
* demos/gtk-demo/textview.c (insert_text): demo font scaling
|
||||||
|
|
||||||
|
* gtk/gtkcellrenderertext.c: Add "scale" property (font scaling
|
||||||
|
factor)
|
||||||
|
(gtk_cell_renderer_text_set_property): remove some bogus
|
||||||
|
g_object_notify
|
||||||
|
|
||||||
|
* gtk/gtktexttag.c: add "scale" property which is a font scaling
|
||||||
|
factor
|
||||||
|
|
||||||
|
* gtk/gtktextlayout.c (add_text_attrs): add font scale attribute
|
||||||
|
to layout
|
||||||
|
|
||||||
|
* gtk/gtktextiter.c (gtk_text_iter_is_start): rename from
|
||||||
|
gtk_text_iter_is_first
|
||||||
|
|
||||||
2001-01-06 Hans Breuer <hans@breuer.org>
|
2001-01-06 Hans Breuer <hans@breuer.org>
|
||||||
|
|
||||||
* gdk/gdk.def : updated exports
|
* gdk/gdk.def : updated exports
|
||||||
|
@ -1,3 +1,46 @@
|
|||||||
|
2001-05-04 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* configure.in: fix some shell typos
|
||||||
|
|
||||||
|
* gtk/gtkcolorsel.c (gtk_color_selection_destroy): warning fix
|
||||||
|
|
||||||
|
* gtk/gtkimage.c: handle animations
|
||||||
|
|
||||||
|
* gtk/gtkcheckbutton.c (gtk_check_button_size_request): request
|
||||||
|
border_width * 2, not just border_width
|
||||||
|
|
||||||
|
* gtk/gtkscale.c: add "format_value" signal to allow people
|
||||||
|
to override the way values are drawn.
|
||||||
|
(gtk_scale_get_value_size): fix width/height mistake,
|
||||||
|
and compute size from actual displayed text, not
|
||||||
|
from made-up text.
|
||||||
|
|
||||||
|
* gtk/gtktexttag.c (gtk_text_tag_class_init): fix return type in
|
||||||
|
signal registration
|
||||||
|
|
||||||
|
* tests/testtext.c: Add "Remove all tags" menu item for testing
|
||||||
|
|
||||||
|
* gtk/gtktextbuffer.c (gtk_text_buffer_remove_all_tags): implement
|
||||||
|
|
||||||
|
* demos/gtk-demo/main.c (main): add hack so we can find modules
|
||||||
|
without installing gtk
|
||||||
|
|
||||||
|
* demos/gtk-demo/textview.c (insert_text): demo font scaling
|
||||||
|
|
||||||
|
* gtk/gtkcellrenderertext.c: Add "scale" property (font scaling
|
||||||
|
factor)
|
||||||
|
(gtk_cell_renderer_text_set_property): remove some bogus
|
||||||
|
g_object_notify
|
||||||
|
|
||||||
|
* gtk/gtktexttag.c: add "scale" property which is a font scaling
|
||||||
|
factor
|
||||||
|
|
||||||
|
* gtk/gtktextlayout.c (add_text_attrs): add font scale attribute
|
||||||
|
to layout
|
||||||
|
|
||||||
|
* gtk/gtktextiter.c (gtk_text_iter_is_start): rename from
|
||||||
|
gtk_text_iter_is_first
|
||||||
|
|
||||||
2001-01-06 Hans Breuer <hans@breuer.org>
|
2001-01-06 Hans Breuer <hans@breuer.org>
|
||||||
|
|
||||||
* gdk/gdk.def : updated exports
|
* gdk/gdk.def : updated exports
|
||||||
|
@ -1,3 +1,46 @@
|
|||||||
|
2001-05-04 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* configure.in: fix some shell typos
|
||||||
|
|
||||||
|
* gtk/gtkcolorsel.c (gtk_color_selection_destroy): warning fix
|
||||||
|
|
||||||
|
* gtk/gtkimage.c: handle animations
|
||||||
|
|
||||||
|
* gtk/gtkcheckbutton.c (gtk_check_button_size_request): request
|
||||||
|
border_width * 2, not just border_width
|
||||||
|
|
||||||
|
* gtk/gtkscale.c: add "format_value" signal to allow people
|
||||||
|
to override the way values are drawn.
|
||||||
|
(gtk_scale_get_value_size): fix width/height mistake,
|
||||||
|
and compute size from actual displayed text, not
|
||||||
|
from made-up text.
|
||||||
|
|
||||||
|
* gtk/gtktexttag.c (gtk_text_tag_class_init): fix return type in
|
||||||
|
signal registration
|
||||||
|
|
||||||
|
* tests/testtext.c: Add "Remove all tags" menu item for testing
|
||||||
|
|
||||||
|
* gtk/gtktextbuffer.c (gtk_text_buffer_remove_all_tags): implement
|
||||||
|
|
||||||
|
* demos/gtk-demo/main.c (main): add hack so we can find modules
|
||||||
|
without installing gtk
|
||||||
|
|
||||||
|
* demos/gtk-demo/textview.c (insert_text): demo font scaling
|
||||||
|
|
||||||
|
* gtk/gtkcellrenderertext.c: Add "scale" property (font scaling
|
||||||
|
factor)
|
||||||
|
(gtk_cell_renderer_text_set_property): remove some bogus
|
||||||
|
g_object_notify
|
||||||
|
|
||||||
|
* gtk/gtktexttag.c: add "scale" property which is a font scaling
|
||||||
|
factor
|
||||||
|
|
||||||
|
* gtk/gtktextlayout.c (add_text_attrs): add font scale attribute
|
||||||
|
to layout
|
||||||
|
|
||||||
|
* gtk/gtktextiter.c (gtk_text_iter_is_start): rename from
|
||||||
|
gtk_text_iter_is_first
|
||||||
|
|
||||||
2001-01-06 Hans Breuer <hans@breuer.org>
|
2001-01-06 Hans Breuer <hans@breuer.org>
|
||||||
|
|
||||||
* gdk/gdk.def : updated exports
|
* gdk/gdk.def : updated exports
|
||||||
|
@ -1,3 +1,46 @@
|
|||||||
|
2001-05-04 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* configure.in: fix some shell typos
|
||||||
|
|
||||||
|
* gtk/gtkcolorsel.c (gtk_color_selection_destroy): warning fix
|
||||||
|
|
||||||
|
* gtk/gtkimage.c: handle animations
|
||||||
|
|
||||||
|
* gtk/gtkcheckbutton.c (gtk_check_button_size_request): request
|
||||||
|
border_width * 2, not just border_width
|
||||||
|
|
||||||
|
* gtk/gtkscale.c: add "format_value" signal to allow people
|
||||||
|
to override the way values are drawn.
|
||||||
|
(gtk_scale_get_value_size): fix width/height mistake,
|
||||||
|
and compute size from actual displayed text, not
|
||||||
|
from made-up text.
|
||||||
|
|
||||||
|
* gtk/gtktexttag.c (gtk_text_tag_class_init): fix return type in
|
||||||
|
signal registration
|
||||||
|
|
||||||
|
* tests/testtext.c: Add "Remove all tags" menu item for testing
|
||||||
|
|
||||||
|
* gtk/gtktextbuffer.c (gtk_text_buffer_remove_all_tags): implement
|
||||||
|
|
||||||
|
* demos/gtk-demo/main.c (main): add hack so we can find modules
|
||||||
|
without installing gtk
|
||||||
|
|
||||||
|
* demos/gtk-demo/textview.c (insert_text): demo font scaling
|
||||||
|
|
||||||
|
* gtk/gtkcellrenderertext.c: Add "scale" property (font scaling
|
||||||
|
factor)
|
||||||
|
(gtk_cell_renderer_text_set_property): remove some bogus
|
||||||
|
g_object_notify
|
||||||
|
|
||||||
|
* gtk/gtktexttag.c: add "scale" property which is a font scaling
|
||||||
|
factor
|
||||||
|
|
||||||
|
* gtk/gtktextlayout.c (add_text_attrs): add font scale attribute
|
||||||
|
to layout
|
||||||
|
|
||||||
|
* gtk/gtktextiter.c (gtk_text_iter_is_start): rename from
|
||||||
|
gtk_text_iter_is_first
|
||||||
|
|
||||||
2001-01-06 Hans Breuer <hans@breuer.org>
|
2001-01-06 Hans Breuer <hans@breuer.org>
|
||||||
|
|
||||||
* gdk/gdk.def : updated exports
|
* gdk/gdk.def : updated exports
|
||||||
|
@ -1,3 +1,46 @@
|
|||||||
|
2001-05-04 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* configure.in: fix some shell typos
|
||||||
|
|
||||||
|
* gtk/gtkcolorsel.c (gtk_color_selection_destroy): warning fix
|
||||||
|
|
||||||
|
* gtk/gtkimage.c: handle animations
|
||||||
|
|
||||||
|
* gtk/gtkcheckbutton.c (gtk_check_button_size_request): request
|
||||||
|
border_width * 2, not just border_width
|
||||||
|
|
||||||
|
* gtk/gtkscale.c: add "format_value" signal to allow people
|
||||||
|
to override the way values are drawn.
|
||||||
|
(gtk_scale_get_value_size): fix width/height mistake,
|
||||||
|
and compute size from actual displayed text, not
|
||||||
|
from made-up text.
|
||||||
|
|
||||||
|
* gtk/gtktexttag.c (gtk_text_tag_class_init): fix return type in
|
||||||
|
signal registration
|
||||||
|
|
||||||
|
* tests/testtext.c: Add "Remove all tags" menu item for testing
|
||||||
|
|
||||||
|
* gtk/gtktextbuffer.c (gtk_text_buffer_remove_all_tags): implement
|
||||||
|
|
||||||
|
* demos/gtk-demo/main.c (main): add hack so we can find modules
|
||||||
|
without installing gtk
|
||||||
|
|
||||||
|
* demos/gtk-demo/textview.c (insert_text): demo font scaling
|
||||||
|
|
||||||
|
* gtk/gtkcellrenderertext.c: Add "scale" property (font scaling
|
||||||
|
factor)
|
||||||
|
(gtk_cell_renderer_text_set_property): remove some bogus
|
||||||
|
g_object_notify
|
||||||
|
|
||||||
|
* gtk/gtktexttag.c: add "scale" property which is a font scaling
|
||||||
|
factor
|
||||||
|
|
||||||
|
* gtk/gtktextlayout.c (add_text_attrs): add font scale attribute
|
||||||
|
to layout
|
||||||
|
|
||||||
|
* gtk/gtktextiter.c (gtk_text_iter_is_start): rename from
|
||||||
|
gtk_text_iter_is_first
|
||||||
|
|
||||||
2001-01-06 Hans Breuer <hans@breuer.org>
|
2001-01-06 Hans Breuer <hans@breuer.org>
|
||||||
|
|
||||||
* gdk/gdk.def : updated exports
|
* gdk/gdk.def : updated exports
|
||||||
|
@ -1,3 +1,46 @@
|
|||||||
|
2001-05-04 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* configure.in: fix some shell typos
|
||||||
|
|
||||||
|
* gtk/gtkcolorsel.c (gtk_color_selection_destroy): warning fix
|
||||||
|
|
||||||
|
* gtk/gtkimage.c: handle animations
|
||||||
|
|
||||||
|
* gtk/gtkcheckbutton.c (gtk_check_button_size_request): request
|
||||||
|
border_width * 2, not just border_width
|
||||||
|
|
||||||
|
* gtk/gtkscale.c: add "format_value" signal to allow people
|
||||||
|
to override the way values are drawn.
|
||||||
|
(gtk_scale_get_value_size): fix width/height mistake,
|
||||||
|
and compute size from actual displayed text, not
|
||||||
|
from made-up text.
|
||||||
|
|
||||||
|
* gtk/gtktexttag.c (gtk_text_tag_class_init): fix return type in
|
||||||
|
signal registration
|
||||||
|
|
||||||
|
* tests/testtext.c: Add "Remove all tags" menu item for testing
|
||||||
|
|
||||||
|
* gtk/gtktextbuffer.c (gtk_text_buffer_remove_all_tags): implement
|
||||||
|
|
||||||
|
* demos/gtk-demo/main.c (main): add hack so we can find modules
|
||||||
|
without installing gtk
|
||||||
|
|
||||||
|
* demos/gtk-demo/textview.c (insert_text): demo font scaling
|
||||||
|
|
||||||
|
* gtk/gtkcellrenderertext.c: Add "scale" property (font scaling
|
||||||
|
factor)
|
||||||
|
(gtk_cell_renderer_text_set_property): remove some bogus
|
||||||
|
g_object_notify
|
||||||
|
|
||||||
|
* gtk/gtktexttag.c: add "scale" property which is a font scaling
|
||||||
|
factor
|
||||||
|
|
||||||
|
* gtk/gtktextlayout.c (add_text_attrs): add font scale attribute
|
||||||
|
to layout
|
||||||
|
|
||||||
|
* gtk/gtktextiter.c (gtk_text_iter_is_start): rename from
|
||||||
|
gtk_text_iter_is_first
|
||||||
|
|
||||||
2001-01-06 Hans Breuer <hans@breuer.org>
|
2001-01-06 Hans Breuer <hans@breuer.org>
|
||||||
|
|
||||||
* gdk/gdk.def : updated exports
|
* gdk/gdk.def : updated exports
|
||||||
|
@ -1,3 +1,46 @@
|
|||||||
|
2001-05-04 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* configure.in: fix some shell typos
|
||||||
|
|
||||||
|
* gtk/gtkcolorsel.c (gtk_color_selection_destroy): warning fix
|
||||||
|
|
||||||
|
* gtk/gtkimage.c: handle animations
|
||||||
|
|
||||||
|
* gtk/gtkcheckbutton.c (gtk_check_button_size_request): request
|
||||||
|
border_width * 2, not just border_width
|
||||||
|
|
||||||
|
* gtk/gtkscale.c: add "format_value" signal to allow people
|
||||||
|
to override the way values are drawn.
|
||||||
|
(gtk_scale_get_value_size): fix width/height mistake,
|
||||||
|
and compute size from actual displayed text, not
|
||||||
|
from made-up text.
|
||||||
|
|
||||||
|
* gtk/gtktexttag.c (gtk_text_tag_class_init): fix return type in
|
||||||
|
signal registration
|
||||||
|
|
||||||
|
* tests/testtext.c: Add "Remove all tags" menu item for testing
|
||||||
|
|
||||||
|
* gtk/gtktextbuffer.c (gtk_text_buffer_remove_all_tags): implement
|
||||||
|
|
||||||
|
* demos/gtk-demo/main.c (main): add hack so we can find modules
|
||||||
|
without installing gtk
|
||||||
|
|
||||||
|
* demos/gtk-demo/textview.c (insert_text): demo font scaling
|
||||||
|
|
||||||
|
* gtk/gtkcellrenderertext.c: Add "scale" property (font scaling
|
||||||
|
factor)
|
||||||
|
(gtk_cell_renderer_text_set_property): remove some bogus
|
||||||
|
g_object_notify
|
||||||
|
|
||||||
|
* gtk/gtktexttag.c: add "scale" property which is a font scaling
|
||||||
|
factor
|
||||||
|
|
||||||
|
* gtk/gtktextlayout.c (add_text_attrs): add font scale attribute
|
||||||
|
to layout
|
||||||
|
|
||||||
|
* gtk/gtktextiter.c (gtk_text_iter_is_start): rename from
|
||||||
|
gtk_text_iter_is_first
|
||||||
|
|
||||||
2001-01-06 Hans Breuer <hans@breuer.org>
|
2001-01-06 Hans Breuer <hans@breuer.org>
|
||||||
|
|
||||||
* gdk/gdk.def : updated exports
|
* gdk/gdk.def : updated exports
|
||||||
|
@ -563,18 +563,18 @@ AM_CONDITIONAL(HAVE_TIFF, test "x$LIBTIFF" != x)
|
|||||||
AM_CONDITIONAL(HAVE_PNG, test "x$LIBPNG" != x)
|
AM_CONDITIONAL(HAVE_PNG, test "x$LIBPNG" != x)
|
||||||
AM_CONDITIONAL(HAVE_JPEG, test "x$LIBJPEG" != x)
|
AM_CONDITIONAL(HAVE_JPEG, test "x$LIBJPEG" != x)
|
||||||
|
|
||||||
if test $dynworks = no ; then
|
if $dynworks ; then
|
||||||
STATIC_LIB_DEPS="$LIBTIFF $LIBJPEG $LIBPNG"
|
STATIC_LIB_DEPS="$LIBTIFF $LIBJPEG $LIBPNG"
|
||||||
else
|
else
|
||||||
STATIC_LIB_DEPS=
|
STATIC_LIB_DEPS=
|
||||||
if echo "$included_loaders" | grep "\(^\|\,\)tiff\(\$\|\,\)" > /dev/null; then
|
if echo "$included_loaders" | grep "\(^\|\,\)tiff\(\$\|\,\)" > /dev/null; then
|
||||||
STATIC_LIB_DEPS="STATIC_LIB_DEPS $LIBTIFF"
|
STATIC_LIB_DEPS="$STATIC_LIB_DEPS $LIBTIFF"
|
||||||
fi
|
fi
|
||||||
if echo "$included_loaders" | grep "\(^\|\,\)jpeg\(\$\|\,\)" > /dev/null; then
|
if echo "$included_loaders" | grep "\(^\|\,\)jpeg\(\$\|\,\)" > /dev/null; then
|
||||||
STATIC_LIB_DEPS="STATIC_LIB_DEPS $LIBJPEG"
|
STATIC_LIB_DEPS="$STATIC_LIB_DEPS $LIBJPEG"
|
||||||
fi
|
fi
|
||||||
if echo "$included_loaders" | grep "\(^\|\,\)png\(\$\|\,\)" > /dev/null; then
|
if echo "$included_loaders" | grep "\(^\|\,\)png\(\$\|\,\)" > /dev/null; then
|
||||||
STATIC_LIB_DEPS="STATIC_LIB_DEPS $LIBPNG"
|
STATIC_LIB_DEPS="$STATIC_LIB_DEPS $LIBPNG"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -59,8 +59,10 @@ gtk_demo_SOURCES = \
|
|||||||
gtk_demo_DEPENDENCIES = $(DEPS)
|
gtk_demo_DEPENDENCIES = $(DEPS)
|
||||||
gtk_demo_LDADD = $(LDADDS)
|
gtk_demo_LDADD = $(LDADDS)
|
||||||
|
|
||||||
IMAGEFILES= apple-red.png \
|
IMAGEFILES= alphatest.png \
|
||||||
|
apple-red.png \
|
||||||
background.jpg \
|
background.jpg \
|
||||||
|
floppybuddy.gif \
|
||||||
gnome-applets.png \
|
gnome-applets.png \
|
||||||
gnome-calendar.png \
|
gnome-calendar.png \
|
||||||
gnome-foot.png \
|
gnome-foot.png \
|
||||||
|
BIN
demos/gtk-demo/alphatest.png
Normal file
BIN
demos/gtk-demo/alphatest.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
BIN
demos/gtk-demo/floppybuddy.gif
Normal file
BIN
demos/gtk-demo/floppybuddy.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
@ -8,6 +8,8 @@
|
|||||||
*
|
*
|
||||||
* If you want to put image data in your program as a C variable,
|
* If you want to put image data in your program as a C variable,
|
||||||
* use the make-inline-pixbuf program that comes with GTK+.
|
* use the make-inline-pixbuf program that comes with GTK+.
|
||||||
|
* This way you won't need to depend on loading external files, your
|
||||||
|
* application binary can be self-contained.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
@ -39,14 +41,14 @@ progressive_prepared_callback (GdkPixbufLoader* loader, gpointer data)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
progressive_updated_callback (GdkPixbufLoader* loader,
|
progressive_updated_callback (GdkPixbufLoader* loader,
|
||||||
guint x, guint y, guint width, guint height,
|
gint x, gint y, gint width, gint height,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
GtkWidget* image;
|
GtkWidget* image;
|
||||||
|
|
||||||
image = GTK_WIDGET (data);
|
image = GTK_WIDGET (data);
|
||||||
|
|
||||||
/* We know the pixbuf inside the image has changed, but the image
|
/* 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
|
* itself doesn't know this; so queue a redraw. If we wanted to be
|
||||||
* really efficient, we could use a drawing area or something
|
* really efficient, we could use a drawing area or something
|
||||||
* instead of a GtkImage, so we could control the exact position of
|
* instead of a GtkImage, so we could control the exact position of
|
||||||
@ -85,7 +87,7 @@ progressive_timeout (gpointer data)
|
|||||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
GTK_MESSAGE_ERROR,
|
GTK_MESSAGE_ERROR,
|
||||||
GTK_BUTTONS_CLOSE,
|
GTK_BUTTONS_CLOSE,
|
||||||
"Failure reading image file 'gtk-logo-rgb.gif': %s",
|
"Failure reading image file 'alphatest.png': %s",
|
||||||
g_strerror (errno));
|
g_strerror (errno));
|
||||||
|
|
||||||
gtk_signal_connect (GTK_OBJECT (dialog),
|
gtk_signal_connect (GTK_OBJECT (dialog),
|
||||||
@ -180,10 +182,10 @@ progressive_timeout (gpointer data)
|
|||||||
{
|
{
|
||||||
const gchar *filename;
|
const gchar *filename;
|
||||||
|
|
||||||
if (g_file_test ("./gtk-logo-rgb.gif", G_FILE_TEST_EXISTS))
|
if (g_file_test ("./alphatest.png", G_FILE_TEST_EXISTS))
|
||||||
filename = "./gtk-logo-rgb.gif";
|
filename = "./alphatest.png";
|
||||||
else
|
else
|
||||||
filename = DEMOCODEDIR"/gtk-logo-rgb.gif";
|
filename = DEMOCODEDIR"/alphatest.png";
|
||||||
|
|
||||||
image_stream = fopen (filename, "r");
|
image_stream = fopen (filename, "r");
|
||||||
|
|
||||||
@ -195,7 +197,7 @@ progressive_timeout (gpointer data)
|
|||||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
GTK_MESSAGE_ERROR,
|
GTK_MESSAGE_ERROR,
|
||||||
GTK_BUTTONS_CLOSE,
|
GTK_BUTTONS_CLOSE,
|
||||||
"Unable to open image file 'gtk-logo-rgb.gif': %s",
|
"Unable to open image file 'alphatest.png': %s",
|
||||||
g_strerror (errno));
|
g_strerror (errno));
|
||||||
|
|
||||||
gtk_signal_connect (GTK_OBJECT (dialog),
|
gtk_signal_connect (GTK_OBJECT (dialog),
|
||||||
@ -246,7 +248,7 @@ start_progressive_loading (GtkWidget *image)
|
|||||||
* The timeout simply simulates a slow data source by inserting
|
* The timeout simply simulates a slow data source by inserting
|
||||||
* pauses in the reading process.
|
* pauses in the reading process.
|
||||||
*/
|
*/
|
||||||
load_timeout = g_timeout_add (300,
|
load_timeout = g_timeout_add (150,
|
||||||
progressive_timeout,
|
progressive_timeout,
|
||||||
image);
|
image);
|
||||||
}
|
}
|
||||||
@ -359,6 +361,37 @@ do_images (void)
|
|||||||
|
|
||||||
gtk_container_add (GTK_CONTAINER (frame), image);
|
gtk_container_add (GTK_CONTAINER (frame), image);
|
||||||
|
|
||||||
|
|
||||||
|
/* Animation */
|
||||||
|
|
||||||
|
label = gtk_label_new (NULL);
|
||||||
|
gtk_label_set_markup (GTK_LABEL (label),
|
||||||
|
"<u>Animation loaded from a file</u>");
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* We look for the image in the current directory first,
|
||||||
|
* so you can run gtk-demo without installing GTK
|
||||||
|
*/
|
||||||
|
if (g_file_test ("./floppybuddy.gif", G_FILE_TEST_EXISTS))
|
||||||
|
image = gtk_image_new_from_file ("./floppybuddy.gif");
|
||||||
|
else
|
||||||
|
image = gtk_image_new_from_file (DEMOCODEDIR"/floppybuddy.gif");
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (frame), image);
|
||||||
|
|
||||||
|
|
||||||
|
/* Progressive */
|
||||||
|
|
||||||
|
|
||||||
label = gtk_label_new (NULL);
|
label = gtk_label_new (NULL);
|
||||||
gtk_label_set_markup (GTK_LABEL (label),
|
gtk_label_set_markup (GTK_LABEL (label),
|
||||||
"<u>Progressive image loading</u>");
|
"<u>Progressive image loading</u>");
|
||||||
|
@ -465,6 +465,18 @@ main (int argc, char **argv)
|
|||||||
GtkWidget *tree;
|
GtkWidget *tree;
|
||||||
GtkTextTag *tag;
|
GtkTextTag *tag;
|
||||||
|
|
||||||
|
/* Most code in gtk-demo is intended to be exemplary, but not
|
||||||
|
* these few lines, which are just a hack so gtk-demo will work
|
||||||
|
* in the GTK tree without installing it.
|
||||||
|
*/
|
||||||
|
if (g_file_test ("../../gdk-pixbuf/.libs/libpixbufloader-pnm.so",
|
||||||
|
G_FILE_TEST_EXISTS))
|
||||||
|
{
|
||||||
|
putenv ("GDK_PIXBUF_MODULEDIR=../../gdk-pixbuf/.libs");
|
||||||
|
putenv ("GTK_IM_MODULE_FILE=../../modules/input/gtk.immodules");
|
||||||
|
}
|
||||||
|
/* -- End of hack -- */
|
||||||
|
|
||||||
gtk_init (&argc, &argv);
|
gtk_init (&argc, &argv);
|
||||||
|
|
||||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
|
@ -84,6 +84,12 @@ create_tags (GtkTextBuffer *buffer)
|
|||||||
/* points times the PANGO_SCALE factor */
|
/* points times the PANGO_SCALE factor */
|
||||||
"size", 30 * PANGO_SCALE, NULL);
|
"size", 30 * PANGO_SCALE, NULL);
|
||||||
|
|
||||||
|
gtk_text_buffer_create_tag (buffer, "xx-small",
|
||||||
|
"scale", PANGO_SCALE_XX_SMALL, NULL);
|
||||||
|
|
||||||
|
gtk_text_buffer_create_tag (buffer, "x-large",
|
||||||
|
"scale", PANGO_SCALE_X_LARGE, NULL);
|
||||||
|
|
||||||
gtk_text_buffer_create_tag (buffer, "monospace",
|
gtk_text_buffer_create_tag (buffer, "monospace",
|
||||||
"family", "monospace", NULL);
|
"family", "monospace", NULL);
|
||||||
|
|
||||||
@ -199,7 +205,16 @@ insert_text (GtkTextBuffer *buffer)
|
|||||||
gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
|
gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
|
||||||
"big", -1,
|
"big", -1,
|
||||||
"big", NULL);
|
"big", NULL);
|
||||||
gtk_text_buffer_insert (buffer, &iter, " text.\n\n", -1);
|
gtk_text_buffer_insert (buffer, &iter, " text. ", -1);
|
||||||
|
gtk_text_buffer_insert (buffer, &iter, "It's best not to hardcode specific text sizes; you can use relative sizes as with CSS, such as ", -1);
|
||||||
|
gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
|
||||||
|
"xx-small", -1,
|
||||||
|
"xx-small", NULL);
|
||||||
|
gtk_text_buffer_insert (buffer, &iter, " or ", -1);
|
||||||
|
gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
|
||||||
|
"x-large", -1,
|
||||||
|
"x-large", NULL);
|
||||||
|
gtk_text_buffer_insert (buffer, &iter, " to ensure that your program properly adapts if the user changes the default font size.\n\n", -1);
|
||||||
|
|
||||||
gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Colors. ", -1,
|
gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Colors. ", -1,
|
||||||
"heading", NULL);
|
"heading", NULL);
|
||||||
|
@ -23,466 +23,426 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <gdk-pixbuf/gdk-pixbuf-loader.h>
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct _LoadContext LoadContext;
|
||||||
FILE *imagefile;
|
|
||||||
GdkPixbufLoader *loader;
|
|
||||||
GtkWidget **rgbwin;
|
|
||||||
guchar *buf;
|
|
||||||
guint timeout;
|
|
||||||
guint readlen;
|
|
||||||
|
|
||||||
} ProgressFileStatus;
|
struct _LoadContext
|
||||||
|
{
|
||||||
|
gchar *filename;
|
||||||
#define DEFAULT_WIDTH 24
|
GtkWidget *window;
|
||||||
#define DEFAULT_HEIGHT 24
|
GdkPixbufLoader *pixbuf_loader;
|
||||||
|
guint load_timeout;
|
||||||
static const unsigned char default_image[] = {
|
FILE* image_stream;
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0xae, 0xb3, 0xb3, 0xc6, 0xc9, 0xcd, 0xd7, 0xd4, 0xdf,
|
|
||||||
0xec, 0xde, 0xf3, 0xe7, 0xcb, 0xe9, 0xd9, 0xb5, 0xd3, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xb1, 0xb7, 0xa5,
|
|
||||||
0xb0, 0xb8, 0xad, 0xb3, 0xb9, 0xb6, 0xc1, 0xc6, 0xc8, 0xd5, 0xd3, 0xdc,
|
|
||||||
0xec, 0xde, 0xf3, 0xe5, 0xca, 0xe6, 0xe0, 0xbb, 0xd7, 0xe1, 0xad, 0xc2,
|
|
||||||
0xe3, 0xac, 0xa3, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xca, 0xc1, 0xa4, 0xc5, 0xc7, 0xac,
|
|
||||||
0xb7, 0xbe, 0xaf, 0xad, 0xb4, 0xaf, 0xbd, 0xc2, 0xc3, 0xd1, 0xd0, 0xd8,
|
|
||||||
0xec, 0xde, 0xf3, 0xe5, 0xc7, 0xe4, 0xe0, 0xb6, 0xd1, 0xe7, 0xa9, 0xb4,
|
|
||||||
0xed, 0xcd, 0xb6, 0xd6, 0xcf, 0xae, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0x00, 0x00, 0x00, 0xdf, 0xa7, 0x9f, 0xdd, 0xbf, 0xaa, 0xcf, 0xc5, 0xa9,
|
|
||||||
0xc1, 0xc4, 0xac, 0xb2, 0xba, 0xaf, 0xb6, 0xbb, 0xbb, 0xcd, 0xce, 0xd4,
|
|
||||||
0xec, 0xde, 0xf3, 0xe4, 0xc4, 0xe1, 0xe0, 0xaf, 0xc7, 0xea, 0xbc, 0xae,
|
|
||||||
0xe1, 0xd6, 0xb6, 0xc7, 0xcc, 0xae, 0xa2, 0xab, 0x9a, 0x00, 0x00, 0x00,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0x00, 0x00, 0x00, 0xe3, 0xab, 0xc0, 0xe6, 0xa3, 0xa7, 0xdf, 0xba, 0xa8,
|
|
||||||
0xcf, 0xc5, 0xa9, 0xbd, 0xc2, 0xae, 0xad, 0xb4, 0xaf, 0xc6, 0xc9, 0xcd,
|
|
||||||
0xec, 0xde, 0xf3, 0xe2, 0xbf, 0xdc, 0xe7, 0xa9, 0xb4, 0xe7, 0xd6, 0xb8,
|
|
||||||
0xc7, 0xcc, 0xae, 0xac, 0xb6, 0xa6, 0x9d, 0xa8, 0x9f, 0x00, 0x00, 0x00,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
|
|
||||||
0xd9, 0xaf, 0xcf, 0xe1, 0xb4, 0xd2, 0xe2, 0xb0, 0xcb, 0xe4, 0xa9, 0xbb,
|
|
||||||
0xe2, 0xb2, 0xa6, 0xcf, 0xc5, 0xa9, 0x6a, 0x6a, 0x6a, 0x0d, 0x0d, 0x0d,
|
|
||||||
0x0d, 0x0d, 0x0d, 0x6a, 0x6a, 0x6a, 0xed, 0xcd, 0xb6, 0xc7, 0xcc, 0xae,
|
|
||||||
0xa6, 0xb1, 0xa3, 0x98, 0xa2, 0x9c, 0x8f, 0x97, 0x96, 0x7e, 0x84, 0x85,
|
|
||||||
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
|
|
||||||
0xe8, 0xc6, 0xe7, 0xe5, 0xc2, 0xe3, 0xe3, 0xbd, 0xdd, 0xe1, 0xb6, 0xd5,
|
|
||||||
0xe2, 0xb0, 0xcb, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x6a, 0x6a, 0x6a, 0x9d, 0xa8, 0x9f,
|
|
||||||
0x8f, 0x97, 0x96, 0x8b, 0x90, 0x92, 0x97, 0x9e, 0xa2, 0xa0, 0xa7, 0xae,
|
|
||||||
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
|
|
||||||
0xe7, 0xd3, 0xed, 0xe8, 0xd1, 0xed, 0xe8, 0xce, 0xec, 0xe9, 0xcc, 0xeb,
|
|
||||||
0xe8, 0xc6, 0xe7, 0x0d, 0x0d, 0x0d, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x0d, 0x0d, 0x0d, 0x97, 0x9e, 0xa2,
|
|
||||||
0xa7, 0xae, 0xb7, 0xb2, 0xb6, 0xc5, 0xba, 0xbc, 0xce, 0xbf, 0xbe, 0xd3,
|
|
||||||
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
|
|
||||||
0xe9, 0xdf, 0xf0, 0xe9, 0xdf, 0xf0, 0xe9, 0xdf, 0xf0, 0xe9, 0xdf, 0xf0,
|
|
||||||
0xe9, 0xdf, 0xf0, 0x0d, 0x0d, 0x0d, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x0d, 0x0d, 0x0d, 0xe1, 0xd2, 0xf7,
|
|
||||||
0xe1, 0xd2, 0xf7, 0xe1, 0xd2, 0xf7, 0xe1, 0xd2, 0xf7, 0xe1, 0xd2, 0xf7,
|
|
||||||
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
|
|
||||||
0xca, 0xc7, 0xd2, 0xc5, 0xc4, 0xcd, 0xbf, 0xbf, 0xc7, 0xb8, 0xb9, 0xc0,
|
|
||||||
0xae, 0xaf, 0xb6, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x6a, 0x6a, 0x6a, 0xd5, 0xa8, 0xe1,
|
|
||||||
0xd8, 0xb2, 0xe9, 0xd9, 0xb8, 0xed, 0xdb, 0xbd, 0xf0, 0xdc, 0xbf, 0xf1,
|
|
||||||
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
|
|
||||||
0xa4, 0xa6, 0xac, 0xa8, 0xaa, 0xaf, 0xa0, 0xa6, 0xa8, 0x98, 0x9e, 0x9c,
|
|
||||||
0xa1, 0xa8, 0x9e, 0xb1, 0xb6, 0xa1, 0x6a, 0x6a, 0x6a, 0x0d, 0x0d, 0x0d,
|
|
||||||
0x0d, 0x0d, 0x0d, 0x6a, 0x6a, 0x6a, 0xc0, 0x8c, 0xad, 0xcc, 0x90, 0xb5,
|
|
||||||
0xd3, 0x94, 0xca, 0xd6, 0xa2, 0xdb, 0xd5, 0xa8, 0xe1, 0xcf, 0xa7, 0xdf,
|
|
||||||
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0x00, 0x00, 0x00, 0x98, 0x9f, 0x9b, 0xa1, 0xa8, 0x9e, 0xac, 0xb3, 0xa0,
|
|
||||||
0xb9, 0xb9, 0xa4, 0xd0, 0xb8, 0xa8, 0xc5, 0xb5, 0xb8, 0xb6, 0xbb, 0xad,
|
|
||||||
0xe3, 0xd7, 0xb5, 0xdd, 0xb4, 0xa9, 0xcb, 0x89, 0xac, 0xc0, 0x8c, 0xad,
|
|
||||||
0xc8, 0x91, 0xb5, 0xd1, 0x8d, 0xb7, 0xd3, 0x94, 0xca, 0x00, 0x00, 0x00,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0x00, 0x00, 0x00, 0xa1, 0xa7, 0x98, 0xb1, 0xb6, 0xa1, 0xbd, 0xb9, 0xa5,
|
|
||||||
0xd0, 0xb8, 0xa8, 0xca, 0xb5, 0xb7, 0xb8, 0xb1, 0xb1, 0xc2, 0xc8, 0xb2,
|
|
||||||
0xe3, 0xd7, 0xb5, 0xe1, 0xbf, 0xaf, 0xdb, 0x92, 0x9a, 0xbe, 0x82, 0xa6,
|
|
||||||
0xc0, 0x8c, 0xad, 0xc8, 0x91, 0xb4, 0xc7, 0x8b, 0xb0, 0x00, 0x00, 0x00,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xbc, 0xb6, 0xa1, 0xd0, 0xb8, 0xa8,
|
|
||||||
0xcd, 0xb6, 0xb7, 0xc0, 0xb4, 0xb5, 0xb1, 0xb1, 0xaa, 0xca, 0xd1, 0xb4,
|
|
||||||
0xe3, 0xd7, 0xb5, 0xe2, 0xc1, 0xb0, 0xdb, 0xa8, 0xa3, 0xd2, 0x8a, 0xa9,
|
|
||||||
0xb7, 0x7e, 0xa2, 0xbd, 0x89, 0xa9, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xc9, 0xaf, 0xaf,
|
|
||||||
0xc5, 0xb5, 0xb8, 0xb8, 0xb1, 0xb1, 0xb6, 0xbb, 0xad, 0xd0, 0xd6, 0xb5,
|
|
||||||
0xe3, 0xd7, 0xb5, 0xe2, 0xbf, 0xaf, 0xdd, 0xb4, 0xa9, 0xdb, 0x92, 0x9a,
|
|
||||||
0xc6, 0x84, 0xa7, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0xac, 0xaa, 0xa6, 0xbd, 0xc3, 0xb0, 0xd2, 0xd7, 0xb5,
|
|
||||||
0xe3, 0xd7, 0xb5, 0xe2, 0xbf, 0xae, 0xdb, 0xb6, 0xa8, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
||||||
0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
quit_func (GtkWidget *widget, gpointer dummy)
|
destroy_context (gpointer data)
|
||||||
{
|
{
|
||||||
gtk_main_quit ();
|
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 (G_OBJECT (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
|
static void
|
||||||
expose_func (GtkWidget *drawing_area, GdkEventExpose *event, gpointer data)
|
progressive_prepared_callback (GdkPixbufLoader* loader,
|
||||||
|
gpointer data)
|
||||||
{
|
{
|
||||||
GdkPixbuf* pixbuf;
|
GdkPixbuf* pixbuf;
|
||||||
|
GtkWidget* image;
|
||||||
|
|
||||||
pixbuf = (GdkPixbuf *)gtk_object_get_data(GTK_OBJECT(drawing_area), "pixbuf");
|
image = GTK_WIDGET (data);
|
||||||
|
|
||||||
if (gdk_pixbuf_get_has_alpha (pixbuf)) {
|
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
|
||||||
gdk_draw_rgb_32_image (drawing_area->window,
|
|
||||||
drawing_area->style->black_gc,
|
/* Avoid displaying random memory contents, since the pixbuf
|
||||||
event->area.x, event->area.y,
|
* isn't filled in yet.
|
||||||
event->area.width,
|
*/
|
||||||
event->area.height,
|
gdk_pixbuf_fill (pixbuf, 0xaaaaaaff);
|
||||||
GDK_RGB_DITHER_MAX,
|
|
||||||
gdk_pixbuf_get_pixels (pixbuf)
|
/* Could set the pixbuf instead, if we only wanted to display
|
||||||
+ (event->area.y * gdk_pixbuf_get_rowstride (pixbuf))
|
* static images.
|
||||||
+ (event->area.x * gdk_pixbuf_get_n_channels (pixbuf)),
|
*/
|
||||||
gdk_pixbuf_get_rowstride (pixbuf));
|
gtk_image_set_from_animation (GTK_IMAGE (image),
|
||||||
} else {
|
gdk_pixbuf_loader_get_animation (loader));
|
||||||
gdk_draw_rgb_image (drawing_area->window,
|
|
||||||
drawing_area->style->white_gc,
|
|
||||||
event->area.x, event->area.y,
|
|
||||||
event->area.width,
|
|
||||||
event->area.height,
|
|
||||||
GDK_RGB_DITHER_NORMAL,
|
|
||||||
gdk_pixbuf_get_pixels (pixbuf)
|
|
||||||
+ (event->area.y * gdk_pixbuf_get_rowstride (pixbuf))
|
|
||||||
+ (event->area.x * gdk_pixbuf_get_n_channels (pixbuf)),
|
|
||||||
gdk_pixbuf_get_rowstride (pixbuf));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
config_func (GtkWidget *drawing_area, GdkEventConfigure *event, gpointer data)
|
progressive_updated_callback (GdkPixbufLoader* loader,
|
||||||
|
gint x, gint y, gint width, gint height,
|
||||||
|
gpointer data)
|
||||||
{
|
{
|
||||||
GdkPixbuf *pixbuf;
|
GtkWidget* image;
|
||||||
|
|
||||||
pixbuf = (GdkPixbuf *)gtk_object_get_data(GTK_OBJECT(drawing_area), "pixbuf");
|
image = GTK_WIDGET (data);
|
||||||
|
|
||||||
#if 0
|
/* We know the pixbuf inside the GtkImage has changed, but the image
|
||||||
if (((event->width) != gdk_pixbuf_get_width (pixbuf)) ||
|
* itself doesn't know this; so queue a redraw. If we wanted to be
|
||||||
((event->height) != gdk_pixbuf_get_height (pixbuf)))
|
* really efficient, we could use a drawing area or something
|
||||||
gdk_pixbuf_scale(pixbuf, event->width, event->height);
|
* instead of a GtkImage, so we could control the exact position of
|
||||||
#endif
|
* 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));
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (dialog),
|
||||||
|
"response",
|
||||||
|
GTK_SIGNAL_FUNC (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);
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (dialog),
|
||||||
|
"response",
|
||||||
|
GTK_SIGNAL_FUNC (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);
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (dialog),
|
||||||
|
"response",
|
||||||
|
GTK_SIGNAL_FUNC (gtk_widget_destroy),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
gtk_widget_show (dialog);
|
||||||
|
|
||||||
|
g_object_unref (G_OBJECT (lc->pixbuf_loader));
|
||||||
|
lc->pixbuf_loader = NULL;
|
||||||
|
|
||||||
|
lc->load_timeout = 0;
|
||||||
|
|
||||||
|
return FALSE; /* uninstall the timeout */
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (G_OBJECT (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));
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (dialog),
|
||||||
|
"response",
|
||||||
|
GTK_SIGNAL_FUNC (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 (G_OBJECT (lc->pixbuf_loader));
|
||||||
|
lc->pixbuf_loader = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
lc->pixbuf_loader = gdk_pixbuf_loader_new ();
|
||||||
|
|
||||||
|
g_signal_connect_data (G_OBJECT (lc->pixbuf_loader),
|
||||||
|
"area_prepared",
|
||||||
|
G_CALLBACK (progressive_prepared_callback),
|
||||||
|
image,
|
||||||
|
NULL, FALSE, FALSE);
|
||||||
|
|
||||||
|
g_signal_connect_data (G_OBJECT (lc->pixbuf_loader),
|
||||||
|
"area_updated",
|
||||||
|
G_CALLBACK (progressive_updated_callback),
|
||||||
|
image,
|
||||||
|
NULL, FALSE, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 = g_timeout_add (100,
|
||||||
|
progressive_timeout,
|
||||||
|
image);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkWidget *
|
static GtkWidget *
|
||||||
new_testrgb_window (GdkPixbuf *pixbuf, gchar *title)
|
do_image (const char *filename)
|
||||||
{
|
{
|
||||||
GtkWidget *window;
|
GtkWidget *frame;
|
||||||
GtkWidget *vbox;
|
GtkWidget *vbox;
|
||||||
GtkWidget *temp_box;
|
GtkWidget *image;
|
||||||
GtkWidget *button;
|
GtkWidget *label;
|
||||||
GtkWidget *drawing_area;
|
GtkWidget *align;
|
||||||
gint w, h;
|
GtkWidget *window;
|
||||||
|
gchar *str, *escaped;
|
||||||
|
LoadContext *lc;
|
||||||
|
|
||||||
w = gdk_pixbuf_get_width (pixbuf);
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
h = gdk_pixbuf_get_height (pixbuf);
|
gtk_window_set_title (GTK_WINDOW (window), "Image Loading");
|
||||||
|
|
||||||
window = gtk_widget_new (gtk_window_get_type (),
|
gtk_container_set_border_width (GTK_CONTAINER (window), 8);
|
||||||
"GtkObject::user_data", NULL,
|
|
||||||
"GtkWindow::type", GTK_WINDOW_TOPLEVEL,
|
|
||||||
"GtkWindow::title", "testrgb",
|
|
||||||
"GtkWindow::allow_shrink", TRUE,
|
|
||||||
NULL);
|
|
||||||
gtk_signal_connect (GTK_OBJECT (window), "destroy",
|
|
||||||
(GtkSignalFunc) quit_func, NULL);
|
|
||||||
|
|
||||||
vbox = gtk_vbox_new (FALSE, 0);
|
|
||||||
|
|
||||||
if (title)
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (title),
|
|
||||||
TRUE, TRUE, 0);
|
|
||||||
|
|
||||||
drawing_area = gtk_drawing_area_new ();
|
|
||||||
|
|
||||||
temp_box = gtk_hbox_new (FALSE, 0);
|
|
||||||
gtk_widget_set_usize (GTK_WIDGET (drawing_area), w, h);
|
|
||||||
gtk_box_pack_start (GTK_BOX (temp_box), drawing_area, FALSE, FALSE, 0);
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox), temp_box, FALSE, FALSE, 0);
|
|
||||||
|
|
||||||
|
|
||||||
gtk_signal_connect (GTK_OBJECT(drawing_area), "expose_event",
|
|
||||||
GTK_SIGNAL_FUNC(expose_func), NULL);
|
|
||||||
gtk_signal_connect (GTK_OBJECT(drawing_area), "configure_event",
|
|
||||||
GTK_SIGNAL_FUNC (config_func), NULL);
|
|
||||||
|
|
||||||
gtk_object_set_data (GTK_OBJECT(drawing_area), "pixbuf", pixbuf);
|
|
||||||
|
|
||||||
gtk_widget_show (drawing_area);
|
|
||||||
|
|
||||||
button = gtk_button_new_with_label ("Quit");
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
|
||||||
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
|
|
||||||
(GtkSignalFunc) gtk_widget_destroy,
|
|
||||||
GTK_OBJECT (window));
|
|
||||||
|
|
||||||
gtk_widget_show (button);
|
|
||||||
|
|
||||||
|
vbox = gtk_vbox_new (FALSE, 8);
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
|
||||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||||
gtk_widget_show_all (vbox);
|
|
||||||
|
|
||||||
gtk_widget_show (window);
|
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);
|
||||||
|
|
||||||
|
gtk_widget_show_all (window);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
static gint
|
|
||||||
update_timeout(gpointer data)
|
|
||||||
{
|
|
||||||
ProgressFileStatus *status = data;
|
|
||||||
gboolean done;
|
|
||||||
|
|
||||||
done = TRUE;
|
|
||||||
if (!feof(status->imagefile)) {
|
|
||||||
gint nbytes;
|
|
||||||
|
|
||||||
nbytes = fread(status->buf, 1, status->readlen,
|
|
||||||
status->imagefile);
|
|
||||||
|
|
||||||
done = !gdk_pixbuf_loader_write (GDK_PIXBUF_LOADER (status->loader), status->buf, nbytes);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (done) {
|
|
||||||
gtk_widget_queue_draw(*status->rgbwin);
|
|
||||||
gdk_pixbuf_loader_close (GDK_PIXBUF_LOADER (status->loader));
|
|
||||||
g_object_destroy (G_OBJECT(status->loader));
|
|
||||||
fclose (status->imagefile);
|
|
||||||
g_free (status->buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !done;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
progressive_prepared_callback(GdkPixbufLoader* loader, gpointer data)
|
do_nonprogressive (const gchar *filename)
|
||||||
{
|
{
|
||||||
GtkWidget** retloc = data;
|
GtkWidget *frame;
|
||||||
GdkPixbuf* pixbuf;
|
GtkWidget *vbox;
|
||||||
|
GtkWidget *image;
|
||||||
|
GtkWidget *label;
|
||||||
|
GtkWidget *align;
|
||||||
|
GtkWidget *window;
|
||||||
|
gchar *str, *escaped;
|
||||||
|
|
||||||
pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
g_assert(pixbuf != NULL);
|
gtk_window_set_title (GTK_WINDOW (window), "Animation");
|
||||||
|
|
||||||
gdk_pixbuf_ref(pixbuf); /* for the RGB window */
|
gtk_container_set_border_width (GTK_CONTAINER (window), 8);
|
||||||
|
|
||||||
*retloc = new_testrgb_window(pixbuf, "Progressive");
|
vbox = gtk_vbox_new (FALSE, 8);
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
|
||||||
|
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||||
|
|
||||||
return;
|
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);
|
||||||
|
|
||||||
|
gtk_widget_show_all (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
progressive_updated_callback(GdkPixbufLoader* loader, guint x, guint y, guint width, guint height, gpointer data)
|
|
||||||
{
|
|
||||||
GtkWidget** window_loc = data;
|
|
||||||
|
|
||||||
/* g_print ("progressive_updated_callback:\n\t%d\t%d\t%d\t%d\n", x, y, width, height); */
|
|
||||||
|
|
||||||
if (*window_loc != NULL)
|
|
||||||
gtk_widget_queue_draw_area(*window_loc,
|
|
||||||
x, y, width, height);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int readlen = 4096;
|
|
||||||
|
|
||||||
extern void pixbuf_init();
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc,
|
||||||
|
char **argv)
|
||||||
{
|
{
|
||||||
int i;
|
gint i;
|
||||||
int found_valid = FALSE;
|
|
||||||
|
|
||||||
GdkPixbufAnimation *animation;
|
|
||||||
|
|
||||||
pixbuf_init ();
|
|
||||||
|
|
||||||
gtk_init (&argc, &argv);
|
gtk_init (&argc, &argv);
|
||||||
|
|
||||||
gdk_rgb_set_verbose (TRUE);
|
|
||||||
|
|
||||||
gdk_rgb_init ();
|
|
||||||
|
|
||||||
gtk_widget_set_default_colormap (gdk_rgb_get_cmap ());
|
|
||||||
|
|
||||||
{
|
|
||||||
char *tbf_readlen = getenv("TBF_READLEN");
|
|
||||||
if(tbf_readlen) readlen = atoi(tbf_readlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
char *tbf_bps = getenv("TBF_KBPS");
|
|
||||||
guint bps;
|
|
||||||
|
|
||||||
if (tbf_bps) {
|
|
||||||
bps = atoi(tbf_bps);
|
|
||||||
g_print ("Simulating %d kBytes/sec\n", bps);
|
|
||||||
readlen = (bps*1024)/10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 1;
|
i = 1;
|
||||||
if (argc == 1) {
|
while (i < argc)
|
||||||
g_print ("USAGE: testanimation FILE1 ...\n");
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
for (i = 1; i < argc; i++) {
|
|
||||||
GError *error;
|
|
||||||
|
|
||||||
error = NULL;
|
|
||||||
animation = gdk_pixbuf_animation_new_from_file (argv[i],
|
|
||||||
&error);
|
|
||||||
|
|
||||||
if (animation == NULL) {
|
|
||||||
g_warning ("Failed to load animation: %s",
|
|
||||||
error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (animation) {
|
|
||||||
gint i = 0;
|
|
||||||
GList *listptr;
|
|
||||||
for (listptr = gdk_pixbuf_animation_get_frames (animation);
|
|
||||||
listptr;
|
|
||||||
listptr = listptr->next) {
|
|
||||||
GdkPixbufFrame *frame;
|
|
||||||
GdkPixbuf *pixbuf;
|
|
||||||
gchar *title;
|
|
||||||
|
|
||||||
frame = listptr->data;
|
|
||||||
pixbuf = gdk_pixbuf_frame_get_pixbuf (frame);
|
|
||||||
|
|
||||||
title = g_strdup_printf ("Frame %d", i);
|
|
||||||
g_print ("Frame %d x:%d y:%d width:%d height:%d\n",
|
|
||||||
i,
|
|
||||||
gdk_pixbuf_frame_get_x_offset (frame),
|
|
||||||
gdk_pixbuf_frame_get_y_offset (frame),
|
|
||||||
gdk_pixbuf_get_width (pixbuf),
|
|
||||||
gdk_pixbuf_get_height (pixbuf));
|
|
||||||
new_testrgb_window (pixbuf, title);
|
|
||||||
g_free (title);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
found_valid = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
{
|
{
|
||||||
GtkWidget* rgb_window = NULL;
|
do_image (argv[i]);
|
||||||
ProgressFileStatus status;
|
do_nonprogressive (argv[i]);
|
||||||
GdkPixbufLoader *pixbuf_loader;
|
|
||||||
|
|
||||||
pixbuf_loader = gdk_pixbuf_loader_new ();
|
++i;
|
||||||
status.loader = pixbuf_loader;
|
|
||||||
|
|
||||||
status.rgbwin = &rgb_window;
|
|
||||||
|
|
||||||
status.buf = g_malloc (readlen);
|
|
||||||
g_signal_connect_data(G_OBJECT(pixbuf_loader),
|
|
||||||
"area_prepared",
|
|
||||||
GTK_SIGNAL_FUNC(progressive_prepared_callback),
|
|
||||||
&rgb_window,
|
|
||||||
NULL, FALSE, FALSE);
|
|
||||||
|
|
||||||
g_signal_connect_data(G_OBJECT(pixbuf_loader),
|
|
||||||
"area_updated",
|
|
||||||
GTK_SIGNAL_FUNC(progressive_updated_callback),
|
|
||||||
&rgb_window,
|
|
||||||
NULL, FALSE, FALSE);
|
|
||||||
|
|
||||||
|
|
||||||
status.imagefile = fopen (argv[1], "r");
|
|
||||||
g_assert (status.imagefile != NULL);
|
|
||||||
|
|
||||||
status.readlen = readlen;
|
|
||||||
|
|
||||||
status.timeout = gtk_timeout_add(100, update_timeout, &status);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found_valid)
|
|
||||||
gtk_main ();
|
gtk_main ();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
2001-04-20 Havoc Pennington <hp@redhat.com>
|
2001-04-26 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* gtk/tmpl/gtkimage.sgml: document GtkImageType
|
||||||
|
|
||||||
|
* gtk/gtk-sections.txt: GtkImageType is public
|
||||||
|
|
||||||
* gdk/tmpl/images.sgml: add warning about gtk_image_new_bitmap
|
* gdk/tmpl/images.sgml: add warning about gtk_image_new_bitmap
|
||||||
|
|
||||||
|
@ -2,15 +2,17 @@
|
|||||||
Animations
|
Animations
|
||||||
|
|
||||||
<!-- ##### SECTION Short_Description ##### -->
|
<!-- ##### SECTION Short_Description ##### -->
|
||||||
Animations as multi-frame structures.
|
Animated images.
|
||||||
|
|
||||||
<!-- ##### SECTION Long_Description ##### -->
|
<!-- ##### SECTION Long_Description ##### -->
|
||||||
<para>
|
<para>
|
||||||
The &gdk-pixbuf; library provides a simple mechanism to load and
|
The &gdk-pixbuf; library provides a simple mechanism to load and represent
|
||||||
represent animations, primarily animated GIF files. Animations
|
animations. An animation is conceptually a series of frames to be displayed
|
||||||
are represented as lists of #GdkPixbufFrame structures. Each
|
over time. Each frame is the same size. The animation may not be represented
|
||||||
frame structure contains a #GdkPixbuf structure and information
|
as a series of frames internally; for example, it may be stored as a
|
||||||
about the frame's overlay mode and duration.
|
sprite and instructions for moving the sprite around a background. To display
|
||||||
|
an animation you don't need to understand its representation, however; you just
|
||||||
|
ask &gdk-pixbuf; what should be displayed at a given point in time.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<!-- ##### SECTION See_Also ##### -->
|
<!-- ##### SECTION See_Also ##### -->
|
||||||
@ -18,34 +20,9 @@ Animations as multi-frame structures.
|
|||||||
#GdkPixbufLoader
|
#GdkPixbufLoader
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<!-- ##### ENUM GdkPixbufFrameAction ##### -->
|
|
||||||
<para>
|
|
||||||
Each animation frame can have several things happen to it when the
|
|
||||||
next frame is displayed. The #GdkPixbufFrameAction determines
|
|
||||||
this. These are essentially the overlay modes supported by GIF
|
|
||||||
animations.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@GDK_PIXBUF_FRAME_RETAIN: The previous image should remain displayed,
|
|
||||||
and will potentially be occluded by the new frame.
|
|
||||||
@GDK_PIXBUF_FRAME_DISPOSE: The animation will be reverted to the state
|
|
||||||
before the frame was shown.
|
|
||||||
@GDK_PIXBUF_FRAME_REVERT: The animation will be reverted to the first
|
|
||||||
frame.
|
|
||||||
|
|
||||||
<!-- ##### STRUCT GdkPixbufFrame ##### -->
|
|
||||||
<para>
|
|
||||||
This structure describes a frame in a #GdkPixbufAnimation. Each
|
|
||||||
frame consists of a #GdkPixbuf, an offset of the frame within the
|
|
||||||
animation's bounding box, a duration, and an overlay mode or
|
|
||||||
action.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### STRUCT GdkPixbufAnimation ##### -->
|
<!-- ##### STRUCT GdkPixbufAnimation ##### -->
|
||||||
<para>
|
<para>
|
||||||
This structure describes an animation, which is represented as a
|
This object describes an animation.
|
||||||
list of #GdkPixbufFrame structures.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
|
||||||
@ -76,15 +53,6 @@ frame.
|
|||||||
@animation:
|
@animation:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gdk_pixbuf_animation_get_frames ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@animation:
|
|
||||||
@Returns:
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gdk_pixbuf_animation_get_width ##### -->
|
<!-- ##### FUNCTION gdk_pixbuf_animation_get_width ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
@ -94,15 +62,6 @@ frame.
|
|||||||
@Returns:
|
@Returns:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gdk_pixbuf_animation_get_num_frames ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@animation:
|
|
||||||
@Returns:
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gdk_pixbuf_animation_get_height ##### -->
|
<!-- ##### FUNCTION gdk_pixbuf_animation_get_height ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
@ -112,70 +71,3 @@ frame.
|
|||||||
@Returns:
|
@Returns:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gdk_pixbuf_frame_copy ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@src:
|
|
||||||
@Returns:
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gdk_pixbuf_frame_free ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@frame:
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gdk_pixbuf_frame_get_pixbuf ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@frame:
|
|
||||||
@Returns:
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gdk_pixbuf_frame_get_action ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@frame:
|
|
||||||
@Returns:
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gdk_pixbuf_frame_get_y_offset ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@frame:
|
|
||||||
@Returns:
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gdk_pixbuf_frame_get_delay_time ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@frame:
|
|
||||||
@Returns:
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gdk_pixbuf_frame_get_x_offset ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@frame:
|
|
||||||
@Returns: <!--
|
|
||||||
Local variables:
|
|
||||||
mode: sgml
|
|
||||||
sgml-parent-document: ("../gdk-pixbuf.sgml" "book" "refsect2" "")
|
|
||||||
End:
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,15 +132,6 @@ Application-driven progressive image loading.
|
|||||||
@Returns:
|
@Returns:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### SIGNAL GdkPixbufLoader::animation-done ##### -->
|
|
||||||
<para>
|
|
||||||
This signal is emitted when an animation is done loading.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@gdkpixbufloader: the object which received the signal.
|
|
||||||
<!-- # Unused Parameters # -->
|
|
||||||
@loader: Loader which emitted the signal.
|
|
||||||
|
|
||||||
<!-- ##### SIGNAL GdkPixbufLoader::area-prepared ##### -->
|
<!-- ##### SIGNAL GdkPixbufLoader::area-prepared ##### -->
|
||||||
<para>
|
<para>
|
||||||
This signal is emitted when the pixbuf loader has been fed the
|
This signal is emitted when the pixbuf loader has been fed the
|
||||||
@ -194,15 +185,3 @@ sgml-parent-document: ("../gdk-pixbuf.sgml" "book" "refsect2" "")
|
|||||||
End:
|
End:
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- ##### SIGNAL GdkPixbufLoader::frame-done ##### -->
|
|
||||||
<para>
|
|
||||||
This signal is emitted when a frame is done loading. It will be
|
|
||||||
emitted for each frame in an animation data stream.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@gdkpixbufloader: the object which received the signal.
|
|
||||||
@arg1:
|
|
||||||
<!-- # Unused Parameters # -->
|
|
||||||
@loader: Loader which emitted the signal.
|
|
||||||
@frame: Frame which just completed loading.
|
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ Module Interface
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
@pixbuf:
|
@pixbuf:
|
||||||
|
@anim:
|
||||||
@user_data:
|
@user_data:
|
||||||
|
|
||||||
|
|
||||||
@ -44,24 +45,6 @@ Module Interface
|
|||||||
@user_data:
|
@user_data:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### USER_FUNCTION ModuleFrameDoneNotifyFunc ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@frame:
|
|
||||||
@user_data:
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### USER_FUNCTION ModuleAnimationDoneNotifyFunc ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@pixbuf:
|
|
||||||
@user_data:
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### STRUCT GdkPixbufModule ##### -->
|
<!-- ##### STRUCT GdkPixbufModule ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
|
@ -967,6 +967,7 @@ GTK_HSEPARATOR_GET_CLASS
|
|||||||
<FILE>gtkimage</FILE>
|
<FILE>gtkimage</FILE>
|
||||||
<TITLE>GtkImage</TITLE>
|
<TITLE>GtkImage</TITLE>
|
||||||
GtkImage
|
GtkImage
|
||||||
|
GtkImageType
|
||||||
gtk_image_get_icon_set
|
gtk_image_get_icon_set
|
||||||
gtk_image_get_image
|
gtk_image_get_image
|
||||||
gtk_image_get_pixbuf
|
gtk_image_get_pixbuf
|
||||||
@ -1002,7 +1003,6 @@ GtkImageImageData
|
|||||||
GtkImagePixbufData
|
GtkImagePixbufData
|
||||||
GtkImagePixmapData
|
GtkImagePixmapData
|
||||||
GtkImageStockData
|
GtkImageStockData
|
||||||
GtkImageType
|
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
|
@ -1621,19 +1621,3 @@ fundamental type.
|
|||||||
@window:
|
@window:
|
||||||
@Returns:
|
@Returns:
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_window_set_decorations_hint ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@window:
|
|
||||||
@decorations:
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_window_set_functions_hint ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@window:
|
|
||||||
@functions:
|
|
||||||
|
|
||||||
|
@ -28,6 +28,24 @@ below.
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ##### ENUM GtkImageType ##### -->
|
||||||
|
<para>
|
||||||
|
Describes the representation stored by a #GtkImage. If you want to get the image
|
||||||
|
from the widget, you can only get the currently-stored representation. e.g. if
|
||||||
|
the gtk_image_get_storage_type() returns #GTK_IMAGE_PIXBUF, then you can call
|
||||||
|
gtk_image_get_pixbuf() but not gtk_image_get_stock(). For empty images, you can
|
||||||
|
request any storage type (call any of the "get" functions), but they will all
|
||||||
|
return %NULL values.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
@GTK_IMAGE_EMPTY: there is no image displayed by the widget
|
||||||
|
@GTK_IMAGE_PIXMAP: the widget contains a #GdkPixmap
|
||||||
|
@GTK_IMAGE_IMAGE: the widget contains a #GdkImage
|
||||||
|
@GTK_IMAGE_PIXBUF: the widget contains a #GdkPixbuf
|
||||||
|
@GTK_IMAGE_STOCK: the widget contains a stock icon name
|
||||||
|
@GTK_IMAGE_ICON_SET: the widget contains a #GtkIconSet
|
||||||
|
@GTK_IMAGE_ANIMATION:
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_image_get_icon_set ##### -->
|
<!-- ##### FUNCTION gtk_image_get_icon_set ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
|
@ -387,7 +387,6 @@ can define other sizes.
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
It's also possible to use custom icons for a given state, for example:
|
It's also possible to use custom icons for a given state, for example:
|
||||||
You can specify custom icons for specific sizes, as follows:
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
stock["my-stock-item"] =
|
stock["my-stock-item"] =
|
||||||
{
|
{
|
||||||
@ -496,6 +495,7 @@ This can later be composited together with other
|
|||||||
#GtkRcStyle structures to form a #GtkStyle.
|
#GtkRcStyle structures to form a #GtkStyle.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
@parent_instance:
|
||||||
@name:
|
@name:
|
||||||
@bg_pixmap_name:
|
@bg_pixmap_name:
|
||||||
@font_desc:
|
@font_desc:
|
||||||
|
@ -43,7 +43,9 @@ slider.</entry>
|
|||||||
|
|
||||||
<!-- ##### FUNCTION gtk_scale_set_digits ##### -->
|
<!-- ##### FUNCTION gtk_scale_set_digits ##### -->
|
||||||
<para>
|
<para>
|
||||||
Sets the number of decimal places that are displayed in the value.
|
Sets the number of decimal places that are displayed in the value. Also causes
|
||||||
|
the value of the adjustment to be rounded off to this number of digits, so the
|
||||||
|
retrieved value matches the value the user saw.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@scale: a #GtkScale.
|
@scale: a #GtkScale.
|
||||||
@ -80,6 +82,15 @@ string.
|
|||||||
@Returns: the maximum width needed to display the value string.
|
@Returns: the maximum width needed to display the value string.
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ##### SIGNAL GtkScale::format-value ##### -->
|
||||||
|
<para>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
@scale: the object which received the signal.
|
||||||
|
@arg1:
|
||||||
|
@Returns:
|
||||||
|
|
||||||
<!-- ##### ARG GtkScale:digits ##### -->
|
<!-- ##### ARG GtkScale:digits ##### -->
|
||||||
<para>
|
<para>
|
||||||
The number of decimal places that are displayed in the value.
|
The number of decimal places that are displayed in the value.
|
||||||
|
@ -289,7 +289,7 @@ you don't want a return value.
|
|||||||
the callbacks.
|
the callbacks.
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_lookup ##### -->
|
<!-- ##### MACRO gtk_signal_lookup ##### -->
|
||||||
<para>
|
<para>
|
||||||
Given the name of the signal and the type of object it connects
|
Given the name of the signal and the type of object it connects
|
||||||
to, get the signal's identifying integer. Emitting the signal
|
to, get the signal's identifying integer. Emitting the signal
|
||||||
@ -304,7 +304,7 @@ It also tries the ancestors of the given type.
|
|||||||
@Returns: the signal's identifying number, or 0 if no signal was found.
|
@Returns: the signal's identifying number, or 0 if no signal was found.
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_name ##### -->
|
<!-- ##### MACRO gtk_signal_name ##### -->
|
||||||
<para>
|
<para>
|
||||||
Given the signal's identifier, find its name.
|
Given the signal's identifier, find its name.
|
||||||
</para>
|
</para>
|
||||||
@ -381,7 +381,7 @@ an array of GtkArgs instead of using C's varargs mechanism.
|
|||||||
followed by one which is a pointer to the return type.
|
followed by one which is a pointer to the return type.
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_emit_stop ##### -->
|
<!-- ##### MACRO gtk_signal_emit_stop ##### -->
|
||||||
<para>
|
<para>
|
||||||
This function aborts a signal's current emission.
|
This function aborts a signal's current emission.
|
||||||
</para>
|
</para>
|
||||||
@ -415,7 +415,7 @@ except it will lookup the signal id for you.
|
|||||||
@name: the name of the signal you wish to stop.
|
@name: the name of the signal you wish to stop.
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_connect ##### -->
|
<!-- ##### MACRO gtk_signal_connect ##### -->
|
||||||
<para>
|
<para>
|
||||||
Attach a function pointer and user data to a signal for
|
Attach a function pointer and user data to a signal for
|
||||||
a particular object.
|
a particular object.
|
||||||
@ -467,7 +467,7 @@ is getting pressed, this is that button.
|
|||||||
@d:
|
@d:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_connect_after ##### -->
|
<!-- ##### MACRO gtk_signal_connect_after ##### -->
|
||||||
<para>
|
<para>
|
||||||
Attach a function pointer and user data to a signal
|
Attach a function pointer and user data to a signal
|
||||||
so that this handler will be called after the other handlers.
|
so that this handler will be called after the other handlers.
|
||||||
@ -485,7 +485,7 @@ so that this handler will be called after the other handlers.
|
|||||||
@d:
|
@d:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_connect_object ##### -->
|
<!-- ##### MACRO gtk_signal_connect_object ##### -->
|
||||||
<para>
|
<para>
|
||||||
This function is for registering a callback that will
|
This function is for registering a callback that will
|
||||||
call another object's callback. That is,
|
call another object's callback. That is,
|
||||||
@ -520,7 +520,7 @@ really pass any gpointer as the #slot_object .)
|
|||||||
@d:
|
@d:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_connect_object_after ##### -->
|
<!-- ##### MACRO gtk_signal_connect_object_after ##### -->
|
||||||
<para>
|
<para>
|
||||||
Attach a signal hook to a signal, passing in an alternate
|
Attach a signal hook to a signal, passing in an alternate
|
||||||
object as the first parameter, and guaranteeing
|
object as the first parameter, and guaranteeing
|
||||||
@ -626,7 +626,7 @@ should signal the removal of this signal.
|
|||||||
@name: name of the signal.
|
@name: name of the signal.
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_disconnect ##### -->
|
<!-- ##### MACRO gtk_signal_disconnect ##### -->
|
||||||
<para>
|
<para>
|
||||||
Destroy a user-defined handler connection.
|
Destroy a user-defined handler connection.
|
||||||
</para>
|
</para>
|
||||||
@ -635,7 +635,7 @@ Destroy a user-defined handler connection.
|
|||||||
@handler_id: the connection id.
|
@handler_id: the connection id.
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_disconnect_by_func ##### -->
|
<!-- ##### MACRO gtk_signal_disconnect_by_func ##### -->
|
||||||
<para>
|
<para>
|
||||||
Destroy all connections for a particular object, with
|
Destroy all connections for a particular object, with
|
||||||
the given function-pointer and user-data.
|
the given function-pointer and user-data.
|
||||||
@ -650,7 +650,7 @@ the given function-pointer and user-data.
|
|||||||
@d:
|
@d:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_disconnect_by_data ##### -->
|
<!-- ##### MACRO gtk_signal_disconnect_by_data ##### -->
|
||||||
<para>
|
<para>
|
||||||
Destroy all connections for a particular object, with
|
Destroy all connections for a particular object, with
|
||||||
the given user-data.
|
the given user-data.
|
||||||
@ -663,7 +663,7 @@ the given user-data.
|
|||||||
@d:
|
@d:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_handler_block ##### -->
|
<!-- ##### MACRO gtk_signal_handler_block ##### -->
|
||||||
<para>
|
<para>
|
||||||
Prevent an user-defined handler from being invoked. All other
|
Prevent an user-defined handler from being invoked. All other
|
||||||
signal processing will go on as normal, but this particular
|
signal processing will go on as normal, but this particular
|
||||||
@ -674,7 +674,7 @@ handler will ignore it.
|
|||||||
@handler_id: the connection id.
|
@handler_id: the connection id.
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_handler_block_by_func ##### -->
|
<!-- ##### MACRO gtk_signal_handler_block_by_func ##### -->
|
||||||
<para>
|
<para>
|
||||||
Prevent a user-defined handler from being invoked, by reference to
|
Prevent a user-defined handler from being invoked, by reference to
|
||||||
the user-defined handler's function pointer and user data. (It may result in
|
the user-defined handler's function pointer and user data. (It may result in
|
||||||
@ -690,7 +690,7 @@ multiple hooks being blocked, if you've called connect multiple times.)
|
|||||||
@d:
|
@d:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_handler_block_by_data ##### -->
|
<!-- ##### MACRO gtk_signal_handler_block_by_data ##### -->
|
||||||
<para>
|
<para>
|
||||||
Prevent all user-defined handlers with a certain user data from being invoked.
|
Prevent all user-defined handlers with a certain user data from being invoked.
|
||||||
</para>
|
</para>
|
||||||
@ -702,7 +702,7 @@ Prevent all user-defined handlers with a certain user data from being invoked.
|
|||||||
@d:
|
@d:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_handler_unblock ##### -->
|
<!-- ##### MACRO gtk_signal_handler_unblock ##### -->
|
||||||
<para>
|
<para>
|
||||||
Undo a block, by connection id. Note that undoing a block doesn't
|
Undo a block, by connection id. Note that undoing a block doesn't
|
||||||
necessarily make the hook callable, because if you block a
|
necessarily make the hook callable, because if you block a
|
||||||
@ -714,7 +714,7 @@ hook twice, you must unblock it twice.
|
|||||||
gtk_signal_connect(), etc.
|
gtk_signal_connect(), etc.
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_handler_unblock_by_func ##### -->
|
<!-- ##### MACRO gtk_signal_handler_unblock_by_func ##### -->
|
||||||
<para>
|
<para>
|
||||||
Undo a block, by function pointer and data.
|
Undo a block, by function pointer and data.
|
||||||
Note that undoing a block doesn't
|
Note that undoing a block doesn't
|
||||||
@ -731,7 +731,7 @@ hook twice, you must unblock it twice.
|
|||||||
@d:
|
@d:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_handler_unblock_by_data ##### -->
|
<!-- ##### MACRO gtk_signal_handler_unblock_by_data ##### -->
|
||||||
<para>
|
<para>
|
||||||
Undo block(s), to all signals for a particular object
|
Undo block(s), to all signals for a particular object
|
||||||
with a particular user-data pointer
|
with a particular user-data pointer
|
||||||
@ -744,7 +744,7 @@ with a particular user-data pointer
|
|||||||
@d:
|
@d:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_handler_pending ##### -->
|
<!-- ##### MACRO gtk_signal_handler_pending ##### -->
|
||||||
<para>
|
<para>
|
||||||
Returns a connection id corresponding to a given signal id and object.
|
Returns a connection id corresponding to a given signal id and object.
|
||||||
</para>
|
</para>
|
||||||
@ -766,7 +766,7 @@ handler.
|
|||||||
@b:
|
@b:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_signal_handler_pending_by_func ##### -->
|
<!-- ##### MACRO gtk_signal_handler_pending_by_func ##### -->
|
||||||
<para>
|
<para>
|
||||||
Returns a connection id corresponding to a given signal id, object, function
|
Returns a connection id corresponding to a given signal id, object, function
|
||||||
pointer and user data.
|
pointer and user data.
|
||||||
|
@ -41,6 +41,7 @@ Styles
|
|||||||
@mid:
|
@mid:
|
||||||
@text:
|
@text:
|
||||||
@base:
|
@base:
|
||||||
|
@text_aa:
|
||||||
@black:
|
@black:
|
||||||
@white:
|
@white:
|
||||||
@font:
|
@font:
|
||||||
@ -54,6 +55,7 @@ Styles
|
|||||||
@mid_gc:
|
@mid_gc:
|
||||||
@text_gc:
|
@text_gc:
|
||||||
@base_gc:
|
@base_gc:
|
||||||
|
@text_aa_gc:
|
||||||
@black_gc:
|
@black_gc:
|
||||||
@white_gc:
|
@white_gc:
|
||||||
@bg_pixmap:
|
@bg_pixmap:
|
||||||
@ -504,6 +506,7 @@ Styles
|
|||||||
@style:
|
@style:
|
||||||
@window:
|
@window:
|
||||||
@state_type:
|
@state_type:
|
||||||
|
@use_text:
|
||||||
@x:
|
@x:
|
||||||
@y:
|
@y:
|
||||||
@layout:
|
@layout:
|
||||||
@ -874,6 +877,7 @@ Styles
|
|||||||
@style:
|
@style:
|
||||||
@window:
|
@window:
|
||||||
@state_type:
|
@state_type:
|
||||||
|
@use_text:
|
||||||
@area:
|
@area:
|
||||||
@widget:
|
@widget:
|
||||||
@detail:
|
@detail:
|
||||||
|
@ -378,15 +378,6 @@ types related to the text widget and how they work together.
|
|||||||
@Returns:
|
@Returns:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_text_iter_is_first ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@iter:
|
|
||||||
@Returns:
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_text_iter_forward_char ##### -->
|
<!-- ##### FUNCTION gtk_text_iter_forward_char ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ Describes a type of line wrapping.
|
|||||||
@justification:
|
@justification:
|
||||||
@direction:
|
@direction:
|
||||||
@font:
|
@font:
|
||||||
|
@font_scale:
|
||||||
@left_margin:
|
@left_margin:
|
||||||
@indent:
|
@indent:
|
||||||
@right_margin:
|
@right_margin:
|
||||||
@ -279,6 +280,11 @@ Font as a #PangoFontDescription.
|
|||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<!-- ##### ARG GtkTextTag:scale ##### -->
|
||||||
|
<para>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
<!-- ##### ARG GtkTextTag:size-points ##### -->
|
<!-- ##### ARG GtkTextTag:size-points ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
@ -419,6 +425,11 @@ applies to the first character in a paragraph.
|
|||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<!-- ##### ARG GtkTextTag:scale-set ##### -->
|
||||||
|
<para>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
<!-- ##### ARG GtkTextTag:justification-set ##### -->
|
<!-- ##### ARG GtkTextTag:justification-set ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
|
@ -560,7 +560,7 @@ Create a new, unique type.
|
|||||||
@type_info: must not be null, and @type_info->type_name must also not be null.
|
@type_info: must not be null, and @type_info->type_name must also not be null.
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_type_name ##### -->
|
<!-- ##### MACRO gtk_type_name ##### -->
|
||||||
<para>
|
<para>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -568,7 +568,7 @@ Create a new, unique type.
|
|||||||
@Returns: a pointer to the name of a type, or NULL if it has none.
|
@Returns: a pointer to the name of a type, or NULL if it has none.
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_type_from_name ##### -->
|
<!-- ##### MACRO gtk_type_from_name ##### -->
|
||||||
<para>
|
<para>
|
||||||
Get the internal representation of a type given its name.
|
Get the internal representation of a type given its name.
|
||||||
</para>
|
</para>
|
||||||
@ -577,7 +577,7 @@ Get the internal representation of a type given its name.
|
|||||||
@Returns: a GtkType
|
@Returns: a GtkType
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_type_parent ##### -->
|
<!-- ##### MACRO gtk_type_parent ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
@ -608,7 +608,7 @@ has all the proper initializers called.
|
|||||||
@Returns: gpointer to a GtkTypeObject
|
@Returns: gpointer to a GtkTypeObject
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_type_is_a ##### -->
|
<!-- ##### MACRO gtk_type_is_a ##### -->
|
||||||
<para>
|
<para>
|
||||||
Look in the type hierarchy to see if @type has @is_a_type among its
|
Look in the type hierarchy to see if @type has @is_a_type among its
|
||||||
ancestors. Do so with a simple lookup, not a loop.
|
ancestors. Do so with a simple lookup, not a loop.
|
||||||
|
@ -393,6 +393,15 @@ it's larger
|
|||||||
@setting:
|
@setting:
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ##### FUNCTION gtk_window_set_decorations_hint ##### -->
|
||||||
|
<para>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
@window:
|
||||||
|
@decorations:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_window_set_frame_dimensions ##### -->
|
<!-- ##### FUNCTION gtk_window_set_frame_dimensions ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
@ -405,6 +414,15 @@ it's larger
|
|||||||
@bottom:
|
@bottom:
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ##### FUNCTION gtk_window_set_functions_hint ##### -->
|
||||||
|
<para>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
@window:
|
||||||
|
@functions:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gtk_window_set_has_frame ##### -->
|
<!-- ##### FUNCTION gtk_window_set_has_frame ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
|
@ -1,3 +1,32 @@
|
|||||||
|
2001-05-04 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
|
* pixops/pixops.c (pixops_process): merge fix from stable: Patch
|
||||||
|
from hoshem@mel.comcen.com.au to fix nonzero X offsets. Fixes
|
||||||
|
bug #50371.
|
||||||
|
|
||||||
|
* gdk-pixbuf/pixops/pixops.c (pixops_composite_nearest): merge
|
||||||
|
from stable: Patch from OKADA Mitsuru <m-okada@fjb.co.jp> to fix
|
||||||
|
confusion of using "src" instead of "p".
|
||||||
|
(pixops_composite_color_nearest): Use a more accurate (and
|
||||||
|
correct, to begin with) compositing method. This cures checks
|
||||||
|
showing through on images with no alpha.
|
||||||
|
|
||||||
|
* gdk-pixbuf.c (gdk_pixbuf_fill): fix bug that left some trailing
|
||||||
|
bytes unfilled.
|
||||||
|
|
||||||
|
* gdk-pixbuf-io.h: fix UpdatedNotifyFunc to use signed ints
|
||||||
|
|
||||||
|
* gdk-pixbuf-loader.h (struct _GdkPixbufLoaderClass): Change
|
||||||
|
area_updated signal to use signed ints. Removed animation-related
|
||||||
|
signals.
|
||||||
|
|
||||||
|
* io-gif.c, io-gif-animation.h, io-gif-animation.c: Massive
|
||||||
|
rewrite action
|
||||||
|
|
||||||
|
* gdk-pixbuf-animation.c: Add GdkPixbufAnimationIter to abstract
|
||||||
|
all the pesky details. Remove old frame-based API. Make
|
||||||
|
GdkPixbufAnimation an abstract base class, derived by the loaders.
|
||||||
|
|
||||||
Sun Apr 22 15:51:32 2001 Owen Taylor <otaylor@redhat.com>
|
Sun Apr 22 15:51:32 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* Makefile.am (LDADDS): Add $(MATH_LIB).
|
* Makefile.am (LDADDS): Add $(MATH_LIB).
|
||||||
|
@ -32,8 +32,8 @@ libpixbufloader_xpm_la_LIBADD =
|
|||||||
#
|
#
|
||||||
# The GIF loader
|
# The GIF loader
|
||||||
#
|
#
|
||||||
libpixbufloader_static_gif_la_SOURCES = io-gif.c
|
libpixbufloader_static_gif_la_SOURCES = io-gif.c io-gif-animation.c io-gif-animation.h
|
||||||
libpixbufloader_gif_la_SOURCES = io-gif.c
|
libpixbufloader_gif_la_SOURCES = io-gif.c io-gif-animation.c io-gif-animation.h
|
||||||
libpixbufloader_gif_la_LDFLAGS = -avoid-version -module
|
libpixbufloader_gif_la_LDFLAGS = -avoid-version -module
|
||||||
libpixbufloader_gif_la_LIBADD =
|
libpixbufloader_gif_la_LIBADD =
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
|
||||||
/* GdkPixbuf library - Simple animation support
|
/* GdkPixbuf library - Simple animation support
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999 The Free Software Foundation
|
* Copyright (C) 1999 The Free Software Foundation
|
||||||
@ -26,12 +27,59 @@
|
|||||||
#include "gdk-pixbuf-io.h"
|
#include "gdk-pixbuf-io.h"
|
||||||
#include "gdk-pixbuf-private.h"
|
#include "gdk-pixbuf-private.h"
|
||||||
|
|
||||||
static void gdk_pixbuf_animation_class_init (GdkPixbufAnimationClass *klass);
|
typedef struct _GdkPixbufNonAnim GdkPixbufNonAnim;
|
||||||
static void gdk_pixbuf_animation_finalize (GObject *object);
|
typedef struct _GdkPixbufNonAnimClass GdkPixbufNonAnimClass;
|
||||||
|
|
||||||
|
#define GDK_TYPE_PIXBUF_NON_ANIM (gdk_pixbuf_non_anim_get_type ())
|
||||||
|
#define GDK_PIXBUF_NON_ANIM(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_NON_ANIM, GdkPixbufNonAnim))
|
||||||
|
#define GDK_IS_PIXBUF_NON_ANIM(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_NON_ANIM))
|
||||||
|
|
||||||
|
#define GDK_PIXBUF_NON_ANIM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_NON_ANIM, GdkPixbufNonAnimClass))
|
||||||
|
#define GDK_IS_PIXBUF_NON_ANIM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_NON_ANIM))
|
||||||
|
#define GDK_PIXBUF_NON_ANIM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_NON_ANIM, GdkPixbufNonAnimClass))
|
||||||
|
|
||||||
|
/* Private part of the GdkPixbufNonAnim structure */
|
||||||
|
struct _GdkPixbufNonAnim {
|
||||||
|
GdkPixbufAnimation parent_instance;
|
||||||
|
|
||||||
|
GdkPixbuf *pixbuf;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GdkPixbufNonAnimClass {
|
||||||
|
GdkPixbufAnimationClass parent_class;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
static GType gdk_pixbuf_non_anim_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static gpointer parent_class;
|
typedef struct _GdkPixbufNonAnimIter GdkPixbufNonAnimIter;
|
||||||
|
typedef struct _GdkPixbufNonAnimIterClass GdkPixbufNonAnimIterClass;
|
||||||
|
|
||||||
|
|
||||||
|
#define GDK_TYPE_PIXBUF_NON_ANIM_ITER (gdk_pixbuf_non_anim_iter_get_type ())
|
||||||
|
#define GDK_PIXBUF_NON_ANIM_ITER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_NON_ANIM_ITER, GdkPixbufNonAnimIter))
|
||||||
|
#define GDK_IS_PIXBUF_NON_ANIM_ITER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_NON_ANIM_ITER))
|
||||||
|
|
||||||
|
#define GDK_PIXBUF_NON_ANIM_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_NON_ANIM_ITER, GdkPixbufNonAnimIterClass))
|
||||||
|
#define GDK_IS_PIXBUF_NON_ANIM_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_NON_ANIM_ITER))
|
||||||
|
#define GDK_PIXBUF_NON_ANIM_ITER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_NON_ANIM_ITER, GdkPixbufNonAnimIterClass))
|
||||||
|
|
||||||
|
struct _GdkPixbufNonAnimIter {
|
||||||
|
GdkPixbufAnimationIter parent_instance;
|
||||||
|
|
||||||
|
GdkPixbufNonAnim *non_anim;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GdkPixbufNonAnimIterClass {
|
||||||
|
GdkPixbufAnimationIterClass parent_class;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
static GType gdk_pixbuf_non_anim_iter_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GType
|
GType
|
||||||
gdk_pixbuf_animation_get_type (void)
|
gdk_pixbuf_animation_get_type (void)
|
||||||
@ -43,7 +91,7 @@ gdk_pixbuf_animation_get_type (void)
|
|||||||
sizeof (GdkPixbufAnimationClass),
|
sizeof (GdkPixbufAnimationClass),
|
||||||
(GBaseInitFunc) NULL,
|
(GBaseInitFunc) NULL,
|
||||||
(GBaseFinalizeFunc) NULL,
|
(GBaseFinalizeFunc) NULL,
|
||||||
(GClassInitFunc) gdk_pixbuf_animation_class_init,
|
(GClassInitFunc) NULL,
|
||||||
NULL, /* class_finalize */
|
NULL, /* class_finalize */
|
||||||
NULL, /* class_data */
|
NULL, /* class_data */
|
||||||
sizeof (GdkPixbufAnimation),
|
sizeof (GdkPixbufAnimation),
|
||||||
@ -59,35 +107,6 @@ gdk_pixbuf_animation_get_type (void)
|
|||||||
return object_type;
|
return object_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gdk_pixbuf_animation_class_init (GdkPixbufAnimationClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
||||||
|
|
||||||
parent_class = g_type_class_peek_parent (klass);
|
|
||||||
|
|
||||||
object_class->finalize = gdk_pixbuf_animation_finalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gdk_pixbuf_animation_finalize (GObject *object)
|
|
||||||
{
|
|
||||||
GdkPixbufAnimation *animation = GDK_PIXBUF_ANIMATION (object);
|
|
||||||
|
|
||||||
GList *l;
|
|
||||||
GdkPixbufFrame *frame;
|
|
||||||
|
|
||||||
for (l = animation->frames; l; l = l->next) {
|
|
||||||
frame = l->data;
|
|
||||||
gdk_pixbuf_unref (frame->pixbuf);
|
|
||||||
g_free (frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_list_free (animation->frames);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,7 +173,6 @@ gdk_pixbuf_animation_new_from_file (const char *filename,
|
|||||||
|
|
||||||
if (image_module->load_animation == NULL) {
|
if (image_module->load_animation == NULL) {
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
GdkPixbufFrame *frame;
|
|
||||||
|
|
||||||
/* Keep this logic in sync with gdk_pixbuf_new_from_file() */
|
/* Keep this logic in sync with gdk_pixbuf_new_from_file() */
|
||||||
|
|
||||||
@ -191,20 +209,9 @@ gdk_pixbuf_animation_new_from_file (const char *filename,
|
|||||||
if (pixbuf == NULL)
|
if (pixbuf == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
frame = g_new (GdkPixbufFrame, 1);
|
animation = gdk_pixbuf_non_anim_new (pixbuf);
|
||||||
frame->pixbuf = pixbuf;
|
|
||||||
g_object_ref (G_OBJECT (frame->pixbuf));
|
|
||||||
frame->x_offset = 0;
|
|
||||||
frame->y_offset = 0;
|
|
||||||
frame->delay_time = -1;
|
|
||||||
frame->action = GDK_PIXBUF_FRAME_RETAIN;
|
|
||||||
|
|
||||||
animation = g_object_new (GDK_TYPE_PIXBUF_ANIMATION, NULL);
|
g_object_unref (G_OBJECT (pixbuf));
|
||||||
|
|
||||||
animation->n_frames = 1;
|
|
||||||
animation->frames = g_list_prepend (NULL, frame);
|
|
||||||
animation->width = gdk_pixbuf_get_width (pixbuf);
|
|
||||||
animation->height = gdk_pixbuf_get_height (pixbuf);
|
|
||||||
} else {
|
} else {
|
||||||
fseek (f, 0, SEEK_SET);
|
fseek (f, 0, SEEK_SET);
|
||||||
animation = (* image_module->load_animation) (f, error);
|
animation = (* image_module->load_animation) (f, error);
|
||||||
@ -261,6 +268,46 @@ gdk_pixbuf_animation_unref (GdkPixbufAnimation *animation)
|
|||||||
g_object_unref (G_OBJECT (animation));
|
g_object_unref (G_OBJECT (animation));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_pixbuf_animation_is_static_image:
|
||||||
|
* @animation: a #GdkPixbufAnimation
|
||||||
|
*
|
||||||
|
* If you load a file with gdk_pixbuf_animation_new_from_file() and it turns
|
||||||
|
* out to be a plain, unanimated image, then this function will return
|
||||||
|
* %TRUE. Use gdk_pixbuf_animation_get_static_image() to retrieve
|
||||||
|
* the image.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if the "animation" was really just an image
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
gdk_pixbuf_animation_is_static_image (GdkPixbufAnimation *animation)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), FALSE);
|
||||||
|
|
||||||
|
return GDK_PIXBUF_ANIMATION_GET_CLASS (animation)->is_static_image (animation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_pixbuf_animation_get_static_image:
|
||||||
|
* @animation: a #GdkPixbufAnimation
|
||||||
|
*
|
||||||
|
* If an animation is really just a plain image (has only one frame),
|
||||||
|
* this function returns that image. If the animation is an animation,
|
||||||
|
* this function returns a reasonable thing to display as a static
|
||||||
|
* unanimated image, which might be the first frame, or something more
|
||||||
|
* sophisticated. If an animation hasn't loaded any frames yet, this
|
||||||
|
* function will return %NULL.
|
||||||
|
*
|
||||||
|
* Return value: unanimated image representing the animation
|
||||||
|
**/
|
||||||
|
GdkPixbuf*
|
||||||
|
gdk_pixbuf_animation_get_static_image (GdkPixbufAnimation *animation)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), NULL);
|
||||||
|
|
||||||
|
return GDK_PIXBUF_ANIMATION_GET_CLASS (animation)->get_static_image (animation);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gdk_pixbuf_animation_get_width:
|
* gdk_pixbuf_animation_get_width:
|
||||||
* @animation: An animation.
|
* @animation: An animation.
|
||||||
@ -272,9 +319,16 @@ gdk_pixbuf_animation_unref (GdkPixbufAnimation *animation)
|
|||||||
int
|
int
|
||||||
gdk_pixbuf_animation_get_width (GdkPixbufAnimation *animation)
|
gdk_pixbuf_animation_get_width (GdkPixbufAnimation *animation)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (animation != NULL, -1);
|
int width;
|
||||||
|
|
||||||
return animation->width;
|
g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), 0);
|
||||||
|
|
||||||
|
width = 0;
|
||||||
|
GDK_PIXBUF_ANIMATION_GET_CLASS (animation)->get_size (animation,
|
||||||
|
&width, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -288,179 +342,444 @@ gdk_pixbuf_animation_get_width (GdkPixbufAnimation *animation)
|
|||||||
int
|
int
|
||||||
gdk_pixbuf_animation_get_height (GdkPixbufAnimation *animation)
|
gdk_pixbuf_animation_get_height (GdkPixbufAnimation *animation)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (animation != NULL, -1);
|
int height;
|
||||||
|
|
||||||
return animation->height;
|
g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), 0);
|
||||||
|
|
||||||
|
height = 0;
|
||||||
|
GDK_PIXBUF_ANIMATION_GET_CLASS (animation)->get_size (animation,
|
||||||
|
NULL, &height);
|
||||||
|
|
||||||
|
|
||||||
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gdk_pixbuf_animation_get_num_frames:
|
|
||||||
* @animation: An animation.
|
|
||||||
*
|
|
||||||
* Queries the number of frames in a pixbuf animation.
|
|
||||||
*
|
|
||||||
* Return value: Number of frames in the animation.
|
|
||||||
**/
|
|
||||||
int
|
|
||||||
gdk_pixbuf_animation_get_num_frames (GdkPixbufAnimation *animation)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (animation != NULL, -1);
|
|
||||||
|
|
||||||
return animation->n_frames;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gdk_pixbuf_animation_get_frames:
|
* gdk_pixbuf_animation_get_iter:
|
||||||
* @animation: An animation.
|
* @animation: a #GdkPixbufAnimation
|
||||||
|
* @start_time: time when the animation starts playing
|
||||||
*
|
*
|
||||||
* Queries the list of frames of an animation.
|
* Get an iterator for displaying an animation. The iterator provides
|
||||||
|
* the frames that should be displayed at a given time.
|
||||||
|
* It should be freed after use with g_object_unref().
|
||||||
*
|
*
|
||||||
* Return value: List of frames in the animation; this is a #GList of
|
* @start_time would normally come from g_get_current_time(), and
|
||||||
* #GdkPixbufFrame structures.
|
* marks the beginning of animation playback. After creating an
|
||||||
|
* iterator, you should immediately display the pixbuf returned by
|
||||||
|
* gdk_pixbuf_animation_iter_get_pixbuf(). Then, you should install a
|
||||||
|
* timeout (with g_timeout_add()) or by some other mechanism ensure
|
||||||
|
* that you'll update the image after
|
||||||
|
* gdk_pixbuf_animation_iter_get_delay_time() milliseconds. Each time
|
||||||
|
* the image is updated, you should reinstall the timeout with the new,
|
||||||
|
* possibly-changed delay time.
|
||||||
|
*
|
||||||
|
* As a shortcut, if @start_time is %NULL, the result of
|
||||||
|
* g_get_current_time() will be used automatically.
|
||||||
|
*
|
||||||
|
* To update the image (i.e. possibly change the result of
|
||||||
|
* gdk_pixbuf_animation_iter_get_pixbuf() to a new frame of the animation),
|
||||||
|
* call gdk_pixbuf_animation_iter_advance().
|
||||||
|
*
|
||||||
|
* If you're using #GdkPixbufLoader, in addition to updating the image
|
||||||
|
* after the delay time, you should also update it whenever you
|
||||||
|
* receive the area_updated signal and
|
||||||
|
* gdk_pixbuf_animation_iter_on_currently_loading_frame() returns
|
||||||
|
* %TRUE. In this case, the frame currently being fed into the loader
|
||||||
|
* has received new data, so needs to be refreshed. The delay time for
|
||||||
|
* a frame may also be modified after an area_updated signal, for
|
||||||
|
* example if the delay time for a frame is encoded in the data after
|
||||||
|
* the frame itself. So your timeout should be reinstalled after any
|
||||||
|
* area_updated signal.
|
||||||
|
*
|
||||||
|
* A delay time of -1 is possible, indicating "infinite."
|
||||||
|
*
|
||||||
|
* Return value: an iterator to move over the animation
|
||||||
**/
|
**/
|
||||||
GList *
|
GdkPixbufAnimationIter*
|
||||||
gdk_pixbuf_animation_get_frames (GdkPixbufAnimation *animation)
|
gdk_pixbuf_animation_get_iter (GdkPixbufAnimation *animation,
|
||||||
|
const GTimeVal *start_time)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (animation != NULL, NULL);
|
GTimeVal val;
|
||||||
|
|
||||||
return animation->frames;
|
g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), NULL);
|
||||||
|
|
||||||
|
|
||||||
|
if (start_time)
|
||||||
|
val = *start_time;
|
||||||
|
else
|
||||||
|
g_get_current_time (&val);
|
||||||
|
|
||||||
|
return GDK_PIXBUF_ANIMATION_GET_CLASS (animation)->get_iter (animation, &val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GType
|
||||||
|
gdk_pixbuf_animation_iter_get_type (void)
|
||||||
|
{
|
||||||
|
static GType object_type = 0;
|
||||||
|
|
||||||
|
if (!object_type) {
|
||||||
|
static const GTypeInfo object_info = {
|
||||||
|
sizeof (GdkPixbufAnimationIterClass),
|
||||||
|
(GBaseInitFunc) NULL,
|
||||||
|
(GBaseFinalizeFunc) NULL,
|
||||||
|
(GClassInitFunc) NULL,
|
||||||
|
NULL, /* class_finalize */
|
||||||
|
NULL, /* class_data */
|
||||||
|
sizeof (GdkPixbufAnimationIter),
|
||||||
|
0, /* n_preallocs */
|
||||||
|
(GInstanceInitFunc) NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
object_type = g_type_register_static (G_TYPE_OBJECT,
|
||||||
|
"GdkPixbufAnimationIter",
|
||||||
|
&object_info, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return object_type;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gdk_pixbuf_frame_get_pixbuf:
|
* gdk_pixbuf_animation_iter_get_delay_time:
|
||||||
* @frame: A pixbuf animation frame.
|
* @iter: an animation iterator
|
||||||
*
|
*
|
||||||
* Queries the pixbuf of an animation frame.
|
* Gets the number of milliseconds the current pixbuf should be displayed,
|
||||||
|
* or -1 if the current pixbuf should be displayed forever. g_timeout_add()
|
||||||
|
* conveniently takes a timeout in milliseconds, so you can use a timeout
|
||||||
|
* to schedule the next update.
|
||||||
*
|
*
|
||||||
* Return value: A pixbuf.
|
* Return value: delay time in milliseconds (thousandths of a second)
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
gdk_pixbuf_animation_iter_get_delay_time (GdkPixbufAnimationIter *iter)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION_ITER (iter), -1);
|
||||||
|
|
||||||
|
return GDK_PIXBUF_ANIMATION_ITER_GET_CLASS (iter)->get_delay_time (iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_pixbuf_animation_iter_get_pixbuf:
|
||||||
|
* @iter: an animation iterator
|
||||||
|
*
|
||||||
|
* Gets the current pixbuf which should be displayed; the pixbuf will
|
||||||
|
* be the same size as the animation itself
|
||||||
|
* (gdk_pixbuf_animation_get_width(),
|
||||||
|
* gdk_pixbuf_animation_get_height()). This pixbuf should be displayed
|
||||||
|
* for gdk_pixbuf_animation_get_delay_time() milliseconds. The caller
|
||||||
|
* of this function does not own a reference to the returned pixbuf;
|
||||||
|
* the returned pixbuf will become invalid when the iterator advances
|
||||||
|
* to the next frame, which may happen anytime you call
|
||||||
|
* gdk_pixbuf_animation_iter_advance(). Copy the pixbuf to keep it
|
||||||
|
* (don't just add a reference), as it may get recycled as you advance
|
||||||
|
* the iterator.
|
||||||
|
*
|
||||||
|
* Return value: the pixbuf to be displayed
|
||||||
**/
|
**/
|
||||||
GdkPixbuf*
|
GdkPixbuf*
|
||||||
gdk_pixbuf_frame_get_pixbuf (GdkPixbufFrame *frame)
|
gdk_pixbuf_animation_iter_get_pixbuf (GdkPixbufAnimationIter *iter)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (frame != NULL, NULL);
|
g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION_ITER (iter), NULL);
|
||||||
|
|
||||||
return frame->pixbuf;
|
return GDK_PIXBUF_ANIMATION_ITER_GET_CLASS (iter)->get_pixbuf (iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gdk_pixbuf_frame_get_x_offset:
|
* gdk_pixbuf_animation_iter_on_currently_loading_frame:
|
||||||
* @frame: A pixbuf animation frame.
|
* @iter: a #GdkPixbufAnimationIter
|
||||||
*
|
*
|
||||||
* Queries the X offset of an animation frame.
|
* Used to determine how to respond to the area_updated signal on
|
||||||
|
* #GdkPixbufLoader when loading an animation. area_updated is emitted
|
||||||
|
* for an area of the frame currently streaming in to the loader. So if
|
||||||
|
* you're on the currently loading frame, you need to redraw the screen for
|
||||||
|
* the updated area.
|
||||||
*
|
*
|
||||||
* Return value: X offset from the top left corner of the animation.
|
* Return value: %TRUE if the frame we're on is partially loaded, or the last frame
|
||||||
**/
|
**/
|
||||||
int
|
gboolean
|
||||||
gdk_pixbuf_frame_get_x_offset (GdkPixbufFrame *frame)
|
gdk_pixbuf_animation_iter_on_currently_loading_frame (GdkPixbufAnimationIter *iter)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (frame != NULL, -1);
|
g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION_ITER (iter), FALSE);
|
||||||
|
|
||||||
return frame->x_offset;
|
return GDK_PIXBUF_ANIMATION_ITER_GET_CLASS (iter)->on_currently_loading_frame (iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gdk_pixbuf_frame_get_y_offset:
|
* gdk_pixbuf_animation_iter_advance:
|
||||||
* @frame: A pixbuf animation frame.
|
* @iter: a #GdkPixbufAnimationIter
|
||||||
|
* @current_time: current time
|
||||||
*
|
*
|
||||||
* Queries the Y offset of an animation frame.
|
* Possibly advances an animation to a new frame. Chooses the frame based
|
||||||
|
* on the start time passed to gdk_pixbuf_animation_get_iter().
|
||||||
|
*
|
||||||
|
* @current_time would normally come from g_get_current_time(), and
|
||||||
|
* must be greater than or equal to the time passed to
|
||||||
|
* gdk_pixbuf_animation_get_iter(), and must increase or remain
|
||||||
|
* unchanged each time gdk_pixbuf_animation_iter_get_pixbuf() is
|
||||||
|
* called. That is, you can't go backward in time; animations only
|
||||||
|
* play forward.
|
||||||
|
*
|
||||||
|
* As a shortcut, pass %NULL for the current time and g_get_current_time()
|
||||||
|
* will be invoked on your behalf. So you only need to explicitly pass
|
||||||
|
* @current_time if you're doing something odd like playing the animation
|
||||||
|
* at double speed.
|
||||||
|
*
|
||||||
|
* If this function returns %FALSE, there's no need to update the animation
|
||||||
|
* display, assuming the display had been rendered prior to advancing;
|
||||||
|
* if %TRUE, you need to call gdk_animation_iter_get_pixbuf() and update the
|
||||||
|
* display with the new pixbuf.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the image may need updating
|
||||||
*
|
*
|
||||||
* Return value: Y offset from the top left corner of the animation.
|
|
||||||
**/
|
**/
|
||||||
int
|
gboolean
|
||||||
gdk_pixbuf_frame_get_y_offset (GdkPixbufFrame *frame)
|
gdk_pixbuf_animation_iter_advance (GdkPixbufAnimationIter *iter,
|
||||||
|
const GTimeVal *current_time)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (frame != NULL, -1);
|
GTimeVal val;
|
||||||
|
|
||||||
return frame->y_offset;
|
g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION_ITER (iter), FALSE);
|
||||||
|
|
||||||
|
if (current_time)
|
||||||
|
val = *current_time;
|
||||||
|
else
|
||||||
|
g_get_current_time (&val);
|
||||||
|
|
||||||
|
return GDK_PIXBUF_ANIMATION_ITER_GET_CLASS (iter)->advance (iter, &val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gdk_pixbuf_frame_get_delay_time:
|
|
||||||
* @frame: A pixbuf animation frame.
|
|
||||||
*
|
|
||||||
* Queries the delay time in milliseconds of an animation frame.
|
|
||||||
*
|
|
||||||
* Return value: Delay time in milliseconds.
|
|
||||||
**/
|
|
||||||
int
|
|
||||||
gdk_pixbuf_frame_get_delay_time (GdkPixbufFrame *frame)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (frame != NULL, -1);
|
|
||||||
|
|
||||||
return frame->delay_time;
|
static void gdk_pixbuf_non_anim_class_init (GdkPixbufNonAnimClass *klass);
|
||||||
}
|
static void gdk_pixbuf_non_anim_finalize (GObject *object);
|
||||||
|
|
||||||
/**
|
static gboolean gdk_pixbuf_non_anim_is_static_image (GdkPixbufAnimation *animation);
|
||||||
* gdk_pixbuf_frame_get_action:
|
static GdkPixbuf* gdk_pixbuf_non_anim_get_static_image (GdkPixbufAnimation *animation);
|
||||||
* @frame: A pixbuf animation frame.
|
static void gdk_pixbuf_non_anim_get_size (GdkPixbufAnimation *anim,
|
||||||
*
|
int *width,
|
||||||
* Queries the overlay action of an animation frame.
|
int *height);
|
||||||
*
|
static GdkPixbufAnimationIter* gdk_pixbuf_non_anim_get_iter (GdkPixbufAnimation *anim,
|
||||||
* Return value: Overlay action for this frame.
|
const GTimeVal *start_time);
|
||||||
**/
|
|
||||||
GdkPixbufFrameAction
|
|
||||||
gdk_pixbuf_frame_get_action (GdkPixbufFrame *frame)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (frame != NULL, GDK_PIXBUF_FRAME_RETAIN);
|
|
||||||
|
|
||||||
return frame->action;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gdk_pixbuf_frame_copy:
|
|
||||||
* @src: a #GdkPixbufFrame to copy
|
|
||||||
*
|
|
||||||
* Copies a #GdkPixbufFrame. Free the result
|
|
||||||
* with gdk_pixbuf_frame_free().
|
|
||||||
*
|
|
||||||
* Return value: a new #GdkPixbufFrame
|
|
||||||
**/
|
|
||||||
GdkPixbufFrame*
|
|
||||||
gdk_pixbuf_frame_copy (GdkPixbufFrame *src)
|
|
||||||
{
|
|
||||||
GdkPixbufFrame *frame;
|
|
||||||
|
|
||||||
frame = g_new (GdkPixbufFrame, 1);
|
|
||||||
frame->pixbuf = src->pixbuf;
|
|
||||||
g_object_ref (G_OBJECT (frame->pixbuf));
|
|
||||||
frame->x_offset = src->x_offset;
|
|
||||||
frame->y_offset = src->y_offset;
|
|
||||||
frame->delay_time = src->delay_time;
|
|
||||||
frame->action = src->action;
|
|
||||||
|
|
||||||
return frame;
|
static gpointer non_parent_class;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gdk_pixbuf_frame_free:
|
|
||||||
* @frame: a #GdkPixbufFrame
|
|
||||||
*
|
|
||||||
* Frees a #GdkPixbufFrame. Don't do this with frames you got from
|
|
||||||
* #GdkPixbufAnimation, usually the animation owns those (it doesn't
|
|
||||||
* make a copy before returning the frame).
|
|
||||||
**/
|
|
||||||
void
|
|
||||||
gdk_pixbuf_frame_free (GdkPixbufFrame *frame)
|
|
||||||
{
|
|
||||||
g_return_if_fail (frame != NULL);
|
|
||||||
|
|
||||||
g_object_unref (G_OBJECT (frame->pixbuf));
|
|
||||||
g_free (frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
GType
|
GType
|
||||||
gdk_pixbuf_frame_get_type (void)
|
gdk_pixbuf_non_anim_get_type (void)
|
||||||
{
|
{
|
||||||
static GType our_type = 0;
|
static GType object_type = 0;
|
||||||
|
|
||||||
if (our_type == 0)
|
if (!object_type) {
|
||||||
our_type = g_boxed_type_register_static ("GdkPixbufFrame",
|
static const GTypeInfo object_info = {
|
||||||
NULL,
|
sizeof (GdkPixbufNonAnimClass),
|
||||||
gdk_pixbuf_frame_copy,
|
(GBaseInitFunc) NULL,
|
||||||
gdk_pixbuf_frame_free,
|
(GBaseFinalizeFunc) NULL,
|
||||||
FALSE);
|
(GClassInitFunc) gdk_pixbuf_non_anim_class_init,
|
||||||
|
NULL, /* class_finalize */
|
||||||
|
NULL, /* class_data */
|
||||||
|
sizeof (GdkPixbufNonAnim),
|
||||||
|
0, /* n_preallocs */
|
||||||
|
(GInstanceInitFunc) NULL,
|
||||||
|
};
|
||||||
|
|
||||||
return our_type;
|
object_type = g_type_register_static (GDK_TYPE_PIXBUF_ANIMATION,
|
||||||
|
"GdkPixbufNonAnim",
|
||||||
|
&object_info, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return object_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_pixbuf_non_anim_class_init (GdkPixbufNonAnimClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
GdkPixbufAnimationClass *anim_class = GDK_PIXBUF_ANIMATION_CLASS (klass);
|
||||||
|
|
||||||
|
non_parent_class = g_type_class_peek_parent (klass);
|
||||||
|
|
||||||
|
object_class->finalize = gdk_pixbuf_non_anim_finalize;
|
||||||
|
|
||||||
|
anim_class->is_static_image = gdk_pixbuf_non_anim_is_static_image;
|
||||||
|
anim_class->get_static_image = gdk_pixbuf_non_anim_get_static_image;
|
||||||
|
anim_class->get_size = gdk_pixbuf_non_anim_get_size;
|
||||||
|
anim_class->get_iter = gdk_pixbuf_non_anim_get_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_pixbuf_non_anim_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
GdkPixbufNonAnim *non_anim = GDK_PIXBUF_NON_ANIM (object);
|
||||||
|
|
||||||
|
if (non_anim->pixbuf)
|
||||||
|
g_object_unref (G_OBJECT (non_anim->pixbuf));
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (non_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
GdkPixbufAnimation*
|
||||||
|
gdk_pixbuf_non_anim_new (GdkPixbuf *pixbuf)
|
||||||
|
{
|
||||||
|
GdkPixbufNonAnim *non_anim;
|
||||||
|
|
||||||
|
non_anim = g_object_new (GDK_TYPE_PIXBUF_NON_ANIM, NULL);
|
||||||
|
|
||||||
|
non_anim->pixbuf = pixbuf;
|
||||||
|
|
||||||
|
if (pixbuf)
|
||||||
|
g_object_ref (G_OBJECT (pixbuf));
|
||||||
|
|
||||||
|
return GDK_PIXBUF_ANIMATION (non_anim);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdk_pixbuf_non_anim_is_static_image (GdkPixbufAnimation *animation)
|
||||||
|
{
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GdkPixbuf*
|
||||||
|
gdk_pixbuf_non_anim_get_static_image (GdkPixbufAnimation *animation)
|
||||||
|
{
|
||||||
|
GdkPixbufNonAnim *non_anim;
|
||||||
|
|
||||||
|
non_anim = GDK_PIXBUF_NON_ANIM (animation);
|
||||||
|
|
||||||
|
return non_anim->pixbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_pixbuf_non_anim_get_size (GdkPixbufAnimation *anim,
|
||||||
|
int *width,
|
||||||
|
int *height)
|
||||||
|
{
|
||||||
|
GdkPixbufNonAnim *non_anim;
|
||||||
|
|
||||||
|
non_anim = GDK_PIXBUF_NON_ANIM (anim);
|
||||||
|
|
||||||
|
if (width)
|
||||||
|
*width = gdk_pixbuf_get_width (non_anim->pixbuf);
|
||||||
|
|
||||||
|
if (height)
|
||||||
|
*height = gdk_pixbuf_get_height (non_anim->pixbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static GdkPixbufAnimationIter*
|
||||||
|
gdk_pixbuf_non_anim_get_iter (GdkPixbufAnimation *anim,
|
||||||
|
const GTimeVal *start_time)
|
||||||
|
{
|
||||||
|
GdkPixbufNonAnimIter *iter;
|
||||||
|
|
||||||
|
iter = g_object_new (GDK_TYPE_PIXBUF_NON_ANIM_ITER, NULL);
|
||||||
|
|
||||||
|
iter->non_anim = GDK_PIXBUF_NON_ANIM (anim);
|
||||||
|
|
||||||
|
g_object_ref (G_OBJECT (iter->non_anim));
|
||||||
|
|
||||||
|
return GDK_PIXBUF_ANIMATION_ITER (iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void gdk_pixbuf_non_anim_iter_class_init (GdkPixbufNonAnimIterClass *klass);
|
||||||
|
static void gdk_pixbuf_non_anim_iter_finalize (GObject *object);
|
||||||
|
static int gdk_pixbuf_non_anim_iter_get_delay_time (GdkPixbufAnimationIter *iter);
|
||||||
|
static GdkPixbuf* gdk_pixbuf_non_anim_iter_get_pixbuf (GdkPixbufAnimationIter *iter);
|
||||||
|
static gboolean gdk_pixbuf_non_anim_iter_on_currently_loading_frame (GdkPixbufAnimationIter *iter);
|
||||||
|
static gboolean gdk_pixbuf_non_anim_iter_advance (GdkPixbufAnimationIter *iter,
|
||||||
|
const GTimeVal *current_time);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static gpointer non_iter_parent_class;
|
||||||
|
|
||||||
|
GType
|
||||||
|
gdk_pixbuf_non_anim_iter_get_type (void)
|
||||||
|
{
|
||||||
|
static GType object_type = 0;
|
||||||
|
|
||||||
|
if (!object_type) {
|
||||||
|
static const GTypeInfo object_info = {
|
||||||
|
sizeof (GdkPixbufNonAnimIterClass),
|
||||||
|
(GBaseInitFunc) NULL,
|
||||||
|
(GBaseFinalizeFunc) NULL,
|
||||||
|
(GClassInitFunc) gdk_pixbuf_non_anim_iter_class_init,
|
||||||
|
NULL, /* class_finalize */
|
||||||
|
NULL, /* class_data */
|
||||||
|
sizeof (GdkPixbufNonAnimIter),
|
||||||
|
0, /* n_preallocs */
|
||||||
|
(GInstanceInitFunc) NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
object_type = g_type_register_static (GDK_TYPE_PIXBUF_ANIMATION_ITER,
|
||||||
|
"GdkPixbufNonAnimIter",
|
||||||
|
&object_info, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return object_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_pixbuf_non_anim_iter_class_init (GdkPixbufNonAnimIterClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
GdkPixbufAnimationIterClass *anim_iter_class =
|
||||||
|
GDK_PIXBUF_ANIMATION_ITER_CLASS (klass);
|
||||||
|
|
||||||
|
non_iter_parent_class = g_type_class_peek_parent (klass);
|
||||||
|
|
||||||
|
object_class->finalize = gdk_pixbuf_non_anim_iter_finalize;
|
||||||
|
|
||||||
|
anim_iter_class->get_delay_time = gdk_pixbuf_non_anim_iter_get_delay_time;
|
||||||
|
anim_iter_class->get_pixbuf = gdk_pixbuf_non_anim_iter_get_pixbuf;
|
||||||
|
anim_iter_class->on_currently_loading_frame = gdk_pixbuf_non_anim_iter_on_currently_loading_frame;
|
||||||
|
anim_iter_class->advance = gdk_pixbuf_non_anim_iter_advance;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_pixbuf_non_anim_iter_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
GdkPixbufNonAnimIter *iter = GDK_PIXBUF_NON_ANIM_ITER (object);
|
||||||
|
|
||||||
|
g_object_unref (G_OBJECT (iter->non_anim));
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (non_iter_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gdk_pixbuf_non_anim_iter_get_delay_time (GdkPixbufAnimationIter *iter)
|
||||||
|
{
|
||||||
|
return -1; /* show only frame forever */
|
||||||
|
}
|
||||||
|
|
||||||
|
static GdkPixbuf*
|
||||||
|
gdk_pixbuf_non_anim_iter_get_pixbuf (GdkPixbufAnimationIter *iter)
|
||||||
|
{
|
||||||
|
return GDK_PIXBUF_NON_ANIM_ITER (iter)->non_anim->pixbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdk_pixbuf_non_anim_iter_on_currently_loading_frame (GdkPixbufAnimationIter *iter)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdk_pixbuf_non_anim_iter_advance (GdkPixbufAnimationIter *iter,
|
||||||
|
const GTimeVal *current_time)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Advancing never requires a refresh */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -39,15 +39,14 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef void (* ModulePreparedNotifyFunc) (GdkPixbuf *pixbuf, gpointer user_data);
|
typedef void (* ModulePreparedNotifyFunc) (GdkPixbuf *pixbuf,
|
||||||
|
GdkPixbufAnimation *anim,
|
||||||
|
gpointer user_data);
|
||||||
typedef void (* ModuleUpdatedNotifyFunc) (GdkPixbuf *pixbuf,
|
typedef void (* ModuleUpdatedNotifyFunc) (GdkPixbuf *pixbuf,
|
||||||
guint x, guint y,
|
int x,
|
||||||
guint width, guint height,
|
int y,
|
||||||
gpointer user_data);
|
int width,
|
||||||
/* Needed only for animated images. */
|
int height,
|
||||||
typedef void (* ModuleFrameDoneNotifyFunc) (GdkPixbufFrame *frame,
|
|
||||||
gpointer user_data);
|
|
||||||
typedef void (* ModuleAnimationDoneNotifyFunc) (GdkPixbuf *pixbuf,
|
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
typedef struct _GdkPixbufModule GdkPixbufModule;
|
typedef struct _GdkPixbufModule GdkPixbufModule;
|
||||||
@ -63,8 +62,6 @@ struct _GdkPixbufModule {
|
|||||||
|
|
||||||
gpointer (* begin_load) (ModulePreparedNotifyFunc prepare_func,
|
gpointer (* begin_load) (ModulePreparedNotifyFunc prepare_func,
|
||||||
ModuleUpdatedNotifyFunc update_func,
|
ModuleUpdatedNotifyFunc update_func,
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func,
|
|
||||||
ModuleAnimationDoneNotifyFunc anim_done_func,
|
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error);
|
GError **error);
|
||||||
gboolean (* stop_load) (gpointer context,
|
gboolean (* stop_load) (gpointer context,
|
||||||
|
@ -35,8 +35,6 @@
|
|||||||
enum {
|
enum {
|
||||||
AREA_UPDATED,
|
AREA_UPDATED,
|
||||||
AREA_PREPARED,
|
AREA_PREPARED,
|
||||||
FRAME_DONE,
|
|
||||||
ANIMATION_DONE,
|
|
||||||
CLOSED,
|
CLOSED,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
@ -56,7 +54,6 @@ static guint pixbuf_loader_signals[LAST_SIGNAL] = { 0 };
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GdkPixbuf *pixbuf;
|
|
||||||
GdkPixbufAnimation *animation;
|
GdkPixbufAnimation *animation;
|
||||||
gboolean closed;
|
gboolean closed;
|
||||||
guchar header_buf[LOADER_HEADER_SIZE];
|
guchar header_buf[LOADER_HEADER_SIZE];
|
||||||
@ -136,25 +133,6 @@ gdk_pixbuf_loader_class_init (GdkPixbufLoaderClass *class)
|
|||||||
G_TYPE_INT,
|
G_TYPE_INT,
|
||||||
G_TYPE_INT);
|
G_TYPE_INT);
|
||||||
|
|
||||||
pixbuf_loader_signals[FRAME_DONE] =
|
|
||||||
g_signal_newc ("frame_done",
|
|
||||||
G_TYPE_FROM_CLASS (object_class),
|
|
||||||
G_SIGNAL_RUN_LAST,
|
|
||||||
G_STRUCT_OFFSET (GdkPixbufLoaderClass, frame_done),
|
|
||||||
NULL, NULL,
|
|
||||||
gdk_pixbuf_marshal_VOID__POINTER,
|
|
||||||
G_TYPE_NONE, 1,
|
|
||||||
GDK_TYPE_PIXBUF_FRAME);
|
|
||||||
|
|
||||||
pixbuf_loader_signals[ANIMATION_DONE] =
|
|
||||||
g_signal_newc ("animation_done",
|
|
||||||
G_TYPE_FROM_CLASS (object_class),
|
|
||||||
G_SIGNAL_RUN_LAST,
|
|
||||||
G_STRUCT_OFFSET (GdkPixbufLoaderClass, animation_done),
|
|
||||||
NULL, NULL,
|
|
||||||
gdk_pixbuf_marshal_VOID__VOID,
|
|
||||||
G_TYPE_NONE, 0);
|
|
||||||
|
|
||||||
pixbuf_loader_signals[CLOSED] =
|
pixbuf_loader_signals[CLOSED] =
|
||||||
g_signal_newc ("closed",
|
g_signal_newc ("closed",
|
||||||
G_TYPE_FROM_CLASS (object_class),
|
G_TYPE_FROM_CLASS (object_class),
|
||||||
@ -189,9 +167,6 @@ gdk_pixbuf_loader_finalize (GObject *object)
|
|||||||
if (priv->animation)
|
if (priv->animation)
|
||||||
gdk_pixbuf_animation_unref (priv->animation);
|
gdk_pixbuf_animation_unref (priv->animation);
|
||||||
|
|
||||||
if (priv->pixbuf)
|
|
||||||
gdk_pixbuf_unref (priv->pixbuf);
|
|
||||||
|
|
||||||
g_free (priv);
|
g_free (priv);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
@ -199,25 +174,29 @@ gdk_pixbuf_loader_finalize (GObject *object)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_pixbuf_loader_prepare (GdkPixbuf *pixbuf,
|
gdk_pixbuf_loader_prepare (GdkPixbuf *pixbuf,
|
||||||
|
GdkPixbufAnimation *anim,
|
||||||
gpointer loader)
|
gpointer loader)
|
||||||
{
|
{
|
||||||
GdkPixbufLoaderPrivate *priv = NULL;
|
GdkPixbufLoaderPrivate *priv = NULL;
|
||||||
|
|
||||||
priv = GDK_PIXBUF_LOADER (loader)->priv;
|
priv = GDK_PIXBUF_LOADER (loader)->priv;
|
||||||
gdk_pixbuf_ref (pixbuf);
|
|
||||||
|
|
||||||
g_assert (priv->pixbuf == NULL);
|
if (anim)
|
||||||
|
g_object_ref (G_OBJECT (anim));
|
||||||
|
else
|
||||||
|
anim = gdk_pixbuf_non_anim_new (pixbuf);
|
||||||
|
|
||||||
|
priv->animation = anim;
|
||||||
|
|
||||||
priv->pixbuf = pixbuf;
|
|
||||||
g_signal_emit (G_OBJECT (loader), pixbuf_loader_signals[AREA_PREPARED], 0);
|
g_signal_emit (G_OBJECT (loader), pixbuf_loader_signals[AREA_PREPARED], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_pixbuf_loader_update (GdkPixbuf *pixbuf,
|
gdk_pixbuf_loader_update (GdkPixbuf *pixbuf,
|
||||||
guint x,
|
gint x,
|
||||||
guint y,
|
gint y,
|
||||||
guint width,
|
gint width,
|
||||||
guint height,
|
gint height,
|
||||||
gpointer loader)
|
gpointer loader)
|
||||||
{
|
{
|
||||||
GdkPixbufLoaderPrivate *priv = NULL;
|
GdkPixbufLoaderPrivate *priv = NULL;
|
||||||
@ -229,82 +208,8 @@ gdk_pixbuf_loader_update (GdkPixbuf *pixbuf,
|
|||||||
0,
|
0,
|
||||||
x, y,
|
x, y,
|
||||||
/* sanity check in here. Defend against an errant loader */
|
/* sanity check in here. Defend against an errant loader */
|
||||||
MIN (width, gdk_pixbuf_get_width (priv->pixbuf)),
|
MIN (width, gdk_pixbuf_animation_get_width (priv->animation)),
|
||||||
MIN (height, gdk_pixbuf_get_height (priv->pixbuf)));
|
MIN (height, gdk_pixbuf_animation_get_height (priv->animation)));
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gdk_pixbuf_loader_frame_done (GdkPixbufFrame *frame,
|
|
||||||
gpointer loader)
|
|
||||||
{
|
|
||||||
GdkPixbufLoaderPrivate *priv = NULL;
|
|
||||||
|
|
||||||
priv = GDK_PIXBUF_LOADER (loader)->priv;
|
|
||||||
|
|
||||||
priv->pixbuf = NULL;
|
|
||||||
|
|
||||||
if (priv->animation == NULL)
|
|
||||||
{
|
|
||||||
priv->animation = g_object_new (GDK_TYPE_PIXBUF_ANIMATION, NULL);
|
|
||||||
|
|
||||||
priv->animation->n_frames = 0;
|
|
||||||
priv->animation->width = gdk_pixbuf_get_width (frame->pixbuf) + frame->x_offset;
|
|
||||||
priv->animation->height = gdk_pixbuf_get_height (frame->pixbuf) + frame->y_offset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int w, h;
|
|
||||||
|
|
||||||
/* update bbox size */
|
|
||||||
w = gdk_pixbuf_get_width (frame->pixbuf) + frame->x_offset;
|
|
||||||
h = gdk_pixbuf_get_height (frame->pixbuf) + frame->y_offset;
|
|
||||||
|
|
||||||
if (w > priv->animation->width) {
|
|
||||||
priv->animation->width = w;
|
|
||||||
}
|
|
||||||
if (h > priv->animation->height) {
|
|
||||||
priv->animation->height = h;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->animation->frames = g_list_append (priv->animation->frames, frame);
|
|
||||||
priv->animation->n_frames++;
|
|
||||||
g_signal_emit (G_OBJECT (loader),
|
|
||||||
pixbuf_loader_signals[FRAME_DONE],
|
|
||||||
0,
|
|
||||||
frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gdk_pixbuf_loader_animation_done (GdkPixbuf *pixbuf,
|
|
||||||
gpointer loader)
|
|
||||||
{
|
|
||||||
GdkPixbufLoaderPrivate *priv = NULL;
|
|
||||||
GdkPixbufFrame *frame;
|
|
||||||
GList *current = NULL;
|
|
||||||
gint h, w;
|
|
||||||
|
|
||||||
priv = GDK_PIXBUF_LOADER (loader)->priv;
|
|
||||||
priv->pixbuf = NULL;
|
|
||||||
|
|
||||||
current = gdk_pixbuf_animation_get_frames (priv->animation);
|
|
||||||
|
|
||||||
while (current)
|
|
||||||
{
|
|
||||||
frame = (GdkPixbufFrame *) current->data;
|
|
||||||
|
|
||||||
/* update bbox size */
|
|
||||||
w = gdk_pixbuf_get_width (frame->pixbuf) + frame->x_offset;
|
|
||||||
h = gdk_pixbuf_get_height (frame->pixbuf) + frame->y_offset;
|
|
||||||
|
|
||||||
if (w > priv->animation->width)
|
|
||||||
priv->animation->width = w;
|
|
||||||
if (h > priv->animation->height)
|
|
||||||
priv->animation->height = h;
|
|
||||||
current = current->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_signal_emit (G_OBJECT (loader), pixbuf_loader_signals[ANIMATION_DONE], 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
@ -353,8 +258,6 @@ gdk_pixbuf_loader_load_module (GdkPixbufLoader *loader,
|
|||||||
|
|
||||||
priv->context = priv->image_module->begin_load (gdk_pixbuf_loader_prepare,
|
priv->context = priv->image_module->begin_load (gdk_pixbuf_loader_prepare,
|
||||||
gdk_pixbuf_loader_update,
|
gdk_pixbuf_loader_update,
|
||||||
gdk_pixbuf_loader_frame_done,
|
|
||||||
gdk_pixbuf_loader_animation_done,
|
|
||||||
loader,
|
loader,
|
||||||
error);
|
error);
|
||||||
|
|
||||||
@ -540,13 +443,14 @@ gdk_pixbuf_loader_new_with_type (const char *image_type,
|
|||||||
* "area_prepared" signal has been emitted by the loader; this means
|
* "area_prepared" signal has been emitted by the loader; this means
|
||||||
* that enough data has been read to know the size of the image that
|
* that enough data has been read to know the size of the image that
|
||||||
* will be allocated. If the loader has not received enough data via
|
* will be allocated. If the loader has not received enough data via
|
||||||
* gdk_pixbuf_loader_write(), then this function returns NULL. The
|
* gdk_pixbuf_loader_write(), then this function returns %NULL. The
|
||||||
* returned pixbuf will be the same in all future calls to the loader,
|
* returned pixbuf will be the same in all future calls to the loader,
|
||||||
* so simply calling gdk_pixbuf_ref() should be sufficient to continue
|
* so simply calling gdk_pixbuf_ref() should be sufficient to continue
|
||||||
* using it. Additionally, if the loader is an animation, it will
|
* using it. Additionally, if the loader is an animation, it will
|
||||||
* return the first frame of the animation.
|
* return the "static image" of the animation
|
||||||
|
* (see gdk_pixbuf_animation_get_static_image()).
|
||||||
*
|
*
|
||||||
* Return value: The GdkPixbuf that the loader is creating, or NULL if not
|
* Return value: The #GdkPixbuf that the loader is creating, or %NULL if not
|
||||||
* enough data has been read to determine how to create the image buffer.
|
* enough data has been read to determine how to create the image buffer.
|
||||||
**/
|
**/
|
||||||
GdkPixbuf *
|
GdkPixbuf *
|
||||||
@ -560,19 +464,9 @@ gdk_pixbuf_loader_get_pixbuf (GdkPixbufLoader *loader)
|
|||||||
priv = loader->priv;
|
priv = loader->priv;
|
||||||
|
|
||||||
if (priv->animation)
|
if (priv->animation)
|
||||||
{
|
return gdk_pixbuf_animation_get_static_image (priv->animation);
|
||||||
GList *list;
|
else
|
||||||
|
return NULL;
|
||||||
list = gdk_pixbuf_animation_get_frames (priv->animation);
|
|
||||||
if (list != NULL)
|
|
||||||
{
|
|
||||||
GdkPixbufFrame *frame = list->data;
|
|
||||||
|
|
||||||
return gdk_pixbuf_frame_get_pixbuf (frame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return priv->pixbuf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -581,8 +475,9 @@ gdk_pixbuf_loader_get_pixbuf (GdkPixbufLoader *loader)
|
|||||||
*
|
*
|
||||||
* Queries the GdkPixbufAnimation that a pixbuf loader is currently creating.
|
* Queries the GdkPixbufAnimation that a pixbuf loader is currently creating.
|
||||||
* In general it only makes sense to call this function afer the "area_prepared"
|
* In general it only makes sense to call this function afer the "area_prepared"
|
||||||
* signal has been emitted by the loader. If the image is not an animation,
|
* signal has been emitted by the loader. If the loader doesn't have enough
|
||||||
* then it will return NULL.
|
* bytes yet (hasn't emitted the area_prepared signal) this function will return
|
||||||
|
* %NULL.
|
||||||
*
|
*
|
||||||
* Return value: The GdkPixbufAnimation that the loader is loading, or NULL if
|
* Return value: The GdkPixbufAnimation that the loader is loading, or NULL if
|
||||||
not enough data has been read to determine the information.
|
not enough data has been read to determine the information.
|
||||||
|
@ -53,14 +53,14 @@ struct _GdkPixbufLoaderClass
|
|||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
void (*area_prepared) (GdkPixbufLoader *loader);
|
void (*area_prepared) (GdkPixbufLoader *loader);
|
||||||
|
|
||||||
|
/* Last known frame needs a redraw for x, y, width, height */
|
||||||
void (*area_updated) (GdkPixbufLoader *loader,
|
void (*area_updated) (GdkPixbufLoader *loader,
|
||||||
guint x,
|
int x,
|
||||||
guint y,
|
int y,
|
||||||
guint width,
|
int width,
|
||||||
guint height);
|
int height);
|
||||||
void (*frame_done) (GdkPixbufLoader *loader,
|
|
||||||
GdkPixbufFrame *frame);
|
|
||||||
void (*animation_done) (GdkPixbufLoader *loader);
|
|
||||||
void (*closed) (GdkPixbufLoader *loader);
|
void (*closed) (GdkPixbufLoader *loader);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
|
||||||
/* GdkPixbuf library - Private declarations
|
/* GdkPixbuf library - Private declarations
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999 The Free Software Foundation
|
* Copyright (C) 1999 The Free Software Foundation
|
||||||
@ -73,22 +74,6 @@ struct _GdkPixbufClass {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Private part of the GdkPixbufFrame structure */
|
|
||||||
struct _GdkPixbufFrame {
|
|
||||||
/* The pixbuf with this frame's image data */
|
|
||||||
GdkPixbuf *pixbuf;
|
|
||||||
|
|
||||||
/* Offsets for overlaying onto the animation's area */
|
|
||||||
int x_offset;
|
|
||||||
int y_offset;
|
|
||||||
|
|
||||||
/* Frame duration in ms */
|
|
||||||
int delay_time;
|
|
||||||
|
|
||||||
/* Overlay mode */
|
|
||||||
GdkPixbufFrameAction action;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _GdkPixbufAnimationClass GdkPixbufAnimationClass;
|
typedef struct _GdkPixbufAnimationClass GdkPixbufAnimationClass;
|
||||||
|
|
||||||
#define GDK_PIXBUF_ANIMATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_ANIMATION, GdkPixbufAnimationClass))
|
#define GDK_PIXBUF_ANIMATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_ANIMATION, GdkPixbufAnimationClass))
|
||||||
@ -99,20 +84,48 @@ typedef struct _GdkPixbufAnimationClass GdkPixbufAnimationClass;
|
|||||||
struct _GdkPixbufAnimation {
|
struct _GdkPixbufAnimation {
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
|
|
||||||
/* Number of frames */
|
|
||||||
int n_frames;
|
|
||||||
|
|
||||||
/* List of GdkPixbufFrame structures */
|
|
||||||
GList *frames;
|
|
||||||
|
|
||||||
/* bounding box size */
|
|
||||||
int width, height;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GdkPixbufAnimationClass {
|
struct _GdkPixbufAnimationClass {
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
gboolean (*is_static_image) (GdkPixbufAnimation *anim);
|
||||||
|
|
||||||
|
GdkPixbuf* (*get_static_image) (GdkPixbufAnimation *anim);
|
||||||
|
|
||||||
|
void (*get_size) (GdkPixbufAnimation *anim,
|
||||||
|
int *width,
|
||||||
|
int *height);
|
||||||
|
|
||||||
|
GdkPixbufAnimationIter* (*get_iter) (GdkPixbufAnimation *anim,
|
||||||
|
const GTimeVal *start_time);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _GdkPixbufAnimationIterClass GdkPixbufAnimationIterClass;
|
||||||
|
|
||||||
|
#define GDK_PIXBUF_ANIMATION_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_ANIMATION_ITER, GdkPixbufAnimationIterClass))
|
||||||
|
#define GDK_IS_PIXBUF_ANIMATION_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_ANIMATION_ITER))
|
||||||
|
#define GDK_PIXBUF_ANIMATION_ITER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_ANIMATION_ITER, GdkPixbufAnimationIterClass))
|
||||||
|
|
||||||
|
struct _GdkPixbufAnimationIter {
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GdkPixbufAnimationIterClass {
|
||||||
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
int (*get_delay_time) (GdkPixbufAnimationIter *iter);
|
||||||
|
|
||||||
|
GdkPixbuf* (*get_pixbuf) (GdkPixbufAnimationIter *iter);
|
||||||
|
|
||||||
|
gboolean (*on_currently_loading_frame) (GdkPixbufAnimationIter *iter);
|
||||||
|
|
||||||
|
gboolean (*advance) (GdkPixbufAnimationIter *iter,
|
||||||
|
const GTimeVal *current_time);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -125,6 +138,8 @@ typedef enum
|
|||||||
GDK_PIXBUF_INLINE_RLE = 1
|
GDK_PIXBUF_INLINE_RLE = 1
|
||||||
} GdkPixbufInlineFormat;
|
} GdkPixbufInlineFormat;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GdkPixbufAnimation* gdk_pixbuf_non_anim_new (GdkPixbuf *pixbuf);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -121,6 +121,8 @@ gdk_pixbuf_copy_area (const GdkPixbuf *src_pixbuf,
|
|||||||
g_return_if_fail (dest_x >= 0 && dest_x + width <= dest_pixbuf->width);
|
g_return_if_fail (dest_x >= 0 && dest_x + width <= dest_pixbuf->width);
|
||||||
g_return_if_fail (dest_y >= 0 && dest_y + height <= dest_pixbuf->height);
|
g_return_if_fail (dest_y >= 0 && dest_y + height <= dest_pixbuf->height);
|
||||||
|
|
||||||
|
g_return_if_fail (!(gdk_pixbuf_get_has_alpha (src_pixbuf) && !gdk_pixbuf_get_has_alpha (dest_pixbuf)));
|
||||||
|
|
||||||
/* This will perform format conversions automatically */
|
/* This will perform format conversions automatically */
|
||||||
|
|
||||||
gdk_pixbuf_scale (src_pixbuf,
|
gdk_pixbuf_scale (src_pixbuf,
|
||||||
|
@ -412,7 +412,7 @@ gdk_pixbuf_error_quark (void)
|
|||||||
/**
|
/**
|
||||||
* gdk_pixbuf_fill:
|
* gdk_pixbuf_fill:
|
||||||
* @pixbuf: a #GdkPixbuf
|
* @pixbuf: a #GdkPixbuf
|
||||||
* @pixel: RGBA pixel to clear to (0xffffff00 is opaque white, 0x000000ff transparent black)
|
* @pixel: RGBA pixel to clear to (0xffffffff is opaque white, 0x00000000 transparent black)
|
||||||
*
|
*
|
||||||
* Clears a pixbuf to the given RGBA value, converting the RGBA value into
|
* Clears a pixbuf to the given RGBA value, converting the RGBA value into
|
||||||
* the pixbuf's pixel format. The alpha will be ignored if the pixbuf
|
* the pixbuf's pixel format. The alpha will be ignored if the pixbuf
|
||||||
@ -454,7 +454,7 @@ gdk_pixbuf_fill (GdkPixbuf *pixbuf,
|
|||||||
|
|
||||||
p = pixels;
|
p = pixels;
|
||||||
end = pixels + pixbuf->rowstride * pixbuf->height;
|
end = pixels + pixbuf->rowstride * pixbuf->height;
|
||||||
end -= (pixbuf->rowstride - pixbuf->width);
|
end -= (pixbuf->rowstride - pixbuf->width * pixbuf->n_channels);
|
||||||
|
|
||||||
while (p < end) {
|
while (p < end) {
|
||||||
*p++ = r;
|
*p++ = r;
|
||||||
|
@ -54,6 +54,7 @@ typedef enum {
|
|||||||
/* All of these are opaque structures */
|
/* All of these are opaque structures */
|
||||||
typedef struct _GdkPixbuf GdkPixbuf;
|
typedef struct _GdkPixbuf GdkPixbuf;
|
||||||
typedef struct _GdkPixbufAnimation GdkPixbufAnimation;
|
typedef struct _GdkPixbufAnimation GdkPixbufAnimation;
|
||||||
|
typedef struct _GdkPixbufAnimationIter GdkPixbufAnimationIter;
|
||||||
typedef struct _GdkPixbufFrame GdkPixbufFrame;
|
typedef struct _GdkPixbufFrame GdkPixbufFrame;
|
||||||
|
|
||||||
#define GDK_TYPE_PIXBUF (gdk_pixbuf_get_type ())
|
#define GDK_TYPE_PIXBUF (gdk_pixbuf_get_type ())
|
||||||
@ -64,6 +65,9 @@ typedef struct _GdkPixbufFrame GdkPixbufFrame;
|
|||||||
#define GDK_PIXBUF_ANIMATION(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_ANIMATION, GdkPixbufAnimation))
|
#define GDK_PIXBUF_ANIMATION(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_ANIMATION, GdkPixbufAnimation))
|
||||||
#define GDK_IS_PIXBUF_ANIMATION(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_ANIMATION))
|
#define GDK_IS_PIXBUF_ANIMATION(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_ANIMATION))
|
||||||
|
|
||||||
|
#define GDK_TYPE_PIXBUF_ANIMATION_ITER (gdk_pixbuf_animation_iter_get_type ())
|
||||||
|
#define GDK_PIXBUF_ANIMATION_ITER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_ANIMATION_ITER, GdkPixbufAnimationIter))
|
||||||
|
#define GDK_IS_PIXBUF_ANIMATION_ITER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_ANIMATION_ITER))
|
||||||
|
|
||||||
/* Handler that must free the pixel array */
|
/* Handler that must free the pixel array */
|
||||||
typedef void (* GdkPixbufDestroyNotify) (guchar *pixels, gpointer data);
|
typedef void (* GdkPixbufDestroyNotify) (guchar *pixels, gpointer data);
|
||||||
@ -255,13 +259,6 @@ GdkPixbuf *gdk_pixbuf_composite_color_simple (const GdkPixbuf *src,
|
|||||||
|
|
||||||
/* Animation support */
|
/* Animation support */
|
||||||
|
|
||||||
/* GIF-like animation overlay modes for frames */
|
|
||||||
typedef enum {
|
|
||||||
GDK_PIXBUF_FRAME_RETAIN,
|
|
||||||
GDK_PIXBUF_FRAME_DISPOSE,
|
|
||||||
GDK_PIXBUF_FRAME_REVERT
|
|
||||||
} GdkPixbufFrameAction;
|
|
||||||
|
|
||||||
GType gdk_pixbuf_animation_get_type (void) G_GNUC_CONST;
|
GType gdk_pixbuf_animation_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
GdkPixbufAnimation *gdk_pixbuf_animation_new_from_file (const char *filename,
|
GdkPixbufAnimation *gdk_pixbuf_animation_new_from_file (const char *filename,
|
||||||
@ -272,20 +269,19 @@ void gdk_pixbuf_animation_unref (GdkPixbufAnimation *an
|
|||||||
|
|
||||||
int gdk_pixbuf_animation_get_width (GdkPixbufAnimation *animation);
|
int gdk_pixbuf_animation_get_width (GdkPixbufAnimation *animation);
|
||||||
int gdk_pixbuf_animation_get_height (GdkPixbufAnimation *animation);
|
int gdk_pixbuf_animation_get_height (GdkPixbufAnimation *animation);
|
||||||
GList *gdk_pixbuf_animation_get_frames (GdkPixbufAnimation *animation);
|
gboolean gdk_pixbuf_animation_is_static_image (GdkPixbufAnimation *animation);
|
||||||
int gdk_pixbuf_animation_get_num_frames (GdkPixbufAnimation *animation);
|
GdkPixbuf *gdk_pixbuf_animation_get_static_image (GdkPixbufAnimation *animation);
|
||||||
|
|
||||||
|
GdkPixbufAnimationIter *gdk_pixbuf_animation_get_iter (GdkPixbufAnimation *animation,
|
||||||
|
const GTimeVal *start_time);
|
||||||
|
GType gdk_pixbuf_animation_iter_get_type (void) G_GNUC_CONST;
|
||||||
|
int gdk_pixbuf_animation_iter_get_delay_time (GdkPixbufAnimationIter *iter);
|
||||||
|
GdkPixbuf *gdk_pixbuf_animation_iter_get_pixbuf (GdkPixbufAnimationIter *iter);
|
||||||
|
gboolean gdk_pixbuf_animation_iter_on_currently_loading_frame (GdkPixbufAnimationIter *iter);
|
||||||
|
gboolean gdk_pixbuf_animation_iter_advance (GdkPixbufAnimationIter *iter,
|
||||||
|
const GTimeVal *current_time);
|
||||||
|
|
||||||
/* Frame accessors */
|
|
||||||
|
|
||||||
GdkPixbuf *gdk_pixbuf_frame_get_pixbuf (GdkPixbufFrame *frame);
|
|
||||||
int gdk_pixbuf_frame_get_x_offset (GdkPixbufFrame *frame);
|
|
||||||
int gdk_pixbuf_frame_get_y_offset (GdkPixbufFrame *frame);
|
|
||||||
int gdk_pixbuf_frame_get_delay_time (GdkPixbufFrame *frame);
|
|
||||||
GdkPixbufFrameAction gdk_pixbuf_frame_get_action (GdkPixbufFrame *frame);
|
|
||||||
GdkPixbufFrame *gdk_pixbuf_frame_copy (GdkPixbufFrame *src);
|
|
||||||
void gdk_pixbuf_frame_free (GdkPixbufFrame *frame);
|
|
||||||
GType gdk_pixbuf_frame_get_type (void) G_GNUC_CONST;
|
|
||||||
#define GDK_TYPE_PIXBUF_FRAME gdk_pixbuf_frame_get_type ()
|
|
||||||
|
|
||||||
#include <gdk-pixbuf/gdk-pixbuf-loader.h>
|
#include <gdk-pixbuf/gdk-pixbuf-loader.h>
|
||||||
|
|
||||||
|
@ -174,9 +174,7 @@ struct bmp_progressive_state {
|
|||||||
static gpointer
|
static gpointer
|
||||||
gdk_pixbuf__bmp_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
gdk_pixbuf__bmp_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
||||||
ModuleUpdatedNotifyFunc updated_func,
|
ModuleUpdatedNotifyFunc updated_func,
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func,
|
gpointer user_data,
|
||||||
ModuleAnimationDoneNotifyFunc
|
|
||||||
anim_done_func, gpointer user_data,
|
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
static gboolean gdk_pixbuf__bmp_image_stop_load(gpointer data, GError **error);
|
static gboolean gdk_pixbuf__bmp_image_stop_load(gpointer data, GError **error);
|
||||||
@ -198,7 +196,7 @@ static GdkPixbuf *gdk_pixbuf__bmp_image_load(FILE * f, GError **error)
|
|||||||
GdkPixbuf *pb;
|
GdkPixbuf *pb;
|
||||||
|
|
||||||
State =
|
State =
|
||||||
gdk_pixbuf__bmp_image_begin_load(NULL, NULL, NULL, NULL, NULL,
|
gdk_pixbuf__bmp_image_begin_load(NULL, NULL, NULL,
|
||||||
error);
|
error);
|
||||||
|
|
||||||
if (State == NULL)
|
if (State == NULL)
|
||||||
@ -312,7 +310,7 @@ static gboolean DecodeHeader(unsigned char *BFH, unsigned char *BIH,
|
|||||||
|
|
||||||
if (State->prepared_func != NULL)
|
if (State->prepared_func != NULL)
|
||||||
/* Notify the client that we are ready to go */
|
/* Notify the client that we are ready to go */
|
||||||
(*State->prepared_func) (State->pixbuf, State->user_data);
|
(*State->prepared_func) (State->pixbuf, NULL, State->user_data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,9 +326,7 @@ static gboolean DecodeHeader(unsigned char *BFH, unsigned char *BIH,
|
|||||||
static gpointer
|
static gpointer
|
||||||
gdk_pixbuf__bmp_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
gdk_pixbuf__bmp_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
||||||
ModuleUpdatedNotifyFunc updated_func,
|
ModuleUpdatedNotifyFunc updated_func,
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func,
|
gpointer user_data,
|
||||||
ModuleAnimationDoneNotifyFunc
|
|
||||||
anim_done_func, gpointer user_data,
|
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
struct bmp_progressive_state *context;
|
struct bmp_progressive_state *context;
|
||||||
|
557
gdk-pixbuf/io-gif-animation.c
Normal file
557
gdk-pixbuf/io-gif-animation.c
Normal file
@ -0,0 +1,557 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
|
||||||
|
/* GdkPixbuf library - animated gif support
|
||||||
|
*
|
||||||
|
* Copyright (C) 1999 The Free Software Foundation
|
||||||
|
*
|
||||||
|
* Authors: Jonathan Blandford <jrb@redhat.com>
|
||||||
|
* Havoc Pennington <hp@redhat.com>
|
||||||
|
*
|
||||||
|
* 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 <errno.h>
|
||||||
|
#include "gdk-pixbuf-io.h"
|
||||||
|
#include "gdk-pixbuf-private.h"
|
||||||
|
#include "io-gif-animation.h"
|
||||||
|
|
||||||
|
static void gdk_pixbuf_gif_anim_class_init (GdkPixbufGifAnimClass *klass);
|
||||||
|
static void gdk_pixbuf_gif_anim_finalize (GObject *object);
|
||||||
|
|
||||||
|
static gboolean gdk_pixbuf_gif_anim_is_static_image (GdkPixbufAnimation *animation);
|
||||||
|
static GdkPixbuf* gdk_pixbuf_gif_anim_get_static_image (GdkPixbufAnimation *animation);
|
||||||
|
|
||||||
|
static void gdk_pixbuf_gif_anim_get_size (GdkPixbufAnimation *anim,
|
||||||
|
int *width,
|
||||||
|
int *height);
|
||||||
|
static GdkPixbufAnimationIter* gdk_pixbuf_gif_anim_get_iter (GdkPixbufAnimation *anim,
|
||||||
|
const GTimeVal *start_time);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static gpointer parent_class;
|
||||||
|
|
||||||
|
GType
|
||||||
|
gdk_pixbuf_gif_anim_get_type (void)
|
||||||
|
{
|
||||||
|
static GType object_type = 0;
|
||||||
|
|
||||||
|
if (!object_type) {
|
||||||
|
static const GTypeInfo object_info = {
|
||||||
|
sizeof (GdkPixbufGifAnimClass),
|
||||||
|
(GBaseInitFunc) NULL,
|
||||||
|
(GBaseFinalizeFunc) NULL,
|
||||||
|
(GClassInitFunc) gdk_pixbuf_gif_anim_class_init,
|
||||||
|
NULL, /* class_finalize */
|
||||||
|
NULL, /* class_data */
|
||||||
|
sizeof (GdkPixbufGifAnim),
|
||||||
|
0, /* n_preallocs */
|
||||||
|
(GInstanceInitFunc) NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
object_type = g_type_register_static (GDK_TYPE_PIXBUF_ANIMATION,
|
||||||
|
"GdkPixbufGifAnim",
|
||||||
|
&object_info, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return object_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_pixbuf_gif_anim_class_init (GdkPixbufGifAnimClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
GdkPixbufAnimationClass *anim_class = GDK_PIXBUF_ANIMATION_CLASS (klass);
|
||||||
|
|
||||||
|
parent_class = g_type_class_peek_parent (klass);
|
||||||
|
|
||||||
|
object_class->finalize = gdk_pixbuf_gif_anim_finalize;
|
||||||
|
|
||||||
|
anim_class->is_static_image = gdk_pixbuf_gif_anim_is_static_image;
|
||||||
|
anim_class->get_static_image = gdk_pixbuf_gif_anim_get_static_image;
|
||||||
|
anim_class->get_size = gdk_pixbuf_gif_anim_get_size;
|
||||||
|
anim_class->get_iter = gdk_pixbuf_gif_anim_get_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_pixbuf_gif_anim_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
GdkPixbufGifAnim *gif_anim = GDK_PIXBUF_GIF_ANIM (object);
|
||||||
|
|
||||||
|
GList *l;
|
||||||
|
GdkPixbufFrame *frame;
|
||||||
|
|
||||||
|
for (l = gif_anim->frames; l; l = l->next) {
|
||||||
|
frame = l->data;
|
||||||
|
gdk_pixbuf_unref (frame->pixbuf);
|
||||||
|
if (frame->composited)
|
||||||
|
gdk_pixbuf_unref (frame->composited);
|
||||||
|
if (frame->revert)
|
||||||
|
gdk_pixbuf_unref (frame->revert);
|
||||||
|
g_free (frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free (gif_anim->frames);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdk_pixbuf_gif_anim_is_static_image (GdkPixbufAnimation *animation)
|
||||||
|
{
|
||||||
|
GdkPixbufGifAnim *gif_anim;
|
||||||
|
|
||||||
|
gif_anim = GDK_PIXBUF_GIF_ANIM (animation);
|
||||||
|
|
||||||
|
return (gif_anim->frames != NULL &&
|
||||||
|
gif_anim->frames->next == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GdkPixbuf*
|
||||||
|
gdk_pixbuf_gif_anim_get_static_image (GdkPixbufAnimation *animation)
|
||||||
|
{
|
||||||
|
GdkPixbufGifAnim *gif_anim;
|
||||||
|
|
||||||
|
gif_anim = GDK_PIXBUF_GIF_ANIM (animation);
|
||||||
|
|
||||||
|
if (gif_anim->frames == NULL)
|
||||||
|
return NULL;
|
||||||
|
else
|
||||||
|
return GDK_PIXBUF (((GdkPixbufFrame*)gif_anim->frames->data)->pixbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_pixbuf_gif_anim_get_size (GdkPixbufAnimation *anim,
|
||||||
|
int *width,
|
||||||
|
int *height)
|
||||||
|
{
|
||||||
|
GdkPixbufGifAnim *gif_anim;
|
||||||
|
|
||||||
|
gif_anim = GDK_PIXBUF_GIF_ANIM (anim);
|
||||||
|
|
||||||
|
if (width)
|
||||||
|
*width = gif_anim->width;
|
||||||
|
|
||||||
|
if (height)
|
||||||
|
*height = gif_anim->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
iter_clear (GdkPixbufGifAnimIter *iter)
|
||||||
|
{
|
||||||
|
iter->current_frame = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
iter_restart (GdkPixbufGifAnimIter *iter)
|
||||||
|
{
|
||||||
|
iter_clear (iter);
|
||||||
|
|
||||||
|
iter->current_frame = iter->gif_anim->frames;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GdkPixbufAnimationIter*
|
||||||
|
gdk_pixbuf_gif_anim_get_iter (GdkPixbufAnimation *anim,
|
||||||
|
const GTimeVal *start_time)
|
||||||
|
{
|
||||||
|
GdkPixbufGifAnimIter *iter;
|
||||||
|
|
||||||
|
iter = g_object_new (GDK_TYPE_PIXBUF_GIF_ANIM_ITER, NULL);
|
||||||
|
|
||||||
|
iter->gif_anim = GDK_PIXBUF_GIF_ANIM (anim);
|
||||||
|
|
||||||
|
g_object_ref (G_OBJECT (iter->gif_anim));
|
||||||
|
|
||||||
|
iter_restart (iter);
|
||||||
|
|
||||||
|
iter->start_time = *start_time;
|
||||||
|
iter->current_time = *start_time;
|
||||||
|
|
||||||
|
return GDK_PIXBUF_ANIMATION_ITER (iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void gdk_pixbuf_gif_anim_iter_class_init (GdkPixbufGifAnimIterClass *klass);
|
||||||
|
static void gdk_pixbuf_gif_anim_iter_finalize (GObject *object);
|
||||||
|
|
||||||
|
static int gdk_pixbuf_gif_anim_iter_get_delay_time (GdkPixbufAnimationIter *iter);
|
||||||
|
static GdkPixbuf* gdk_pixbuf_gif_anim_iter_get_pixbuf (GdkPixbufAnimationIter *iter);
|
||||||
|
static gboolean gdk_pixbuf_gif_anim_iter_on_currently_loading_frame (GdkPixbufAnimationIter *iter);
|
||||||
|
static gboolean gdk_pixbuf_gif_anim_iter_advance (GdkPixbufAnimationIter *iter,
|
||||||
|
const GTimeVal *current_time);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static gpointer iter_parent_class;
|
||||||
|
|
||||||
|
GType
|
||||||
|
gdk_pixbuf_gif_anim_iter_get_type (void)
|
||||||
|
{
|
||||||
|
static GType object_type = 0;
|
||||||
|
|
||||||
|
if (!object_type) {
|
||||||
|
static const GTypeInfo object_info = {
|
||||||
|
sizeof (GdkPixbufGifAnimIterClass),
|
||||||
|
(GBaseInitFunc) NULL,
|
||||||
|
(GBaseFinalizeFunc) NULL,
|
||||||
|
(GClassInitFunc) gdk_pixbuf_gif_anim_iter_class_init,
|
||||||
|
NULL, /* class_finalize */
|
||||||
|
NULL, /* class_data */
|
||||||
|
sizeof (GdkPixbufGifAnimIter),
|
||||||
|
0, /* n_preallocs */
|
||||||
|
(GInstanceInitFunc) NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
object_type = g_type_register_static (GDK_TYPE_PIXBUF_ANIMATION_ITER,
|
||||||
|
"GdkPixbufGifAnimIter",
|
||||||
|
&object_info, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return object_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_pixbuf_gif_anim_iter_class_init (GdkPixbufGifAnimIterClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
GdkPixbufAnimationIterClass *anim_iter_class =
|
||||||
|
GDK_PIXBUF_ANIMATION_ITER_CLASS (klass);
|
||||||
|
|
||||||
|
iter_parent_class = g_type_class_peek_parent (klass);
|
||||||
|
|
||||||
|
object_class->finalize = gdk_pixbuf_gif_anim_iter_finalize;
|
||||||
|
|
||||||
|
anim_iter_class->get_delay_time = gdk_pixbuf_gif_anim_iter_get_delay_time;
|
||||||
|
anim_iter_class->get_pixbuf = gdk_pixbuf_gif_anim_iter_get_pixbuf;
|
||||||
|
anim_iter_class->on_currently_loading_frame = gdk_pixbuf_gif_anim_iter_on_currently_loading_frame;
|
||||||
|
anim_iter_class->advance = gdk_pixbuf_gif_anim_iter_advance;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_pixbuf_gif_anim_iter_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
GdkPixbufGifAnimIter *iter = GDK_PIXBUF_GIF_ANIM_ITER (object);
|
||||||
|
|
||||||
|
iter_clear (iter);
|
||||||
|
|
||||||
|
g_object_unref (G_OBJECT (iter->gif_anim));
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (iter_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdk_pixbuf_gif_anim_iter_advance (GdkPixbufAnimationIter *anim_iter,
|
||||||
|
const GTimeVal *current_time)
|
||||||
|
{
|
||||||
|
GdkPixbufGifAnimIter *iter;
|
||||||
|
gint elapsed;
|
||||||
|
GList *tmp;
|
||||||
|
GList *old;
|
||||||
|
|
||||||
|
iter = GDK_PIXBUF_GIF_ANIM_ITER (anim_iter);
|
||||||
|
|
||||||
|
iter->current_time = *current_time;
|
||||||
|
|
||||||
|
/* We use milliseconds for all times */
|
||||||
|
elapsed =
|
||||||
|
(((iter->current_time.tv_sec - iter->start_time.tv_sec) * G_USEC_PER_SEC +
|
||||||
|
iter->current_time.tv_usec - iter->start_time.tv_usec)) / 1000;
|
||||||
|
|
||||||
|
if (elapsed < 0) {
|
||||||
|
/* Try to compensate; probably the system clock
|
||||||
|
* was set backwards
|
||||||
|
*/
|
||||||
|
iter->start_time = iter->current_time;
|
||||||
|
elapsed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See how many times we've already played the full animation,
|
||||||
|
* and subtract time for that.
|
||||||
|
*/
|
||||||
|
elapsed = elapsed % iter->gif_anim->total_time;
|
||||||
|
|
||||||
|
g_assert (elapsed < iter->gif_anim->total_time);
|
||||||
|
|
||||||
|
iter->position = elapsed;
|
||||||
|
|
||||||
|
/* Now move to the proper frame */
|
||||||
|
tmp = iter->gif_anim->frames;
|
||||||
|
while (tmp != NULL) {
|
||||||
|
GdkPixbufFrame *frame = tmp->data;
|
||||||
|
|
||||||
|
if (iter->position >= frame->elapsed &&
|
||||||
|
iter->position < (frame->elapsed + frame->delay_time))
|
||||||
|
break;
|
||||||
|
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
old = iter->current_frame;
|
||||||
|
|
||||||
|
iter->current_frame = tmp;
|
||||||
|
|
||||||
|
return iter->current_frame != old;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gdk_pixbuf_gif_anim_iter_get_delay_time (GdkPixbufAnimationIter *anim_iter)
|
||||||
|
{
|
||||||
|
GdkPixbufFrame *frame;
|
||||||
|
GdkPixbufGifAnimIter *iter;
|
||||||
|
|
||||||
|
iter = GDK_PIXBUF_GIF_ANIM_ITER (anim_iter);
|
||||||
|
|
||||||
|
if (iter->current_frame) {
|
||||||
|
frame = iter->current_frame->data;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
g_print ("frame start: %d pos: %d frame len: %d frame remaining: %d\n",
|
||||||
|
frame->elapsed,
|
||||||
|
iter->position,
|
||||||
|
frame->delay_time,
|
||||||
|
frame->delay_time - (iter->position - frame->elapsed));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return frame->delay_time - (iter->position - frame->elapsed);
|
||||||
|
} else {
|
||||||
|
return -1; /* show last frame forever */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdk_pixbuf_gif_anim_frame_composite (GdkPixbufGifAnim *gif_anim,
|
||||||
|
GdkPixbufFrame *frame)
|
||||||
|
{
|
||||||
|
GList *link;
|
||||||
|
GList *tmp;
|
||||||
|
|
||||||
|
link = g_list_find (gif_anim->frames, frame);
|
||||||
|
|
||||||
|
if (frame->need_recomposite || frame->composited == NULL) {
|
||||||
|
/* For now, to composite we start with the last
|
||||||
|
* composited frame and composite everything up to
|
||||||
|
* here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Rewind to last composited frame. */
|
||||||
|
tmp = link;
|
||||||
|
while (tmp != NULL) {
|
||||||
|
GdkPixbufFrame *f = tmp->data;
|
||||||
|
|
||||||
|
if (f->need_recomposite) {
|
||||||
|
if (f->composited) {
|
||||||
|
g_object_unref (G_OBJECT (f->composited));
|
||||||
|
f->composited = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f->composited != NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
tmp = tmp->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Go forward, compositing all frames up to the current frame */
|
||||||
|
if (tmp == NULL)
|
||||||
|
tmp = gif_anim->frames;
|
||||||
|
|
||||||
|
while (tmp != NULL) {
|
||||||
|
GdkPixbufFrame *f = tmp->data;
|
||||||
|
|
||||||
|
if (f->need_recomposite) {
|
||||||
|
if (f->composited) {
|
||||||
|
g_object_unref (G_OBJECT (f->composited));
|
||||||
|
f->composited = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f->composited != NULL)
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
if (tmp->prev == NULL) {
|
||||||
|
/* First frame may be smaller than the whole image;
|
||||||
|
* if so, we make the area outside it full alpha if the
|
||||||
|
* image has alpha, and background color otherwise.
|
||||||
|
* GIF spec doesn't actually say what to do about this.
|
||||||
|
*/
|
||||||
|
f->composited = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
|
||||||
|
TRUE,
|
||||||
|
8, gif_anim->width, gif_anim->height);
|
||||||
|
|
||||||
|
/* alpha gets dumped if f->composited has no alpha */
|
||||||
|
|
||||||
|
gdk_pixbuf_fill (f->composited,
|
||||||
|
(gif_anim->bg_red << 24) |
|
||||||
|
(gif_anim->bg_green << 16) |
|
||||||
|
(gif_anim->bg_blue << 8) |
|
||||||
|
(f->bg_transparent ? 0 : 255));
|
||||||
|
|
||||||
|
gdk_pixbuf_composite (f->pixbuf,
|
||||||
|
f->composited,
|
||||||
|
f->x_offset,
|
||||||
|
f->y_offset,
|
||||||
|
gdk_pixbuf_get_width (f->pixbuf),
|
||||||
|
gdk_pixbuf_get_height (f->pixbuf),
|
||||||
|
f->x_offset, f->y_offset,
|
||||||
|
1.0, 1.0,
|
||||||
|
GDK_INTERP_BILINEAR,
|
||||||
|
255);
|
||||||
|
#if 0
|
||||||
|
gdk_pixbuf_copy_area (f->pixbuf,
|
||||||
|
0, 0,
|
||||||
|
gdk_pixbuf_get_width (f->pixbuf),
|
||||||
|
gdk_pixbuf_get_height (f->pixbuf),
|
||||||
|
f->composited,
|
||||||
|
f->x_offset,
|
||||||
|
f->y_offset);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (f->action == GDK_PIXBUF_FRAME_REVERT)
|
||||||
|
g_warning ("First frame of GIF has bad dispose mode, GIF loader should not have loaded this image");
|
||||||
|
|
||||||
|
f->need_recomposite = FALSE;
|
||||||
|
} else {
|
||||||
|
GdkPixbufFrame *prev_frame;
|
||||||
|
|
||||||
|
prev_frame = tmp->prev->data;
|
||||||
|
|
||||||
|
/* Init f->composited with what we should have after the previous
|
||||||
|
* frame
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (prev_frame->action == GDK_PIXBUF_FRAME_RETAIN) {
|
||||||
|
f->composited = gdk_pixbuf_copy (prev_frame->composited);
|
||||||
|
|
||||||
|
} else if (prev_frame->action == GDK_PIXBUF_FRAME_DISPOSE) {
|
||||||
|
GdkPixbuf *area;
|
||||||
|
|
||||||
|
f->composited = gdk_pixbuf_copy (prev_frame->composited);
|
||||||
|
|
||||||
|
/* Clear area of previous frame to background */
|
||||||
|
area = gdk_pixbuf_new_subpixbuf (f->composited,
|
||||||
|
prev_frame->x_offset,
|
||||||
|
prev_frame->y_offset,
|
||||||
|
gdk_pixbuf_get_width (prev_frame->pixbuf),
|
||||||
|
gdk_pixbuf_get_height (prev_frame->pixbuf));
|
||||||
|
|
||||||
|
gdk_pixbuf_fill (area,
|
||||||
|
(gif_anim->bg_red << 24) |
|
||||||
|
(gif_anim->bg_green << 16) |
|
||||||
|
(gif_anim->bg_blue << 8) |
|
||||||
|
prev_frame->bg_transparent ? 0 : 255);
|
||||||
|
|
||||||
|
g_object_unref (G_OBJECT (area));
|
||||||
|
|
||||||
|
} else if (prev_frame->action == GDK_PIXBUF_FRAME_REVERT) {
|
||||||
|
f->composited = gdk_pixbuf_copy (prev_frame->composited);
|
||||||
|
|
||||||
|
/* Copy in the revert frame */
|
||||||
|
gdk_pixbuf_copy_area (prev_frame->revert,
|
||||||
|
0, 0,
|
||||||
|
gdk_pixbuf_get_width (prev_frame->revert),
|
||||||
|
gdk_pixbuf_get_height (prev_frame->revert),
|
||||||
|
f->composited,
|
||||||
|
prev_frame->x_offset,
|
||||||
|
prev_frame->y_offset);
|
||||||
|
} else {
|
||||||
|
g_warning ("Unknown revert action for GIF frame");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f->revert == NULL &&
|
||||||
|
f->action == GDK_PIXBUF_FRAME_REVERT) {
|
||||||
|
/* We need to save the contents before compositing */
|
||||||
|
GdkPixbuf *area;
|
||||||
|
|
||||||
|
area = gdk_pixbuf_new_subpixbuf (f->composited,
|
||||||
|
f->x_offset,
|
||||||
|
f->y_offset,
|
||||||
|
gdk_pixbuf_get_width (f->pixbuf),
|
||||||
|
gdk_pixbuf_get_height (f->pixbuf));
|
||||||
|
|
||||||
|
f->revert = gdk_pixbuf_copy (area);
|
||||||
|
|
||||||
|
g_object_unref (G_OBJECT (area));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put current frame onto f->composited */
|
||||||
|
gdk_pixbuf_composite (f->pixbuf,
|
||||||
|
f->composited,
|
||||||
|
f->x_offset,
|
||||||
|
f->y_offset,
|
||||||
|
gdk_pixbuf_get_width (f->pixbuf),
|
||||||
|
gdk_pixbuf_get_height (f->pixbuf),
|
||||||
|
f->x_offset, f->y_offset,
|
||||||
|
1.0, 1.0,
|
||||||
|
GDK_INTERP_NEAREST,
|
||||||
|
255);
|
||||||
|
|
||||||
|
f->need_recomposite = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
next:
|
||||||
|
if (tmp == link)
|
||||||
|
break;
|
||||||
|
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert (frame->composited != NULL);
|
||||||
|
g_assert (gdk_pixbuf_get_width (frame->composited) == gif_anim->width);
|
||||||
|
g_assert (gdk_pixbuf_get_height (frame->composited) == gif_anim->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
GdkPixbuf*
|
||||||
|
gdk_pixbuf_gif_anim_iter_get_pixbuf (GdkPixbufAnimationIter *anim_iter)
|
||||||
|
{
|
||||||
|
GdkPixbufGifAnimIter *iter;
|
||||||
|
GdkPixbufFrame *frame;
|
||||||
|
|
||||||
|
iter = GDK_PIXBUF_GIF_ANIM_ITER (anim_iter);
|
||||||
|
|
||||||
|
frame = iter->current_frame ? iter->current_frame->data : NULL;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (FALSE && frame)
|
||||||
|
g_print ("current frame %d dispose mode %d %d x %d\n",
|
||||||
|
g_list_index (iter->gif_anim->frames,
|
||||||
|
frame),
|
||||||
|
frame->action,
|
||||||
|
gdk_pixbuf_get_width (frame->pixbuf),
|
||||||
|
gdk_pixbuf_get_height (frame->pixbuf));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (frame == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
gdk_pixbuf_gif_anim_frame_composite (iter->gif_anim, frame);
|
||||||
|
|
||||||
|
return frame->composited;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdk_pixbuf_gif_anim_iter_on_currently_loading_frame (GdkPixbufAnimationIter *anim_iter)
|
||||||
|
{
|
||||||
|
GdkPixbufGifAnimIter *iter;
|
||||||
|
|
||||||
|
iter = GDK_PIXBUF_GIF_ANIM_ITER (anim_iter);
|
||||||
|
|
||||||
|
return iter->current_frame == NULL || iter->current_frame->next == NULL;
|
||||||
|
}
|
169
gdk-pixbuf/io-gif-animation.h
Normal file
169
gdk-pixbuf/io-gif-animation.h
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
|
||||||
|
/* GdkPixbuf library - GIF loader declarations
|
||||||
|
*
|
||||||
|
* Copyright (C) 1999 The Free Software Foundation
|
||||||
|
*
|
||||||
|
* Authors: Mark Crichton <crichton@gimp.org>
|
||||||
|
* Miguel de Icaza <miguel@gnu.org>
|
||||||
|
* Federico Mena-Quintero <federico@gimp.org>
|
||||||
|
* Havoc Pennington <hp@redhat.com>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GDK_PIXBUF_GIF_H
|
||||||
|
#define GDK_PIXBUF_GIF_H
|
||||||
|
|
||||||
|
#include "gdk-pixbuf-private.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* Keep this frame and composite next frame over it */
|
||||||
|
/* (GIF disposal method 1) */
|
||||||
|
GDK_PIXBUF_FRAME_RETAIN,
|
||||||
|
/* Revert to background color before compositing next frame */
|
||||||
|
/* (GIF disposal method 2) */
|
||||||
|
GDK_PIXBUF_FRAME_DISPOSE,
|
||||||
|
/* Revert to previously-displayed composite image after
|
||||||
|
* displaying this frame
|
||||||
|
*/
|
||||||
|
/* (GIF disposal method 3) */
|
||||||
|
GDK_PIXBUF_FRAME_REVERT
|
||||||
|
} GdkPixbufFrameAction;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _GdkPixbufGifAnim GdkPixbufGifAnim;
|
||||||
|
typedef struct _GdkPixbufGifAnimClass GdkPixbufGifAnimClass;
|
||||||
|
|
||||||
|
#define GDK_TYPE_PIXBUF_GIF_ANIM (gdk_pixbuf_gif_anim_get_type ())
|
||||||
|
#define GDK_PIXBUF_GIF_ANIM(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_GIF_ANIM, GdkPixbufGifAnim))
|
||||||
|
#define GDK_IS_PIXBUF_GIF_ANIM(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_GIF_ANIM))
|
||||||
|
|
||||||
|
#define GDK_PIXBUF_GIF_ANIM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_GIF_ANIM, GdkPixbufGifAnimClass))
|
||||||
|
#define GDK_IS_PIXBUF_GIF_ANIM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_GIF_ANIM))
|
||||||
|
#define GDK_PIXBUF_GIF_ANIM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_GIF_ANIM, GdkPixbufGifAnimClass))
|
||||||
|
|
||||||
|
/* Private part of the GdkPixbufGifAnim structure */
|
||||||
|
struct _GdkPixbufGifAnim {
|
||||||
|
GdkPixbufAnimation parent_instance;
|
||||||
|
|
||||||
|
/* Number of frames */
|
||||||
|
int n_frames;
|
||||||
|
|
||||||
|
/* Total length of animation */
|
||||||
|
int total_time;
|
||||||
|
|
||||||
|
/* List of GdkPixbufFrame structures */
|
||||||
|
GList *frames;
|
||||||
|
|
||||||
|
/* bounding box size */
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
guchar bg_red;
|
||||||
|
guchar bg_green;
|
||||||
|
guchar bg_blue;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GdkPixbufGifAnimClass {
|
||||||
|
GdkPixbufAnimationClass parent_class;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
GType gdk_pixbuf_gif_anim_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _GdkPixbufGifAnimIter GdkPixbufGifAnimIter;
|
||||||
|
typedef struct _GdkPixbufGifAnimIterClass GdkPixbufGifAnimIterClass;
|
||||||
|
|
||||||
|
|
||||||
|
#define GDK_TYPE_PIXBUF_GIF_ANIM_ITER (gdk_pixbuf_gif_anim_iter_get_type ())
|
||||||
|
#define GDK_PIXBUF_GIF_ANIM_ITER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_GIF_ANIM_ITER, GdkPixbufGifAnimIter))
|
||||||
|
#define GDK_IS_PIXBUF_GIF_ANIM_ITER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_GIF_ANIM_ITER))
|
||||||
|
|
||||||
|
#define GDK_PIXBUF_GIF_ANIM_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_GIF_ANIM_ITER, GdkPixbufGifAnimIterClass))
|
||||||
|
#define GDK_IS_PIXBUF_GIF_ANIM_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_GIF_ANIM_ITER))
|
||||||
|
#define GDK_PIXBUF_GIF_ANIM_ITER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_GIF_ANIM_ITER, GdkPixbufGifAnimIterClass))
|
||||||
|
|
||||||
|
struct _GdkPixbufGifAnimIter {
|
||||||
|
GdkPixbufAnimationIter parent_instance;
|
||||||
|
|
||||||
|
GdkPixbufGifAnim *gif_anim;
|
||||||
|
|
||||||
|
GTimeVal start_time;
|
||||||
|
GTimeVal current_time;
|
||||||
|
|
||||||
|
/* Time in milliseconds into this run of the animation */
|
||||||
|
gint position;
|
||||||
|
|
||||||
|
GList *current_frame;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GdkPixbufGifAnimIterClass {
|
||||||
|
GdkPixbufAnimationIterClass parent_class;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
GType gdk_pixbuf_gif_anim_iter_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct _GdkPixbufFrame {
|
||||||
|
/* The pixbuf with this frame's image data */
|
||||||
|
GdkPixbuf *pixbuf;
|
||||||
|
|
||||||
|
/* Offsets for overlaying onto the GIF graphic area */
|
||||||
|
int x_offset;
|
||||||
|
int y_offset;
|
||||||
|
|
||||||
|
/* Frame duration in ms */
|
||||||
|
int delay_time;
|
||||||
|
|
||||||
|
/* Sum of preceding delay times */
|
||||||
|
int elapsed;
|
||||||
|
|
||||||
|
/* Overlay mode */
|
||||||
|
GdkPixbufFrameAction action;
|
||||||
|
|
||||||
|
/* TRUE if the pixbuf has been modified since
|
||||||
|
* the last frame composite operation
|
||||||
|
*/
|
||||||
|
gboolean need_recomposite;
|
||||||
|
|
||||||
|
/* TRUE if the background for this frame is transparent */
|
||||||
|
gboolean bg_transparent;
|
||||||
|
|
||||||
|
/* The below reflects the "use hell of a lot of RAM"
|
||||||
|
* philosophy of coding
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Cached composite image (the image you actually display
|
||||||
|
* for this frame)
|
||||||
|
*/
|
||||||
|
GdkPixbuf *composited;
|
||||||
|
|
||||||
|
/* Cached revert image (the contents of the area
|
||||||
|
* covered by the frame prior to compositing;
|
||||||
|
* same size as pixbuf, not as the composite image; only
|
||||||
|
* used for FRAME_REVERT frames)
|
||||||
|
*/
|
||||||
|
GdkPixbuf *revert;
|
||||||
|
};
|
||||||
|
|
||||||
|
void gdk_pixbuf_gif_anim_frame_composite (GdkPixbufGifAnim *gif_anim,
|
||||||
|
GdkPixbufFrame *frame);
|
||||||
|
|
||||||
|
#endif
|
@ -1,3 +1,4 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
|
||||||
/* GdkPixbuf library - GIF image loader
|
/* GdkPixbuf library - GIF image loader
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999 Mark Crichton
|
* Copyright (C) 1999 Mark Crichton
|
||||||
@ -30,10 +31,6 @@
|
|||||||
* in it got a bit messy. Basicly, every function is written to expect a failed
|
* in it got a bit messy. Basicly, every function is written to expect a failed
|
||||||
* read_gif, and lets you call it again assuming that the bytes are there.
|
* read_gif, and lets you call it again assuming that the bytes are there.
|
||||||
*
|
*
|
||||||
* A note on Animations:
|
|
||||||
* Currently, it doesn't correctly read the different colormap per frame. This
|
|
||||||
* needs implementing sometime.
|
|
||||||
*
|
|
||||||
* Return vals.
|
* Return vals.
|
||||||
* Unless otherwise specified, these are the return vals for most functions:
|
* Unless otherwise specified, these are the return vals for most functions:
|
||||||
*
|
*
|
||||||
@ -59,11 +56,15 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
#include "gdk-pixbuf-private.h"
|
#include "gdk-pixbuf-private.h"
|
||||||
#include "gdk-pixbuf-io.h"
|
#include "gdk-pixbuf-io.h"
|
||||||
|
#include "io-gif-animation.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#undef DUMP_IMAGE_DETAILS
|
||||||
|
|
||||||
#define MAXCOLORMAPSIZE 256
|
#define MAXCOLORMAPSIZE 256
|
||||||
#define MAX_LZW_BITS 12
|
#define MAX_LZW_BITS 12
|
||||||
|
|
||||||
@ -88,7 +89,7 @@ enum {
|
|||||||
GIF_LZW_FILL_BUFFER,
|
GIF_LZW_FILL_BUFFER,
|
||||||
GIF_LZW_CLEAR_CODE,
|
GIF_LZW_CLEAR_CODE,
|
||||||
GIF_GET_LZW,
|
GIF_GET_LZW,
|
||||||
GIF_DONE,
|
GIF_DONE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -107,19 +108,27 @@ struct _GifContext
|
|||||||
int state; /* really only relevant for progressive loading */
|
int state; /* really only relevant for progressive loading */
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
CMap color_map;
|
|
||||||
|
gboolean has_global_cmap;
|
||||||
|
|
||||||
|
CMap global_color_map;
|
||||||
|
gint global_colormap_size;
|
||||||
|
unsigned int global_bit_pixel;
|
||||||
|
unsigned int global_color_resolution;
|
||||||
|
unsigned int background_index;
|
||||||
|
|
||||||
|
gboolean frame_cmap_active;
|
||||||
CMap frame_color_map;
|
CMap frame_color_map;
|
||||||
unsigned int bit_pixel;
|
gint frame_colormap_size;
|
||||||
unsigned int color_resolution;
|
unsigned int frame_bit_pixel;
|
||||||
unsigned int background;
|
|
||||||
unsigned int aspect_ratio;
|
unsigned int aspect_ratio;
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
GdkPixbufAnimation *animation;
|
GdkPixbufGifAnim *animation;
|
||||||
GdkPixbufFrame *frame;
|
GdkPixbufFrame *frame;
|
||||||
Gif89 gif89;
|
Gif89 gif89;
|
||||||
|
|
||||||
/* stuff per frame. As we only support the first one, not so
|
/* stuff per frame. */
|
||||||
* relevant. But still needed */
|
|
||||||
int frame_len;
|
int frame_len;
|
||||||
int frame_height;
|
int frame_height;
|
||||||
int frame_interlace;
|
int frame_interlace;
|
||||||
@ -132,18 +141,12 @@ struct _GifContext
|
|||||||
/* progressive read, only. */
|
/* progressive read, only. */
|
||||||
ModulePreparedNotifyFunc prepare_func;
|
ModulePreparedNotifyFunc prepare_func;
|
||||||
ModuleUpdatedNotifyFunc update_func;
|
ModuleUpdatedNotifyFunc update_func;
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func;
|
|
||||||
ModuleAnimationDoneNotifyFunc anim_done_func;
|
|
||||||
gpointer user_data;
|
gpointer user_data;
|
||||||
guchar *buf;
|
guchar *buf;
|
||||||
guint ptr;
|
guint ptr;
|
||||||
guint size;
|
guint size;
|
||||||
guint amount_needed;
|
guint amount_needed;
|
||||||
|
|
||||||
/* colormap context */
|
|
||||||
gint colormap_index;
|
|
||||||
gint colormap_flag;
|
|
||||||
|
|
||||||
/* extension context */
|
/* extension context */
|
||||||
guchar extension_label;
|
guchar extension_label;
|
||||||
guchar extension_flag;
|
guchar extension_flag;
|
||||||
@ -208,6 +211,13 @@ gif_read (GifContext *context, guchar *buffer, size_t len)
|
|||||||
g_print ("Fsize :%d\tcount :%d\t", len, count);
|
g_print ("Fsize :%d\tcount :%d\t", len, count);
|
||||||
#endif
|
#endif
|
||||||
retval = (fread(buffer, len, 1, context->file) != 0);
|
retval = (fread(buffer, len, 1, context->file) != 0);
|
||||||
|
|
||||||
|
if (!retval && ferror (context->file))
|
||||||
|
g_set_error (context->error,
|
||||||
|
G_FILE_ERROR,
|
||||||
|
g_file_error_from_errno (errno),
|
||||||
|
_("Failure reading GIF: %s"), strerror (errno));
|
||||||
|
|
||||||
#ifdef IO_GIFDEBUG
|
#ifdef IO_GIFDEBUG
|
||||||
if (len < 100) {
|
if (len < 100) {
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
@ -247,16 +257,14 @@ gif_read (GifContext *context, guchar *buffer, size_t len)
|
|||||||
static void
|
static void
|
||||||
gif_set_get_colormap (GifContext *context)
|
gif_set_get_colormap (GifContext *context)
|
||||||
{
|
{
|
||||||
context->colormap_flag = TRUE;
|
context->global_colormap_size = 0;
|
||||||
context->colormap_index = 0;
|
|
||||||
context->state = GIF_GET_COLORMAP;
|
context->state = GIF_GET_COLORMAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gif_set_get_colormap2 (GifContext *context)
|
gif_set_get_colormap2 (GifContext *context)
|
||||||
{
|
{
|
||||||
context->colormap_flag = TRUE;
|
context->frame_colormap_size = 0;
|
||||||
context->colormap_index = 0;
|
|
||||||
context->state = GIF_GET_COLORMAP2;
|
context->state = GIF_GET_COLORMAP2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,18 +273,43 @@ gif_get_colormap (GifContext *context)
|
|||||||
{
|
{
|
||||||
unsigned char rgb[3];
|
unsigned char rgb[3];
|
||||||
|
|
||||||
while (context->colormap_index < context->bit_pixel) {
|
while (context->global_colormap_size < context->global_bit_pixel) {
|
||||||
if (!gif_read (context, rgb, sizeof (rgb))) {
|
if (!gif_read (context, rgb, sizeof (rgb))) {
|
||||||
/*g_message (_("GIF: bad colormap\n"));*/
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->color_map[0][context->colormap_index] = rgb[0];
|
context->global_color_map[0][context->global_colormap_size] = rgb[0];
|
||||||
context->color_map[1][context->colormap_index] = rgb[1];
|
context->global_color_map[1][context->global_colormap_size] = rgb[1];
|
||||||
context->color_map[2][context->colormap_index] = rgb[2];
|
context->global_color_map[2][context->global_colormap_size] = rgb[2];
|
||||||
|
|
||||||
context->colormap_flag &= (rgb[0] == rgb[1] && rgb[1] == rgb[2]);
|
if (context->global_colormap_size == context->background_index) {
|
||||||
context->colormap_index ++;
|
context->animation->bg_red = rgb[0];
|
||||||
|
context->animation->bg_green = rgb[1];
|
||||||
|
context->animation->bg_blue = rgb[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
context->global_colormap_size ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gint
|
||||||
|
gif_get_colormap2 (GifContext *context)
|
||||||
|
{
|
||||||
|
unsigned char rgb[3];
|
||||||
|
|
||||||
|
while (context->frame_colormap_size < context->frame_bit_pixel) {
|
||||||
|
if (!gif_read (context, rgb, sizeof (rgb))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
context->frame_color_map[0][context->frame_colormap_size] = rgb[0];
|
||||||
|
context->frame_color_map[1][context->frame_colormap_size] = rgb[1];
|
||||||
|
context->frame_color_map[2][context->frame_colormap_size] = rgb[2];
|
||||||
|
|
||||||
|
context->frame_colormap_size ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -348,9 +381,11 @@ gif_get_extension (GifContext *context)
|
|||||||
retval = get_data_block (context, (unsigned char *) context->block_buf, NULL);
|
retval = get_data_block (context, (unsigned char *) context->block_buf, NULL);
|
||||||
if (retval != 0)
|
if (retval != 0)
|
||||||
return retval;
|
return retval;
|
||||||
if (context->pixbuf == NULL) {
|
|
||||||
|
if (context->frame == NULL) {
|
||||||
/* I only want to set the transparency if I haven't
|
/* I only want to set the transparency if I haven't
|
||||||
* created the pixbuf yet. */
|
* created the frame yet.
|
||||||
|
*/
|
||||||
context->gif89.disposal = (context->block_buf[0] >> 2) & 0x7;
|
context->gif89.disposal = (context->block_buf[0] >> 2) & 0x7;
|
||||||
context->gif89.input_flag = (context->block_buf[0] >> 1) & 0x1;
|
context->gif89.input_flag = (context->block_buf[0] >> 1) & 0x1;
|
||||||
context->gif89.delay_time = LM_to_uint (context->block_buf[1], context->block_buf[2]);
|
context->gif89.delay_time = LM_to_uint (context->block_buf[1], context->block_buf[2]);
|
||||||
@ -623,18 +658,24 @@ static void
|
|||||||
gif_fill_in_pixels (GifContext *context, guchar *dest, gint offset, guchar v)
|
gif_fill_in_pixels (GifContext *context, guchar *dest, gint offset, guchar v)
|
||||||
{
|
{
|
||||||
guchar *pixel = NULL;
|
guchar *pixel = NULL;
|
||||||
|
guchar (*cmap)[MAXCOLORMAPSIZE];
|
||||||
|
|
||||||
|
if (context->frame_cmap_active)
|
||||||
|
cmap = context->frame_color_map;
|
||||||
|
else
|
||||||
|
cmap = context->global_color_map;
|
||||||
|
|
||||||
if (context->gif89.transparent != -1) {
|
if (context->gif89.transparent != -1) {
|
||||||
pixel = dest + (context->draw_ypos + offset) * gdk_pixbuf_get_rowstride (context->pixbuf) + context->draw_xpos * 4;
|
pixel = dest + (context->draw_ypos + offset) * gdk_pixbuf_get_rowstride (context->frame->pixbuf) + context->draw_xpos * 4;
|
||||||
*pixel = context->color_map [0][(guchar) v];
|
*pixel = cmap [0][(guchar) v];
|
||||||
*(pixel+1) = context->color_map [1][(guchar) v];
|
*(pixel+1) = cmap [1][(guchar) v];
|
||||||
*(pixel+2) = context->color_map [2][(guchar) v];
|
*(pixel+2) = cmap [2][(guchar) v];
|
||||||
*(pixel+3) = (guchar) ((v == context->gif89.transparent) ? 0 : 65535);
|
*(pixel+3) = (guchar) ((v == context->gif89.transparent) ? 0 : 255);
|
||||||
} else {
|
} else {
|
||||||
pixel = dest + (context->draw_ypos + offset) * gdk_pixbuf_get_rowstride (context->pixbuf) + context->draw_xpos * 3;
|
pixel = dest + (context->draw_ypos + offset) * gdk_pixbuf_get_rowstride (context->frame->pixbuf) + context->draw_xpos * 3;
|
||||||
*pixel = context->color_map [0][(guchar) v];
|
*pixel = cmap [0][(guchar) v];
|
||||||
*(pixel+1) = context->color_map [1][(guchar) v];
|
*(pixel+1) = cmap [1][(guchar) v];
|
||||||
*(pixel+2) = context->color_map [2][(guchar) v];
|
*(pixel+2) = cmap [2][(guchar) v];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,20 +723,28 @@ gif_get_lzw (GifContext *context)
|
|||||||
gint first_pass; /* bounds for emitting the area_updated signal */
|
gint first_pass; /* bounds for emitting the area_updated signal */
|
||||||
gint v;
|
gint v;
|
||||||
|
|
||||||
if (context->pixbuf == NULL) {
|
if (context->frame == NULL) {
|
||||||
context->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
|
context->frame = g_new (GdkPixbufFrame, 1);
|
||||||
context->gif89.transparent != -1,
|
|
||||||
|
context->frame->composited = NULL;
|
||||||
|
context->frame->revert = NULL;
|
||||||
|
|
||||||
|
context->frame->pixbuf =
|
||||||
|
gdk_pixbuf_new (GDK_COLORSPACE_RGB,
|
||||||
|
TRUE,
|
||||||
8,
|
8,
|
||||||
context->frame_len,
|
context->frame_len,
|
||||||
context->frame_height);
|
context->frame_height);
|
||||||
|
|
||||||
if (context->prepare_func)
|
|
||||||
(* context->prepare_func) (context->pixbuf, context->user_data);
|
|
||||||
if (context->animation || context->frame_done_func || context->anim_done_func) {
|
|
||||||
context->frame = g_new (GdkPixbufFrame, 1);
|
|
||||||
context->frame->x_offset = context->x_offset;
|
context->frame->x_offset = context->x_offset;
|
||||||
context->frame->y_offset = context->y_offset;;
|
context->frame->y_offset = context->y_offset;
|
||||||
context->frame->delay_time = context->gif89.delay_time;
|
context->frame->need_recomposite = TRUE;
|
||||||
|
|
||||||
|
/* GIF delay is in hundredths, we want thousandths */
|
||||||
|
context->frame->delay_time = context->gif89.delay_time * 10;
|
||||||
|
context->frame->elapsed = context->animation->total_time;
|
||||||
|
context->animation->total_time += context->frame->delay_time;
|
||||||
|
|
||||||
switch (context->gif89.disposal) {
|
switch (context->gif89.disposal) {
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
@ -711,45 +760,80 @@ gif_get_lzw (GifContext *context)
|
|||||||
context->frame->action = GDK_PIXBUF_FRAME_RETAIN;
|
context->frame->action = GDK_PIXBUF_FRAME_RETAIN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
context->frame->pixbuf = context->pixbuf;
|
|
||||||
if (context->animation) {
|
context->frame->bg_transparent = (context->gif89.transparent == context->background_index);
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Update animation size */
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
context->animation->n_frames ++;
|
context->animation->n_frames ++;
|
||||||
context->animation->frames = g_list_append (context->animation->frames, context->frame);
|
context->animation->frames = g_list_append (context->animation->frames, context->frame);
|
||||||
w = gdk_pixbuf_get_width (context->pixbuf);
|
|
||||||
h = gdk_pixbuf_get_height (context->pixbuf);
|
w = context->frame->x_offset +
|
||||||
|
gdk_pixbuf_get_width (context->frame->pixbuf);
|
||||||
|
h = context->frame->y_offset +
|
||||||
|
gdk_pixbuf_get_height (context->frame->pixbuf);
|
||||||
if (w > context->animation->width)
|
if (w > context->animation->width)
|
||||||
context->animation->width = w;
|
context->animation->width = w;
|
||||||
if (h > context->animation->height)
|
if (h > context->animation->height)
|
||||||
context->animation->height = h;
|
context->animation->height = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only call prepare_func for the first frame */
|
||||||
|
if (context->animation->frames->next == NULL) {
|
||||||
|
if (context->prepare_func)
|
||||||
|
(* context->prepare_func) (context->frame->pixbuf,
|
||||||
|
GDK_PIXBUF_ANIMATION (context->animation),
|
||||||
|
context->user_data);
|
||||||
|
} else {
|
||||||
|
/* Otherwise init frame with last frame */
|
||||||
|
GList *link;
|
||||||
|
GdkPixbufFrame *prev_frame;
|
||||||
|
|
||||||
|
link = g_list_find (context->animation->frames, context->frame);
|
||||||
|
|
||||||
|
prev_frame = link->prev->data;
|
||||||
|
|
||||||
|
gdk_pixbuf_gif_anim_frame_composite (context->animation, prev_frame);
|
||||||
|
|
||||||
|
gdk_pixbuf_copy_area (prev_frame->composited,
|
||||||
|
context->frame->x_offset,
|
||||||
|
context->frame->y_offset,
|
||||||
|
gdk_pixbuf_get_width (context->frame->pixbuf),
|
||||||
|
gdk_pixbuf_get_height (context->frame->pixbuf),
|
||||||
|
context->frame->pixbuf,
|
||||||
|
0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dest = gdk_pixbuf_get_pixels (context->pixbuf);
|
|
||||||
|
dest = gdk_pixbuf_get_pixels (context->frame->pixbuf);
|
||||||
|
|
||||||
bound_flag = FALSE;
|
bound_flag = FALSE;
|
||||||
lower_bound = upper_bound = context->draw_ypos;
|
lower_bound = upper_bound = context->draw_ypos;
|
||||||
first_pass = context->draw_pass;
|
first_pass = context->draw_pass;
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
|
guchar (*cmap)[MAXCOLORMAPSIZE];
|
||||||
|
|
||||||
|
if (context->frame_cmap_active)
|
||||||
|
cmap = context->frame_color_map;
|
||||||
|
else
|
||||||
|
cmap = context->global_color_map;
|
||||||
|
|
||||||
v = lzw_read_byte (context);
|
v = lzw_read_byte (context);
|
||||||
if (v < 0) {
|
if (v < 0) {
|
||||||
goto finished_data;
|
goto finished_data;
|
||||||
}
|
}
|
||||||
bound_flag = TRUE;
|
bound_flag = TRUE;
|
||||||
|
|
||||||
if (context->gif89.transparent != -1) {
|
g_assert (gdk_pixbuf_get_has_alpha (context->frame->pixbuf));
|
||||||
temp = dest + context->draw_ypos * gdk_pixbuf_get_rowstride (context->pixbuf) + context->draw_xpos * 4;
|
|
||||||
*temp = context->color_map [0][(guchar) v];
|
temp = dest + context->draw_ypos * gdk_pixbuf_get_rowstride (context->frame->pixbuf) + context->draw_xpos * 4;
|
||||||
*(temp+1) = context->color_map [1][(guchar) v];
|
*temp = cmap [0][(guchar) v];
|
||||||
*(temp+2) = context->color_map [2][(guchar) v];
|
*(temp+1) = cmap [1][(guchar) v];
|
||||||
*(temp+3) = (guchar) ((v == context->gif89.transparent) ? 0 : -1);
|
*(temp+2) = cmap [2][(guchar) v];
|
||||||
} else {
|
*(temp+3) = (guchar) ((v == context->gif89.transparent) ? 0 : 255);
|
||||||
temp = dest + context->draw_ypos * gdk_pixbuf_get_rowstride (context->pixbuf) + context->draw_xpos * 3;
|
|
||||||
*temp = context->color_map [0][(guchar) v];
|
|
||||||
*(temp+1) = context->color_map [1][(guchar) v];
|
|
||||||
*(temp+2) = context->color_map [2][(guchar) v];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context->prepare_func && context->frame_interlace)
|
if (context->prepare_func && context->frame_interlace)
|
||||||
gif_fill_in_lines (context, dest, v);
|
gif_fill_in_lines (context, dest, v);
|
||||||
@ -804,56 +888,60 @@ gif_get_lzw (GifContext *context)
|
|||||||
if (context->draw_ypos >= context->frame_height)
|
if (context->draw_ypos >= context->frame_height)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
/* we got enough data. there may be more (ie, newer layers) but we can quit now */
|
|
||||||
if (context->animation || context->frame_done_func || context->anim_done_func) {
|
|
||||||
context->state = GIF_GET_NEXT_STEP;
|
context->state = GIF_GET_NEXT_STEP;
|
||||||
} else
|
|
||||||
context->state = GIF_DONE;
|
|
||||||
v = 0;
|
v = 0;
|
||||||
|
|
||||||
finished_data:
|
finished_data:
|
||||||
|
|
||||||
|
if (bound_flag)
|
||||||
|
context->frame->need_recomposite = TRUE;
|
||||||
|
|
||||||
if (bound_flag && context->update_func) {
|
if (bound_flag && context->update_func) {
|
||||||
if (lower_bound <= upper_bound && first_pass == context->draw_pass) {
|
if (lower_bound <= upper_bound && first_pass == context->draw_pass) {
|
||||||
(* context->update_func)
|
(* context->update_func)
|
||||||
(context->pixbuf,
|
(context->frame->pixbuf,
|
||||||
0, lower_bound,
|
0, lower_bound,
|
||||||
gdk_pixbuf_get_width (context->pixbuf),
|
gdk_pixbuf_get_width (context->frame->pixbuf),
|
||||||
upper_bound - lower_bound,
|
upper_bound - lower_bound,
|
||||||
context->user_data);
|
context->user_data);
|
||||||
} else {
|
} else {
|
||||||
if (lower_bound <= upper_bound) {
|
if (lower_bound <= upper_bound) {
|
||||||
(* context->update_func)
|
(* context->update_func)
|
||||||
(context->pixbuf,
|
(context->frame->pixbuf,
|
||||||
0, 0,
|
context->frame->x_offset,
|
||||||
gdk_pixbuf_get_width (context->pixbuf),
|
context->frame->y_offset,
|
||||||
gdk_pixbuf_get_height (context->pixbuf),
|
gdk_pixbuf_get_width (context->frame->pixbuf),
|
||||||
|
gdk_pixbuf_get_height (context->frame->pixbuf),
|
||||||
context->user_data);
|
context->user_data);
|
||||||
} else {
|
} else {
|
||||||
(* context->update_func)
|
(* context->update_func)
|
||||||
(context->pixbuf,
|
(context->frame->pixbuf,
|
||||||
0, 0,
|
context->frame->x_offset,
|
||||||
gdk_pixbuf_get_width (context->pixbuf),
|
context->frame->y_offset,
|
||||||
|
gdk_pixbuf_get_width (context->frame->pixbuf),
|
||||||
upper_bound,
|
upper_bound,
|
||||||
context->user_data);
|
context->user_data);
|
||||||
(* context->update_func)
|
(* context->update_func)
|
||||||
(context->pixbuf,
|
(context->frame->pixbuf,
|
||||||
0, lower_bound,
|
context->frame->x_offset,
|
||||||
gdk_pixbuf_get_width (context->pixbuf),
|
lower_bound + context->frame->y_offset,
|
||||||
gdk_pixbuf_get_height (context->pixbuf),
|
gdk_pixbuf_get_width (context->frame->pixbuf),
|
||||||
|
gdk_pixbuf_get_height (context->frame->pixbuf),
|
||||||
context->user_data);
|
context->user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((context->animation || context->frame_done_func || context->anim_done_func)
|
if (context->state == GIF_GET_NEXT_STEP) {
|
||||||
&& context->state == GIF_GET_NEXT_STEP) {
|
/* Will be freed with context->animation, we are just
|
||||||
if (context->frame_done_func)
|
* marking that we're done with it (no current frame)
|
||||||
(* context->frame_done_func) (context->frame,
|
*/
|
||||||
context->user_data);
|
|
||||||
if (context->frame_done_func)
|
|
||||||
gdk_pixbuf_unref (context->pixbuf);
|
|
||||||
context->pixbuf = NULL;
|
|
||||||
context->frame = NULL;
|
context->frame = NULL;
|
||||||
|
context->frame_cmap_active = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
@ -943,16 +1031,36 @@ gif_init (GifContext *context)
|
|||||||
|
|
||||||
context->width = LM_to_uint (buf[0], buf[1]);
|
context->width = LM_to_uint (buf[0], buf[1]);
|
||||||
context->height = LM_to_uint (buf[2], buf[3]);
|
context->height = LM_to_uint (buf[2], buf[3]);
|
||||||
context->bit_pixel = 2 << (buf[4] & 0x07);
|
/* The 4th byte is
|
||||||
context->color_resolution = (((buf[4] & 0x70) >> 3) + 1);
|
* high bit: whether to use the background index
|
||||||
context->background = buf[5];
|
* next 3: color resolution
|
||||||
|
* next: whether colormap is sorted by priority of allocation
|
||||||
|
* last 3: size of colormap
|
||||||
|
*/
|
||||||
|
context->global_bit_pixel = 2 << (buf[4] & 0x07);
|
||||||
|
context->global_color_resolution = (((buf[4] & 0x70) >> 3) + 1);
|
||||||
|
context->has_global_cmap = (buf[4] & 0x80) != 0;
|
||||||
|
context->background_index = buf[5];
|
||||||
context->aspect_ratio = buf[6];
|
context->aspect_ratio = buf[6];
|
||||||
|
|
||||||
if (BitSet (buf[4], LOCALCOLORMAP)) {
|
/* Use background of transparent black as default, though if
|
||||||
|
* one isn't set explicitly no one should ever use it.
|
||||||
|
*/
|
||||||
|
context->animation->bg_red = 0;
|
||||||
|
context->animation->bg_green = 0;
|
||||||
|
context->animation->bg_blue = 0;
|
||||||
|
|
||||||
|
if (context->has_global_cmap) {
|
||||||
gif_set_get_colormap (context);
|
gif_set_get_colormap (context);
|
||||||
} else {
|
} else {
|
||||||
context->state = GIF_GET_NEXT_STEP;
|
context->state = GIF_GET_NEXT_STEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DUMP_IMAGE_DETAILS
|
||||||
|
g_print (">Image width: %d height: %d global_cmap: %d background: %d\n",
|
||||||
|
context->width, context->height, context->has_global_cmap, context->background_index);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -966,38 +1074,81 @@ static gint
|
|||||||
gif_get_frame_info (GifContext *context)
|
gif_get_frame_info (GifContext *context)
|
||||||
{
|
{
|
||||||
unsigned char buf[9];
|
unsigned char buf[9];
|
||||||
|
|
||||||
if (!gif_read (context, buf, 9)) {
|
if (!gif_read (context, buf, 9)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Okay, we got all the info we need. Lets record it */
|
/* Okay, we got all the info we need. Lets record it */
|
||||||
context->frame_len = LM_to_uint (buf[4], buf[5]);
|
context->frame_len = LM_to_uint (buf[4], buf[5]);
|
||||||
context->frame_height = LM_to_uint (buf[6], buf[7]);
|
context->frame_height = LM_to_uint (buf[6], buf[7]);
|
||||||
context->x_offset = LM_to_uint (buf[0], buf[1]);
|
context->x_offset = LM_to_uint (buf[0], buf[1]);
|
||||||
context->y_offset = LM_to_uint (buf[2], buf[3]);
|
context->y_offset = LM_to_uint (buf[2], buf[3]);
|
||||||
|
|
||||||
if (context->frame_height > context->height) {
|
if (((context->frame_height + context->y_offset) > context->height) ||
|
||||||
/* we don't want to resize things. So we exit */
|
((context->frame_len + context->x_offset) > context->width)) {
|
||||||
|
/* All frames must fit in the image bounds */
|
||||||
context->state = GIF_DONE;
|
context->state = GIF_DONE;
|
||||||
|
|
||||||
g_set_error (context->error,
|
g_set_error (context->error,
|
||||||
GDK_PIXBUF_ERROR,
|
GDK_PIXBUF_ERROR,
|
||||||
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
|
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
|
||||||
_("GIF animation contained a frame with an incorrect size"));
|
_("GIF image contained a frame appearing outside the image bounds."));
|
||||||
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context->animation->frames == NULL &&
|
||||||
|
context->gif89.disposal == 3) {
|
||||||
|
/* First frame can't have "revert to previous" as its
|
||||||
|
* dispose mode.
|
||||||
|
*/
|
||||||
|
|
||||||
|
context->state = GIF_DONE;
|
||||||
|
|
||||||
|
g_set_error (context->error,
|
||||||
|
GDK_PIXBUF_ERROR,
|
||||||
|
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
|
||||||
|
_("First frame of GIF image had 'revert to previous' as its disposal mode."));
|
||||||
|
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DUMP_IMAGE_DETAILS
|
||||||
|
g_print (">width: %d height: %d xoffset: %d yoffset: %d disposal: %d delay: %d transparent: %d\n",
|
||||||
|
context->frame_len, context->frame_height, context->x_offset, context->y_offset,
|
||||||
|
context->gif89.disposal, context->gif89.delay_time, context->gif89.transparent);
|
||||||
|
#endif
|
||||||
|
|
||||||
context->frame_interlace = BitSet (buf[8], INTERLACE);
|
context->frame_interlace = BitSet (buf[8], INTERLACE);
|
||||||
if (BitSet (buf[8], LOCALCOLORMAP)) {
|
if (BitSet (buf[8], LOCALCOLORMAP)) {
|
||||||
|
|
||||||
|
#ifdef DUMP_IMAGE_DETAILS
|
||||||
|
g_print (">has local colormap\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Does this frame have it's own colormap. */
|
/* Does this frame have it's own colormap. */
|
||||||
/* really only relevant when looking at the first frame
|
/* really only relevant when looking at the first frame
|
||||||
* of an animated gif. */
|
* of an animated gif. */
|
||||||
/* if it does, we need to re-read in the colormap,
|
/* if it does, we need to re-read in the colormap,
|
||||||
* the gray_scale, and the bit_pixel */
|
* the gray_scale, and the bit_pixel */
|
||||||
context->bit_pixel = 1 << ((buf[8] & 0x07) + 1);
|
context->frame_cmap_active = TRUE;
|
||||||
|
context->frame_bit_pixel = 1 << ((buf[8] & 0x07) + 1);
|
||||||
gif_set_get_colormap2 (context);
|
gif_set_get_colormap2 (context);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!context->has_global_cmap) {
|
||||||
|
context->state = GIF_DONE;
|
||||||
|
|
||||||
|
g_set_error (context->error,
|
||||||
|
GDK_PIXBUF_ERROR,
|
||||||
|
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
|
||||||
|
_("GIF image has no global colormap, and a frame inside it has no local colormap."));
|
||||||
|
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
gif_set_prepare_lzw (context);
|
gif_set_prepare_lzw (context);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1037,6 +1188,8 @@ gif_get_next_step (GifContext *context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define LOG(x)
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
gif_main_loop (GifContext *context)
|
gif_main_loop (GifContext *context)
|
||||||
{
|
{
|
||||||
@ -1045,52 +1198,63 @@ gif_main_loop (GifContext *context)
|
|||||||
do {
|
do {
|
||||||
switch (context->state) {
|
switch (context->state) {
|
||||||
case GIF_START:
|
case GIF_START:
|
||||||
|
LOG("start\n");
|
||||||
retval = gif_init (context);
|
retval = gif_init (context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GIF_GET_COLORMAP:
|
case GIF_GET_COLORMAP:
|
||||||
|
LOG("get_colormap\n");
|
||||||
retval = gif_get_colormap (context);
|
retval = gif_get_colormap (context);
|
||||||
if (retval == 0)
|
if (retval == 0)
|
||||||
context->state = GIF_GET_NEXT_STEP;
|
context->state = GIF_GET_NEXT_STEP;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GIF_GET_NEXT_STEP:
|
case GIF_GET_NEXT_STEP:
|
||||||
|
LOG("next_step\n");
|
||||||
retval = gif_get_next_step (context);
|
retval = gif_get_next_step (context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GIF_GET_FRAME_INFO:
|
case GIF_GET_FRAME_INFO:
|
||||||
|
LOG("frame_info\n");
|
||||||
retval = gif_get_frame_info (context);
|
retval = gif_get_frame_info (context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GIF_GET_EXTENTION:
|
case GIF_GET_EXTENTION:
|
||||||
|
LOG("get_extension\n");
|
||||||
retval = gif_get_extension (context);
|
retval = gif_get_extension (context);
|
||||||
if (retval == 0)
|
if (retval == 0)
|
||||||
context->state = GIF_GET_NEXT_STEP;
|
context->state = GIF_GET_NEXT_STEP;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GIF_GET_COLORMAP2:
|
case GIF_GET_COLORMAP2:
|
||||||
retval = gif_get_colormap (context);
|
LOG("get_colormap2\n");
|
||||||
|
retval = gif_get_colormap2 (context);
|
||||||
if (retval == 0)
|
if (retval == 0)
|
||||||
gif_set_prepare_lzw (context);
|
gif_set_prepare_lzw (context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GIF_PREPARE_LZW:
|
case GIF_PREPARE_LZW:
|
||||||
|
LOG("prepare_lzw\n");
|
||||||
retval = gif_prepare_lzw (context);
|
retval = gif_prepare_lzw (context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GIF_LZW_FILL_BUFFER:
|
case GIF_LZW_FILL_BUFFER:
|
||||||
|
LOG("fill_buffer\n");
|
||||||
retval = gif_lzw_fill_buffer (context);
|
retval = gif_lzw_fill_buffer (context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GIF_LZW_CLEAR_CODE:
|
case GIF_LZW_CLEAR_CODE:
|
||||||
|
LOG("clear_code\n");
|
||||||
retval = gif_lzw_clear_code (context);
|
retval = gif_lzw_clear_code (context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GIF_GET_LZW:
|
case GIF_GET_LZW:
|
||||||
|
LOG("get_lzw\n");
|
||||||
retval = gif_get_lzw (context);
|
retval = gif_get_lzw (context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GIF_DONE:
|
case GIF_DONE:
|
||||||
|
LOG("done\n");
|
||||||
default:
|
default:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
goto done;
|
goto done;
|
||||||
@ -1107,13 +1271,12 @@ new_context (void)
|
|||||||
|
|
||||||
context = g_new0 (GifContext, 1);
|
context = g_new0 (GifContext, 1);
|
||||||
|
|
||||||
context->pixbuf = NULL;
|
context->animation = g_object_new (GDK_TYPE_PIXBUF_GIF_ANIM, NULL);
|
||||||
|
context->frame = NULL;
|
||||||
context->file = NULL;
|
context->file = NULL;
|
||||||
context->state = GIF_START;
|
context->state = GIF_START;
|
||||||
context->prepare_func = NULL;
|
context->prepare_func = NULL;
|
||||||
context->update_func = NULL;
|
context->update_func = NULL;
|
||||||
context->frame_done_func = NULL;
|
|
||||||
context->anim_done_func = NULL;
|
|
||||||
context->user_data = NULL;
|
context->user_data = NULL;
|
||||||
context->buf = NULL;
|
context->buf = NULL;
|
||||||
context->amount_needed = 0;
|
context->amount_needed = 0;
|
||||||
@ -1137,9 +1300,22 @@ gdk_pixbuf__gif_image_load (FILE *file, GError **error)
|
|||||||
context->file = file;
|
context->file = file;
|
||||||
context->error = error;
|
context->error = error;
|
||||||
|
|
||||||
gif_main_loop (context);
|
if (gif_main_loop (context) == -1 || context->animation->frames == NULL) {
|
||||||
|
if (context->error && *(context->error) == NULL)
|
||||||
|
g_set_error (context->error,
|
||||||
|
GDK_PIXBUF_ERROR,
|
||||||
|
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
|
||||||
|
_("GIF file was missing some data (perhaps it was truncated somehow?)"));
|
||||||
|
}
|
||||||
|
|
||||||
pixbuf = context->pixbuf;
|
pixbuf = gdk_pixbuf_animation_get_static_image (GDK_PIXBUF_ANIMATION (context->animation));
|
||||||
|
|
||||||
|
if (pixbuf)
|
||||||
|
g_object_ref (G_OBJECT (pixbuf));
|
||||||
|
|
||||||
|
g_object_unref (G_OBJECT (context->animation));
|
||||||
|
|
||||||
|
g_free (context->buf);
|
||||||
g_free (context);
|
g_free (context);
|
||||||
|
|
||||||
return pixbuf;
|
return pixbuf;
|
||||||
@ -1148,8 +1324,6 @@ gdk_pixbuf__gif_image_load (FILE *file, GError **error)
|
|||||||
static gpointer
|
static gpointer
|
||||||
gdk_pixbuf__gif_image_begin_load (ModulePreparedNotifyFunc prepare_func,
|
gdk_pixbuf__gif_image_begin_load (ModulePreparedNotifyFunc prepare_func,
|
||||||
ModuleUpdatedNotifyFunc update_func,
|
ModuleUpdatedNotifyFunc update_func,
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func,
|
|
||||||
ModuleAnimationDoneNotifyFunc anim_done_func,
|
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@ -1162,8 +1336,6 @@ gdk_pixbuf__gif_image_begin_load (ModulePreparedNotifyFunc prepare_func,
|
|||||||
context->error = error;
|
context->error = error;
|
||||||
context->prepare_func = prepare_func;
|
context->prepare_func = prepare_func;
|
||||||
context->update_func = update_func;
|
context->update_func = update_func;
|
||||||
context->frame_done_func = frame_done_func;
|
|
||||||
context->anim_done_func = anim_done_func;
|
|
||||||
context->user_data = user_data;
|
context->user_data = user_data;
|
||||||
|
|
||||||
return (gpointer) context;
|
return (gpointer) context;
|
||||||
@ -1173,21 +1345,23 @@ static gboolean
|
|||||||
gdk_pixbuf__gif_image_stop_load (gpointer data, GError **error)
|
gdk_pixbuf__gif_image_stop_load (gpointer data, GError **error)
|
||||||
{
|
{
|
||||||
GifContext *context = (GifContext *) data;
|
GifContext *context = (GifContext *) data;
|
||||||
|
gboolean retval = TRUE;
|
||||||
|
|
||||||
/* FIXME: free the animation data */
|
if (context->state != GIF_DONE) {
|
||||||
|
g_set_error (error,
|
||||||
|
GDK_PIXBUF_ERROR,
|
||||||
|
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
|
||||||
|
_("GIF image was truncated or incomplete."));
|
||||||
|
|
||||||
/* FIXME this thing needs to report errors if
|
retval = FALSE;
|
||||||
* we have unused image data
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
if (context->pixbuf)
|
g_object_unref (G_OBJECT (context->animation));
|
||||||
gdk_pixbuf_unref (context->pixbuf);
|
|
||||||
if (context->animation)
|
g_free (context->buf);
|
||||||
gdk_pixbuf_animation_unref (context->animation);
|
|
||||||
/* g_free (context->buf);*/
|
|
||||||
g_free (context);
|
g_free (context);
|
||||||
|
|
||||||
return TRUE;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -1264,18 +1438,28 @@ gdk_pixbuf__gif_image_load_animation (FILE *file,
|
|||||||
context = new_context ();
|
context = new_context ();
|
||||||
|
|
||||||
context->error = error;
|
context->error = error;
|
||||||
|
|
||||||
context->animation = g_object_new (GDK_TYPE_PIXBUF_ANIMATION, NULL);
|
|
||||||
|
|
||||||
context->animation->n_frames = 0;
|
|
||||||
context->animation->frames = NULL;
|
|
||||||
context->animation->width = 0;
|
|
||||||
context->animation->height = 0;
|
|
||||||
context->file = file;
|
context->file = file;
|
||||||
|
|
||||||
gif_main_loop (context);
|
if (gif_main_loop (context) == -1 || context->animation->frames == NULL) {
|
||||||
|
if (context->error && *(context->error) == NULL)
|
||||||
|
g_set_error (context->error,
|
||||||
|
GDK_PIXBUF_ERROR,
|
||||||
|
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
|
||||||
|
_("GIF file was missing some data (perhaps it was truncated somehow?)"));
|
||||||
|
|
||||||
animation = context->animation;
|
g_object_unref (G_OBJECT (context->animation));
|
||||||
|
context->animation = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context->animation)
|
||||||
|
animation = GDK_PIXBUF_ANIMATION (context->animation);
|
||||||
|
else
|
||||||
|
animation = NULL;
|
||||||
|
|
||||||
|
if (context->error && *(context->error))
|
||||||
|
g_print ("%s\n", (*(context->error))->message);
|
||||||
|
|
||||||
|
g_free (context->buf);
|
||||||
g_free (context);
|
g_free (context);
|
||||||
return animation;
|
return animation;
|
||||||
}
|
}
|
||||||
|
@ -156,8 +156,6 @@ struct ico_progressive_state {
|
|||||||
static gpointer
|
static gpointer
|
||||||
gdk_pixbuf__ico_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
gdk_pixbuf__ico_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
||||||
ModuleUpdatedNotifyFunc updated_func,
|
ModuleUpdatedNotifyFunc updated_func,
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func,
|
|
||||||
ModuleAnimationDoneNotifyFunc anim_done_func,
|
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error);
|
GError **error);
|
||||||
static gboolean gdk_pixbuf__ico_image_stop_load(gpointer data, GError **error);
|
static gboolean gdk_pixbuf__ico_image_stop_load(gpointer data, GError **error);
|
||||||
@ -178,8 +176,8 @@ gdk_pixbuf__ico_image_load(FILE * f, GError **error)
|
|||||||
|
|
||||||
GdkPixbuf *pb;
|
GdkPixbuf *pb;
|
||||||
|
|
||||||
State = gdk_pixbuf__ico_image_begin_load(NULL, NULL, NULL,
|
State = gdk_pixbuf__ico_image_begin_load(NULL, NULL, NULL, error);
|
||||||
NULL, NULL, error);
|
|
||||||
if (State == NULL)
|
if (State == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -363,6 +361,7 @@ static void DecodeHeader(guchar *Data, gint Bytes,
|
|||||||
if (State->prepared_func != NULL)
|
if (State->prepared_func != NULL)
|
||||||
/* Notify the client that we are ready to go */
|
/* Notify the client that we are ready to go */
|
||||||
(*State->prepared_func) (State->pixbuf,
|
(*State->prepared_func) (State->pixbuf,
|
||||||
|
NULL,
|
||||||
State->user_data);
|
State->user_data);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -378,8 +377,6 @@ static void DecodeHeader(guchar *Data, gint Bytes,
|
|||||||
static gpointer
|
static gpointer
|
||||||
gdk_pixbuf__ico_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
gdk_pixbuf__ico_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
||||||
ModuleUpdatedNotifyFunc updated_func,
|
ModuleUpdatedNotifyFunc updated_func,
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func,
|
|
||||||
ModuleAnimationDoneNotifyFunc anim_done_func,
|
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
@ -96,8 +96,6 @@ typedef struct {
|
|||||||
static GdkPixbuf *gdk_pixbuf__jpeg_image_load (FILE *f, GError **error);
|
static GdkPixbuf *gdk_pixbuf__jpeg_image_load (FILE *f, GError **error);
|
||||||
static gpointer gdk_pixbuf__jpeg_image_begin_load (ModulePreparedNotifyFunc func,
|
static gpointer gdk_pixbuf__jpeg_image_begin_load (ModulePreparedNotifyFunc func,
|
||||||
ModuleUpdatedNotifyFunc func2,
|
ModuleUpdatedNotifyFunc func2,
|
||||||
ModuleFrameDoneNotifyFunc func3,
|
|
||||||
ModuleAnimationDoneNotifyFunc func4,
|
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error);
|
GError **error);
|
||||||
static gboolean gdk_pixbuf__jpeg_image_stop_load (gpointer context, GError **error);
|
static gboolean gdk_pixbuf__jpeg_image_stop_load (gpointer context, GError **error);
|
||||||
@ -321,8 +319,6 @@ skip_input_data (j_decompress_ptr cinfo, long num_bytes)
|
|||||||
gpointer
|
gpointer
|
||||||
gdk_pixbuf__jpeg_image_begin_load (ModulePreparedNotifyFunc prepared_func,
|
gdk_pixbuf__jpeg_image_begin_load (ModulePreparedNotifyFunc prepared_func,
|
||||||
ModuleUpdatedNotifyFunc updated_func,
|
ModuleUpdatedNotifyFunc updated_func,
|
||||||
ModuleFrameDoneNotifyFunc frame_func,
|
|
||||||
ModuleAnimationDoneNotifyFunc anim_done_func,
|
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@ -539,6 +535,7 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data,
|
|||||||
|
|
||||||
/* Notify the client that we are ready to go */
|
/* Notify the client that we are ready to go */
|
||||||
(* context->prepared_func) (context->pixbuf,
|
(* context->prepared_func) (context->pixbuf,
|
||||||
|
NULL,
|
||||||
context->user_data);
|
context->user_data);
|
||||||
|
|
||||||
} else if (!context->did_prescan) {
|
} else if (!context->did_prescan) {
|
||||||
|
@ -324,8 +324,6 @@ struct _LoadContext {
|
|||||||
static gpointer
|
static gpointer
|
||||||
gdk_pixbuf__png_image_begin_load (ModulePreparedNotifyFunc prepare_func,
|
gdk_pixbuf__png_image_begin_load (ModulePreparedNotifyFunc prepare_func,
|
||||||
ModuleUpdatedNotifyFunc update_func,
|
ModuleUpdatedNotifyFunc update_func,
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func,
|
|
||||||
ModuleAnimationDoneNotifyFunc anim_done_func,
|
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@ -540,7 +538,7 @@ png_info_callback (png_structp png_read_ptr,
|
|||||||
/* Notify the client that we are ready to go */
|
/* Notify the client that we are ready to go */
|
||||||
|
|
||||||
if (lc->prepare_func)
|
if (lc->prepare_func)
|
||||||
(* lc->prepare_func) (lc->pixbuf, lc->notify_user_data);
|
(* lc->prepare_func) (lc->pixbuf, NULL, lc->notify_user_data);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -84,8 +84,6 @@ typedef struct {
|
|||||||
static GdkPixbuf *gdk_pixbuf__pnm_image_load (FILE *f, GError **error);
|
static GdkPixbuf *gdk_pixbuf__pnm_image_load (FILE *f, GError **error);
|
||||||
static gpointer gdk_pixbuf__pnm_image_begin_load (ModulePreparedNotifyFunc func,
|
static gpointer gdk_pixbuf__pnm_image_begin_load (ModulePreparedNotifyFunc func,
|
||||||
ModuleUpdatedNotifyFunc func2,
|
ModuleUpdatedNotifyFunc func2,
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func,
|
|
||||||
ModuleAnimationDoneNotifyFunc anim_done_func,
|
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error);
|
GError **error);
|
||||||
static gboolean gdk_pixbuf__pnm_image_stop_load (gpointer context, GError **error);
|
static gboolean gdk_pixbuf__pnm_image_stop_load (gpointer context, GError **error);
|
||||||
@ -763,8 +761,6 @@ gdk_pixbuf__pnm_image_load (FILE *f, GError **error)
|
|||||||
static gpointer
|
static gpointer
|
||||||
gdk_pixbuf__pnm_image_begin_load (ModulePreparedNotifyFunc prepared_func,
|
gdk_pixbuf__pnm_image_begin_load (ModulePreparedNotifyFunc prepared_func,
|
||||||
ModuleUpdatedNotifyFunc updated_func,
|
ModuleUpdatedNotifyFunc updated_func,
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func,
|
|
||||||
ModuleAnimationDoneNotifyFunc anim_done_func,
|
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@ -923,6 +919,7 @@ gdk_pixbuf__pnm_image_load_increment (gpointer data,
|
|||||||
|
|
||||||
/* Notify the client that we are ready to go */
|
/* Notify the client that we are ready to go */
|
||||||
(* context->prepared_func) (context->pixbuf,
|
(* context->prepared_func) (context->pixbuf,
|
||||||
|
NULL,
|
||||||
context->user_data);
|
context->user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,8 +96,6 @@ struct ras_progressive_state {
|
|||||||
static gpointer
|
static gpointer
|
||||||
gdk_pixbuf__ras_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
gdk_pixbuf__ras_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
||||||
ModuleUpdatedNotifyFunc updated_func,
|
ModuleUpdatedNotifyFunc updated_func,
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func,
|
|
||||||
ModuleAnimationDoneNotifyFunc anim_done_func,
|
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error);
|
GError **error);
|
||||||
static gboolean gdk_pixbuf__ras_image_stop_load(gpointer data, GError **error);
|
static gboolean gdk_pixbuf__ras_image_stop_load(gpointer data, GError **error);
|
||||||
@ -116,8 +114,7 @@ static GdkPixbuf *gdk_pixbuf__ras_image_load(FILE * f, GError **error)
|
|||||||
|
|
||||||
GdkPixbuf *pb;
|
GdkPixbuf *pb;
|
||||||
|
|
||||||
State = gdk_pixbuf__ras_image_begin_load(NULL, NULL, NULL,
|
State = gdk_pixbuf__ras_image_begin_load(NULL, NULL, NULL, error);
|
||||||
NULL, NULL, error);
|
|
||||||
|
|
||||||
membuf = g_malloc(4096);
|
membuf = g_malloc(4096);
|
||||||
|
|
||||||
@ -195,6 +192,7 @@ static void RAS2State(struct rasterfile *RAS,
|
|||||||
if (State->prepared_func != NULL)
|
if (State->prepared_func != NULL)
|
||||||
/* Notify the client that we are ready to go */
|
/* Notify the client that we are ready to go */
|
||||||
(*State->prepared_func) (State->pixbuf,
|
(*State->prepared_func) (State->pixbuf,
|
||||||
|
NULL,
|
||||||
State->user_data);
|
State->user_data);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -219,8 +217,6 @@ static void RAS2State(struct rasterfile *RAS,
|
|||||||
static gpointer
|
static gpointer
|
||||||
gdk_pixbuf__ras_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
gdk_pixbuf__ras_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
||||||
ModuleUpdatedNotifyFunc updated_func,
|
ModuleUpdatedNotifyFunc updated_func,
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func,
|
|
||||||
ModuleAnimationDoneNotifyFunc anim_done_func,
|
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
@ -92,7 +92,7 @@ gdk_pixbuf__tiff_image_load_real (FILE *f, TiffData *context, GError **error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (context)
|
if (context)
|
||||||
(* context->prepare_func) (pixbuf, context->user_data);
|
(* context->prepare_func) (pixbuf, NULL, context->user_data);
|
||||||
|
|
||||||
/* Yes, it needs to be _TIFFMalloc... */
|
/* Yes, it needs to be _TIFFMalloc... */
|
||||||
rast = (uint32 *) _TIFFmalloc (num_pixs * sizeof (uint32));
|
rast = (uint32 *) _TIFFmalloc (num_pixs * sizeof (uint32));
|
||||||
@ -163,8 +163,6 @@ gdk_pixbuf__tiff_image_load (FILE *f, GError **error)
|
|||||||
static gpointer
|
static gpointer
|
||||||
gdk_pixbuf__tiff_image_begin_load (ModulePreparedNotifyFunc prepare_func,
|
gdk_pixbuf__tiff_image_begin_load (ModulePreparedNotifyFunc prepare_func,
|
||||||
ModuleUpdatedNotifyFunc update_func,
|
ModuleUpdatedNotifyFunc update_func,
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func,
|
|
||||||
ModuleAnimationDoneNotifyFunc anim_done_func,
|
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
@ -65,9 +65,7 @@ struct wbmp_progressive_state {
|
|||||||
static gpointer
|
static gpointer
|
||||||
gdk_pixbuf__wbmp_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
gdk_pixbuf__wbmp_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
||||||
ModuleUpdatedNotifyFunc updated_func,
|
ModuleUpdatedNotifyFunc updated_func,
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func,
|
gpointer user_data,
|
||||||
ModuleAnimationDoneNotifyFunc
|
|
||||||
anim_done_func, gpointer user_data,
|
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
static gboolean gdk_pixbuf__wbmp_image_stop_load(gpointer data, GError **error);
|
static gboolean gdk_pixbuf__wbmp_image_stop_load(gpointer data, GError **error);
|
||||||
@ -87,7 +85,7 @@ static GdkPixbuf *gdk_pixbuf__wbmp_image_load(FILE * f, GError **error)
|
|||||||
|
|
||||||
GdkPixbuf *pb;
|
GdkPixbuf *pb;
|
||||||
|
|
||||||
State = gdk_pixbuf__wbmp_image_begin_load(NULL, NULL, NULL, NULL, NULL,
|
State = gdk_pixbuf__wbmp_image_begin_load(NULL, NULL, NULL,
|
||||||
error);
|
error);
|
||||||
|
|
||||||
if (State == NULL)
|
if (State == NULL)
|
||||||
@ -120,9 +118,7 @@ static GdkPixbuf *gdk_pixbuf__wbmp_image_load(FILE * f, GError **error)
|
|||||||
static gpointer
|
static gpointer
|
||||||
gdk_pixbuf__wbmp_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
gdk_pixbuf__wbmp_image_begin_load(ModulePreparedNotifyFunc prepared_func,
|
||||||
ModuleUpdatedNotifyFunc updated_func,
|
ModuleUpdatedNotifyFunc updated_func,
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func,
|
gpointer user_data,
|
||||||
ModuleAnimationDoneNotifyFunc
|
|
||||||
anim_done_func, gpointer user_data,
|
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
struct wbmp_progressive_state *context;
|
struct wbmp_progressive_state *context;
|
||||||
@ -285,7 +281,7 @@ static gboolean gdk_pixbuf__wbmp_image_load_increment(gpointer data,
|
|||||||
g_assert(context->pixbuf);
|
g_assert(context->pixbuf);
|
||||||
|
|
||||||
if(context->prepared_func)
|
if(context->prepared_func)
|
||||||
context->prepared_func(context->pixbuf, context->user_data);
|
context->prepared_func(context->pixbuf, NULL, context->user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(context->needmore)
|
else if(context->needmore)
|
||||||
|
@ -300,7 +300,7 @@ gdk_pixbuf__xbm_image_load_real (FILE *f, XBMData *context, GError **error)
|
|||||||
row_stride = gdk_pixbuf_get_rowstride (pixbuf);
|
row_stride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||||
|
|
||||||
if (context)
|
if (context)
|
||||||
(* context->prepare_func) (pixbuf, context->user_data);
|
(* context->prepare_func) (pixbuf, NULL, context->user_data);
|
||||||
|
|
||||||
|
|
||||||
/* Initialize PIXBUF */
|
/* Initialize PIXBUF */
|
||||||
@ -355,8 +355,6 @@ gdk_pixbuf__xbm_image_load (FILE *f, GError **error)
|
|||||||
static gpointer
|
static gpointer
|
||||||
gdk_pixbuf__xbm_image_begin_load (ModulePreparedNotifyFunc prepare_func,
|
gdk_pixbuf__xbm_image_begin_load (ModulePreparedNotifyFunc prepare_func,
|
||||||
ModuleUpdatedNotifyFunc update_func,
|
ModuleUpdatedNotifyFunc update_func,
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func,
|
|
||||||
ModuleAnimationDoneNotifyFunc anim_done_func,
|
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
@ -1424,8 +1424,6 @@ struct _XPMContext
|
|||||||
static gpointer
|
static gpointer
|
||||||
gdk_pixbuf__xpm_image_begin_load (ModulePreparedNotifyFunc prepare_func,
|
gdk_pixbuf__xpm_image_begin_load (ModulePreparedNotifyFunc prepare_func,
|
||||||
ModuleUpdatedNotifyFunc update_func,
|
ModuleUpdatedNotifyFunc update_func,
|
||||||
ModuleFrameDoneNotifyFunc frame_done_func,
|
|
||||||
ModuleAnimationDoneNotifyFunc anim_done_func,
|
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@ -1471,7 +1469,9 @@ gdk_pixbuf__xpm_image_stop_load (gpointer data,
|
|||||||
pixbuf = gdk_pixbuf__xpm_image_load (context->file, error);
|
pixbuf = gdk_pixbuf__xpm_image_load (context->file, error);
|
||||||
|
|
||||||
if (pixbuf != NULL) {
|
if (pixbuf != NULL) {
|
||||||
(* context->prepare_func) (pixbuf, context->user_data);
|
(* context->prepare_func) (pixbuf,
|
||||||
|
NULL,
|
||||||
|
context->user_data);
|
||||||
(* context->update_func) (pixbuf, 0, 0, pixbuf->width, pixbuf->height, context->user_data);
|
(* context->update_func) (pixbuf, 0, 0, pixbuf->width, pixbuf->height, context->user_data);
|
||||||
gdk_pixbuf_unref (pixbuf);
|
gdk_pixbuf_unref (pixbuf);
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <glib.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "pixops.h"
|
#include "pixops.h"
|
||||||
@ -93,6 +94,7 @@ pixops_scale_nearest (guchar *dest_buf,
|
|||||||
for (i = 0; i < (render_y1 - render_y0); i++)
|
for (i = 0; i < (render_y1 - render_y0); i++)
|
||||||
{
|
{
|
||||||
const guchar *src = src_buf + (((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT) * src_rowstride;
|
const guchar *src = src_buf + (((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT) * src_rowstride;
|
||||||
|
/* FIXME Owen needs to look at this */
|
||||||
guchar *dest = dest_buf + i * dest_rowstride;
|
guchar *dest = dest_buf + i * dest_rowstride;
|
||||||
|
|
||||||
x = render_x0 * x_step + x_step / 2;
|
x = render_x0 * x_step + x_step / 2;
|
||||||
@ -160,7 +162,6 @@ pixops_composite_nearest (guchar *dest_buf,
|
|||||||
for (i = 0; i < (render_y1 - render_y0); i++)
|
for (i = 0; i < (render_y1 - render_y0); i++)
|
||||||
{
|
{
|
||||||
const guchar *src = src_buf + (((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT) * src_rowstride;
|
const guchar *src = src_buf + (((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT) * src_rowstride;
|
||||||
/* FIXME Owen needs to look at this */
|
|
||||||
guchar *dest = dest_buf + i * dest_rowstride;
|
guchar *dest = dest_buf + i * dest_rowstride;
|
||||||
|
|
||||||
x = render_x0 * x_step + x_step / 2;
|
x = render_x0 * x_step + x_step / 2;
|
||||||
@ -183,9 +184,9 @@ pixops_composite_nearest (guchar *dest_buf,
|
|||||||
|
|
||||||
if (w != 0)
|
if (w != 0)
|
||||||
{
|
{
|
||||||
dest[0] = (w0 * src[0] + w1 * dest[0]) / w;
|
dest[0] = (w0 * p[0] + w1 * dest[0]) / w;
|
||||||
dest[1] = (w0 * src[1] + w1 * dest[1]) / w;
|
dest[1] = (w0 * p[1] + w1 * dest[1]) / w;
|
||||||
dest[2] = (w0 * src[2] + w1 * dest[2]) / w;
|
dest[2] = (w0 * p[2] + w1 * dest[2]) / w;
|
||||||
dest[3] = w / 0xff;
|
dest[3] = w / 0xff;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -274,24 +275,38 @@ pixops_composite_color_nearest (guchar *dest_buf,
|
|||||||
for (j=0 ; j < (render_x1 - render_x0); j++)
|
for (j=0 ; j < (render_x1 - render_x0); j++)
|
||||||
{
|
{
|
||||||
const guchar *p = src + (x >> SCALE_SHIFT) * src_channels;
|
const guchar *p = src + (x >> SCALE_SHIFT) * src_channels;
|
||||||
unsigned int a0;
|
int a0;
|
||||||
|
int tmp;
|
||||||
|
|
||||||
if (src_has_alpha)
|
if (src_has_alpha)
|
||||||
a0 = (p[3] * overall_alpha + 0xff) >> 8;
|
a0 = (p[3] * overall_alpha + 0xff) >> 8;
|
||||||
else
|
else
|
||||||
a0 = overall_alpha;
|
a0 = overall_alpha;
|
||||||
|
|
||||||
|
if (a0 == 255)
|
||||||
|
{
|
||||||
|
dest[0] = p[0];
|
||||||
|
dest[1] = p[1];
|
||||||
|
dest[2] = p[2];
|
||||||
|
}
|
||||||
|
else
|
||||||
if (((j + check_x) >> check_shift) & 1)
|
if (((j + check_x) >> check_shift) & 1)
|
||||||
{
|
{
|
||||||
dest[0] = r2 + ((a0 * ((int)p[0] - r2) + 0xff) >> 8);
|
tmp = ((int) p[0] - r2) * a0;
|
||||||
dest[1] = g2 + ((a0 * ((int)p[1] - g2) + 0xff) >> 8);
|
dest[0] = r2 + ((tmp + (tmp >> 8) + 0x80) >> 8);
|
||||||
dest[2] = b2 + ((a0 * ((int)p[2] - b2) + 0xff) >> 8);
|
tmp = ((int) p[1] - g2) * a0;
|
||||||
|
dest[1] = g2 + ((tmp + (tmp >> 8) + 0x80) >> 8);
|
||||||
|
tmp = ((int) p[2] - b2) * a0;
|
||||||
|
dest[2] = b2 + ((tmp + (tmp >> 8) + 0x80) >> 8);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dest[0] = r1 + ((a0 * ((int)p[0] - r1) + 0xff) >> 8);
|
tmp = ((int) p[0] - r1) * a0;
|
||||||
dest[1] = g1 + ((a0 * ((int)p[1] - g1) + 0xff) >> 8);
|
dest[0] = r1 + ((tmp + (tmp >> 8) + 0x80) >> 8);
|
||||||
dest[2] = b1 + ((a0 * ((int)p[2] - b1) + 0xff) >> 8);
|
tmp = ((int) p[1] - g1) * a0;
|
||||||
|
dest[1] = g1 + ((tmp + (tmp >> 8) + 0x80) >> 8);
|
||||||
|
tmp = ((int) p[2] - b1) * a0;
|
||||||
|
dest[2] = b1 + ((tmp + (tmp >> 8) + 0x80) >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dest_channels == 4)
|
if (dest_channels == 4)
|
||||||
@ -1003,7 +1018,7 @@ pixops_process (guchar *dest_buf,
|
|||||||
|
|
||||||
dest_x += (new_outbuf - outbuf) / dest_channels;
|
dest_x += (new_outbuf - outbuf) / dest_channels;
|
||||||
|
|
||||||
x = dest_x * x_step + scaled_x_offset;
|
x = (dest_x - check_x + render_x0) * x_step + scaled_x_offset;
|
||||||
outbuf = new_outbuf;
|
outbuf = new_outbuf;
|
||||||
|
|
||||||
while (outbuf < outbuf_end)
|
while (outbuf < outbuf_end)
|
||||||
|
@ -70,6 +70,7 @@ enum {
|
|||||||
PROP_STRETCH,
|
PROP_STRETCH,
|
||||||
PROP_SIZE,
|
PROP_SIZE,
|
||||||
PROP_SIZE_POINTS,
|
PROP_SIZE_POINTS,
|
||||||
|
PROP_SCALE,
|
||||||
PROP_EDITABLE,
|
PROP_EDITABLE,
|
||||||
PROP_STRIKETHROUGH,
|
PROP_STRIKETHROUGH,
|
||||||
PROP_UNDERLINE,
|
PROP_UNDERLINE,
|
||||||
@ -84,6 +85,7 @@ enum {
|
|||||||
PROP_WEIGHT_SET,
|
PROP_WEIGHT_SET,
|
||||||
PROP_STRETCH_SET,
|
PROP_STRETCH_SET,
|
||||||
PROP_SIZE_SET,
|
PROP_SIZE_SET,
|
||||||
|
PROP_SCALE_SET,
|
||||||
PROP_EDITABLE_SET,
|
PROP_EDITABLE_SET,
|
||||||
PROP_STRIKETHROUGH_SET,
|
PROP_STRIKETHROUGH_SET,
|
||||||
PROP_UNDERLINE_SET,
|
PROP_UNDERLINE_SET,
|
||||||
@ -283,6 +285,16 @@ gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
|
|||||||
0.0,
|
0.0,
|
||||||
G_PARAM_READABLE | G_PARAM_WRITABLE));
|
G_PARAM_READABLE | G_PARAM_WRITABLE));
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_SCALE,
|
||||||
|
g_param_spec_double ("scale",
|
||||||
|
_("Font scale"),
|
||||||
|
_("Font scaling factor"),
|
||||||
|
0.0,
|
||||||
|
G_MAXDOUBLE,
|
||||||
|
1.0,
|
||||||
|
G_PARAM_READABLE | G_PARAM_WRITABLE));
|
||||||
|
|
||||||
g_object_class_install_property (object_class,
|
g_object_class_install_property (object_class,
|
||||||
PROP_RISE,
|
PROP_RISE,
|
||||||
g_param_spec_int ("rise",
|
g_param_spec_int ("rise",
|
||||||
@ -351,6 +363,10 @@ gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
|
|||||||
_("Font size set"),
|
_("Font size set"),
|
||||||
_("Whether this tag affects the font size"));
|
_("Whether this tag affects the font size"));
|
||||||
|
|
||||||
|
ADD_SET_PROP ("scale_set", PROP_SCALE_SET,
|
||||||
|
_("Font scale set"),
|
||||||
|
_("Whether this tag scales the font size by a factor"));
|
||||||
|
|
||||||
ADD_SET_PROP ("rise_set", PROP_RISE_SET,
|
ADD_SET_PROP ("rise_set", PROP_RISE_SET,
|
||||||
_("Rise set"),
|
_("Rise set"),
|
||||||
_("Whether this tag affects the rise"));
|
_("Whether this tag affects the rise"));
|
||||||
@ -462,6 +478,10 @@ gtk_cell_renderer_text_get_property (GObject *object,
|
|||||||
g_value_set_double (value, ((double)celltext->font.size) / (double)PANGO_SCALE);
|
g_value_set_double (value, ((double)celltext->font.size) / (double)PANGO_SCALE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_SCALE:
|
||||||
|
g_value_set_double (value, celltext->font_scale);
|
||||||
|
break;
|
||||||
|
|
||||||
case PROP_EDITABLE:
|
case PROP_EDITABLE:
|
||||||
g_value_set_boolean (value, celltext->editable);
|
g_value_set_boolean (value, celltext->editable);
|
||||||
break;
|
break;
|
||||||
@ -510,6 +530,10 @@ gtk_cell_renderer_text_get_property (GObject *object,
|
|||||||
g_value_set_boolean (value, celltext->size_set);
|
g_value_set_boolean (value, celltext->size_set);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_SCALE_SET:
|
||||||
|
g_value_set_boolean (value, celltext->scale_set);
|
||||||
|
break;
|
||||||
|
|
||||||
case PROP_EDITABLE_SET:
|
case PROP_EDITABLE_SET:
|
||||||
g_value_set_boolean (value, celltext->editable_set);
|
g_value_set_boolean (value, celltext->editable_set);
|
||||||
break;
|
break;
|
||||||
@ -824,6 +848,11 @@ gtk_cell_renderer_text_set_property (GObject *object,
|
|||||||
g_object_notify (G_OBJECT (celltext), "font");
|
g_object_notify (G_OBJECT (celltext), "font");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_SCALE:
|
||||||
|
celltext->font_scale = g_value_get_double (value);
|
||||||
|
celltext->scale_set = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
case PROP_SIZE_POINTS:
|
case PROP_SIZE_POINTS:
|
||||||
celltext->font.size = g_value_get_double (value) * PANGO_SCALE;
|
celltext->font.size = g_value_get_double (value) * PANGO_SCALE;
|
||||||
|
|
||||||
@ -849,6 +878,7 @@ gtk_cell_renderer_text_set_property (GObject *object,
|
|||||||
celltext->underline_style = g_value_get_enum (value);
|
celltext->underline_style = g_value_get_enum (value);
|
||||||
celltext->underline_set = TRUE;
|
celltext->underline_set = TRUE;
|
||||||
g_object_notify (G_OBJECT (celltext), "underline_set");
|
g_object_notify (G_OBJECT (celltext), "underline_set");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_RISE:
|
case PROP_RISE:
|
||||||
@ -859,62 +889,54 @@ gtk_cell_renderer_text_set_property (GObject *object,
|
|||||||
|
|
||||||
case PROP_BACKGROUND_SET:
|
case PROP_BACKGROUND_SET:
|
||||||
celltext->background_set = g_value_get_boolean (value);
|
celltext->background_set = g_value_get_boolean (value);
|
||||||
g_object_notify(G_OBJECT(object), "background_set");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_FOREGROUND_SET:
|
case PROP_FOREGROUND_SET:
|
||||||
celltext->foreground_set = g_value_get_boolean (value);
|
celltext->foreground_set = g_value_get_boolean (value);
|
||||||
g_object_notify(G_OBJECT(object), "foreground_set");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_FAMILY_SET:
|
case PROP_FAMILY_SET:
|
||||||
celltext->family_set = g_value_get_boolean (value);
|
celltext->family_set = g_value_get_boolean (value);
|
||||||
g_object_notify(G_OBJECT(object), "family_set");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_STYLE_SET:
|
case PROP_STYLE_SET:
|
||||||
celltext->style_set = g_value_get_boolean (value);
|
celltext->style_set = g_value_get_boolean (value);
|
||||||
g_object_notify(G_OBJECT(object), "style_set");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_VARIANT_SET:
|
case PROP_VARIANT_SET:
|
||||||
celltext->variant_set = g_value_get_boolean (value);
|
celltext->variant_set = g_value_get_boolean (value);
|
||||||
g_object_notify(G_OBJECT(object), "variant_set");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_WEIGHT_SET:
|
case PROP_WEIGHT_SET:
|
||||||
celltext->weight_set = g_value_get_boolean (value);
|
celltext->weight_set = g_value_get_boolean (value);
|
||||||
g_object_notify(G_OBJECT(object), "weight_set");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_STRETCH_SET:
|
case PROP_STRETCH_SET:
|
||||||
celltext->stretch_set = g_value_get_boolean (value);
|
celltext->stretch_set = g_value_get_boolean (value);
|
||||||
g_object_notify(G_OBJECT(object), "stretch_set");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_SIZE_SET:
|
case PROP_SIZE_SET:
|
||||||
celltext->size_set = g_value_get_boolean (value);
|
celltext->size_set = g_value_get_boolean (value);
|
||||||
g_object_notify(G_OBJECT(object), "size_set");
|
break;
|
||||||
|
|
||||||
|
case PROP_SCALE_SET:
|
||||||
|
celltext->scale_set = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_EDITABLE_SET:
|
case PROP_EDITABLE_SET:
|
||||||
celltext->editable_set = g_value_get_boolean (value);
|
celltext->editable_set = g_value_get_boolean (value);
|
||||||
g_object_notify(G_OBJECT(object), "editable_set");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_STRIKETHROUGH_SET:
|
case PROP_STRIKETHROUGH_SET:
|
||||||
celltext->strikethrough_set = g_value_get_boolean (value);
|
celltext->strikethrough_set = g_value_get_boolean (value);
|
||||||
g_object_notify(G_OBJECT(object), "strikethrough_set");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_UNDERLINE_SET:
|
case PROP_UNDERLINE_SET:
|
||||||
celltext->underline_set = g_value_get_boolean (value);
|
celltext->underline_set = g_value_get_boolean (value);
|
||||||
g_object_notify(G_OBJECT(object), "underline_set");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_RISE_SET:
|
case PROP_RISE_SET:
|
||||||
celltext->rise_set = g_value_get_boolean (value);
|
celltext->rise_set = g_value_get_boolean (value);
|
||||||
g_object_notify(G_OBJECT(object), "rise_set");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1012,6 +1034,10 @@ get_layout (GtkCellRendererText *celltext,
|
|||||||
celltext->font.size >= 0)
|
celltext->font.size >= 0)
|
||||||
add_attr (attr_list, pango_attr_size_new (celltext->font.size));
|
add_attr (attr_list, pango_attr_size_new (celltext->font.size));
|
||||||
|
|
||||||
|
if (celltext->scale_set &&
|
||||||
|
celltext->font_scale != 1.0)
|
||||||
|
add_attr (attr_list, pango_attr_scale_new (celltext->font_scale));
|
||||||
|
|
||||||
if (celltext->underline_set)
|
if (celltext->underline_set)
|
||||||
uline = celltext->underline_style;
|
uline = celltext->underline_style;
|
||||||
else
|
else
|
||||||
|
@ -44,6 +44,7 @@ struct _GtkCellRendererText
|
|||||||
/*< private >*/
|
/*< private >*/
|
||||||
gchar *text;
|
gchar *text;
|
||||||
PangoFontDescription font;
|
PangoFontDescription font;
|
||||||
|
gdouble font_scale;
|
||||||
PangoColor foreground;
|
PangoColor foreground;
|
||||||
PangoColor background;
|
PangoColor background;
|
||||||
|
|
||||||
@ -66,6 +67,8 @@ struct _GtkCellRendererText
|
|||||||
guint stretch_set : 1;
|
guint stretch_set : 1;
|
||||||
guint size_set : 1;
|
guint size_set : 1;
|
||||||
|
|
||||||
|
guint scale_set : 1;
|
||||||
|
|
||||||
guint foreground_set : 1;
|
guint foreground_set : 1;
|
||||||
guint background_set : 1;
|
guint background_set : 1;
|
||||||
|
|
||||||
|
@ -246,8 +246,8 @@ gtk_check_button_size_request (GtkWidget *widget,
|
|||||||
gint indicator_spacing;
|
gint indicator_spacing;
|
||||||
gint border_width = GTK_CONTAINER (widget)->border_width;
|
gint border_width = GTK_CONTAINER (widget)->border_width;
|
||||||
|
|
||||||
requisition->width = border_width + 2;
|
requisition->width = border_width * 2 + 2;
|
||||||
requisition->height = border_width + 2;
|
requisition->height = border_width * 2 + 2;
|
||||||
|
|
||||||
child = GTK_BIN (widget)->child;
|
child = GTK_BIN (widget)->child;
|
||||||
if (child && GTK_WIDGET_VISIBLE (child))
|
if (child && GTK_WIDGET_VISIBLE (child))
|
||||||
|
@ -1848,7 +1848,7 @@ gtk_color_selection_destroy (GtkObject *object)
|
|||||||
|
|
||||||
if (priv->tooltips)
|
if (priv->tooltips)
|
||||||
{
|
{
|
||||||
gtk_object_destroy (priv->tooltips);
|
gtk_object_destroy (GTK_OBJECT (priv->tooltips));
|
||||||
priv->tooltips = NULL;
|
priv->tooltips = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,7 +523,6 @@ gtk_hscale_draw_value (GtkScale *scale)
|
|||||||
{
|
{
|
||||||
GtkStateType state_type;
|
GtkStateType state_type;
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
gchar buffer[32];
|
|
||||||
gint width, height;
|
gint width, height;
|
||||||
gint x, y;
|
gint x, y;
|
||||||
|
|
||||||
@ -536,9 +535,14 @@ gtk_hscale_draw_value (GtkScale *scale)
|
|||||||
{
|
{
|
||||||
PangoLayout *layout;
|
PangoLayout *layout;
|
||||||
PangoRectangle logical_rect;
|
PangoRectangle logical_rect;
|
||||||
|
gchar *txt;
|
||||||
|
|
||||||
|
txt = _gtk_scale_format_value (scale,
|
||||||
|
GTK_RANGE (scale)->adjustment->value);
|
||||||
|
|
||||||
|
layout = gtk_widget_create_pango_layout (widget, txt);
|
||||||
|
g_free (txt);
|
||||||
|
|
||||||
sprintf (buffer, "%0.*f", GTK_RANGE (scale)->digits, GTK_RANGE (scale)->adjustment->value);
|
|
||||||
layout = gtk_widget_create_pango_layout (widget, buffer);
|
|
||||||
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||||||
|
|
||||||
switch (scale->value_pos)
|
switch (scale->value_pos)
|
||||||
|
244
gtk/gtkimage.c
244
gtk/gtkimage.c
@ -28,11 +28,13 @@
|
|||||||
#include "gtkimage.h"
|
#include "gtkimage.h"
|
||||||
#include "gtkiconfactory.h"
|
#include "gtkiconfactory.h"
|
||||||
#include "gtkstock.h"
|
#include "gtkstock.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static void gtk_image_class_init (GtkImageClass *klass);
|
static void gtk_image_class_init (GtkImageClass *klass);
|
||||||
static void gtk_image_init (GtkImage *image);
|
static void gtk_image_init (GtkImage *image);
|
||||||
static gint gtk_image_expose (GtkWidget *widget,
|
static gint gtk_image_expose (GtkWidget *widget,
|
||||||
GdkEventExpose *event);
|
GdkEventExpose *event);
|
||||||
|
static void gtk_image_unmap (GtkWidget *widget);
|
||||||
static void gtk_image_size_request (GtkWidget *widget,
|
static void gtk_image_size_request (GtkWidget *widget,
|
||||||
GtkRequisition *requisition);
|
GtkRequisition *requisition);
|
||||||
static void gtk_image_destroy (GtkObject *object);
|
static void gtk_image_destroy (GtkObject *object);
|
||||||
@ -85,6 +87,7 @@ gtk_image_class_init (GtkImageClass *class)
|
|||||||
|
|
||||||
widget_class->expose_event = gtk_image_expose;
|
widget_class->expose_event = gtk_image_expose;
|
||||||
widget_class->size_request = gtk_image_size_request;
|
widget_class->size_request = gtk_image_size_request;
|
||||||
|
widget_class->unmap = gtk_image_unmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -163,11 +166,22 @@ gtk_image_new_from_image (GdkImage *gdk_image,
|
|||||||
* gtk_image_new_from_file:
|
* gtk_image_new_from_file:
|
||||||
* @filename: a filename
|
* @filename: a filename
|
||||||
*
|
*
|
||||||
* Creates a new #GtkImage displaying the file @filename. If the
|
* Creates a new #GtkImage displaying the file @filename. If the file
|
||||||
* file isn't found or can't be loaded, the #GtkImage will display
|
* isn't found or can't be loaded, the resulting #GtkImage will
|
||||||
* a "broken image" icon. If you need to detect failures to load
|
* display a "broken image" icon. This function never returns %NULL,
|
||||||
* the file, use gdk_pixbuf_new_from_file() to load the file yourself,
|
* it always returns a valid #GtkImage widget.
|
||||||
* then create the #GtkImage from the pixbuf.
|
*
|
||||||
|
* If the file contains an animation, the image will contain an
|
||||||
|
* animation.
|
||||||
|
*
|
||||||
|
* If you need to detect failures to load the file, use
|
||||||
|
* gdk_pixbuf_new_from_file() to load the file yourself, then create
|
||||||
|
* the #GtkImage from the pixbuf. (Or for animations, use
|
||||||
|
* gdk_pixbuf_animation_new_from_file()).
|
||||||
|
*
|
||||||
|
* The storage type (gtk_image_get_storage_type()) of the returned
|
||||||
|
* image is not defined, it will be whatever is appropriate for
|
||||||
|
* displaying the file.
|
||||||
*
|
*
|
||||||
* Return value: a new #GtkImage
|
* Return value: a new #GtkImage
|
||||||
**/
|
**/
|
||||||
@ -194,7 +208,7 @@ gtk_image_new_from_file (const gchar *filename)
|
|||||||
*
|
*
|
||||||
* Note that this function just creates an #GtkImage from the pixbuf. The
|
* Note that this function just creates an #GtkImage from the pixbuf. The
|
||||||
* #GtkImage created will not react to state changes. Should you want that, you
|
* #GtkImage created will not react to state changes. Should you want that, you
|
||||||
* should use @gtk_image_new_from_icon_set.
|
* should use gtk_image_new_from_icon_set().
|
||||||
*
|
*
|
||||||
* Return value: a new #GtkImage
|
* Return value: a new #GtkImage
|
||||||
**/
|
**/
|
||||||
@ -268,6 +282,31 @@ gtk_image_new_from_icon_set (GtkIconSet *icon_set,
|
|||||||
return GTK_WIDGET (image);
|
return GTK_WIDGET (image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_image_new_from_animation:
|
||||||
|
* @animation: an animation
|
||||||
|
*
|
||||||
|
* Creates a #GtkImage displaying the given animation.
|
||||||
|
* The #GtkImage does not assume a reference to the
|
||||||
|
* animation; you still need to unref it if you own references.
|
||||||
|
* #GtkImage will add its own reference rather than adopting yours.
|
||||||
|
*
|
||||||
|
* Return value: a new #GtkImage widget
|
||||||
|
**/
|
||||||
|
GtkWidget*
|
||||||
|
gtk_image_new_from_animation (GdkPixbufAnimation *animation)
|
||||||
|
{
|
||||||
|
GtkImage *image;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), NULL);
|
||||||
|
|
||||||
|
image = gtk_type_new (GTK_TYPE_IMAGE);
|
||||||
|
|
||||||
|
gtk_image_set_from_animation (image, animation);
|
||||||
|
|
||||||
|
return GTK_WIDGET (image);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_image_set_from_pixmap:
|
* gtk_image_set_from_pixmap:
|
||||||
* @image: a #GtkImage
|
* @image: a #GtkImage
|
||||||
@ -376,7 +415,7 @@ void
|
|||||||
gtk_image_set_from_file (GtkImage *image,
|
gtk_image_set_from_file (GtkImage *image,
|
||||||
const gchar *filename)
|
const gchar *filename)
|
||||||
{
|
{
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbufAnimation *anim;
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_IMAGE (image));
|
g_return_if_fail (GTK_IS_IMAGE (image));
|
||||||
g_return_if_fail (filename != NULL);
|
g_return_if_fail (filename != NULL);
|
||||||
@ -386,9 +425,9 @@ gtk_image_set_from_file (GtkImage *image,
|
|||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
|
anim = gdk_pixbuf_animation_new_from_file (filename, NULL);
|
||||||
|
|
||||||
if (pixbuf == NULL)
|
if (anim == NULL)
|
||||||
{
|
{
|
||||||
gtk_image_set_from_stock (image,
|
gtk_image_set_from_stock (image,
|
||||||
GTK_STOCK_MISSING_IMAGE,
|
GTK_STOCK_MISSING_IMAGE,
|
||||||
@ -396,9 +435,22 @@ gtk_image_set_from_file (GtkImage *image,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_image_set_from_pixbuf (image, pixbuf);
|
/* We could just unconditionally set_from_animation,
|
||||||
|
* but it's nicer for memory if we toss the animation
|
||||||
|
* if it's just a single pixbuf
|
||||||
|
*/
|
||||||
|
|
||||||
g_object_unref (G_OBJECT (pixbuf));
|
if (gdk_pixbuf_animation_is_static_image (anim))
|
||||||
|
{
|
||||||
|
gtk_image_set_from_pixbuf (image,
|
||||||
|
gdk_pixbuf_animation_get_static_image (anim));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_image_set_from_animation (image, anim);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (G_OBJECT (anim));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -500,6 +552,41 @@ gtk_image_set_from_icon_set (GtkImage *image,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_image_set_from_animation:
|
||||||
|
* @image: a #GtkImage
|
||||||
|
* @animation: the #GdkPixbufAnimation
|
||||||
|
*
|
||||||
|
* Causes the #GtkImage to display the given animation (or display
|
||||||
|
* nothing, if you set the animation to %NULL).
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
gtk_image_set_from_animation (GtkImage *image,
|
||||||
|
GdkPixbufAnimation *animation)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GTK_IS_IMAGE (image));
|
||||||
|
g_return_if_fail (animation == NULL ||
|
||||||
|
GDK_IS_PIXBUF_ANIMATION (animation));
|
||||||
|
|
||||||
|
if (animation)
|
||||||
|
g_object_ref (G_OBJECT (animation));
|
||||||
|
|
||||||
|
gtk_image_reset (image);
|
||||||
|
|
||||||
|
if (animation != NULL)
|
||||||
|
{
|
||||||
|
image->storage_type = GTK_IMAGE_ANIMATION;
|
||||||
|
|
||||||
|
image->data.anim.anim = animation;
|
||||||
|
image->data.anim.frame_timeout = 0;
|
||||||
|
image->data.anim.iter = NULL;
|
||||||
|
|
||||||
|
gtk_image_update_size (image,
|
||||||
|
gdk_pixbuf_animation_get_width (animation),
|
||||||
|
gdk_pixbuf_animation_get_height (animation));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_image_get_storage_type:
|
* gtk_image_get_storage_type:
|
||||||
* @image: a #GtkImage
|
* @image: a #GtkImage
|
||||||
@ -660,6 +747,33 @@ gtk_image_get_icon_set (GtkImage *image,
|
|||||||
*size = image->data.icon_set.size;
|
*size = image->data.icon_set.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_image_get_animation:
|
||||||
|
* @image: a #GtkImage
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Gets the #GdkPixbufAnimation being displayed by the #GtkImage.
|
||||||
|
* The storage type of the image must be %GTK_IMAGE_EMPTY or
|
||||||
|
* %GTK_IMAGE_ANIMATION (see gtk_image_get_storage_type()).
|
||||||
|
* The caller of this function does not own a reference to the
|
||||||
|
* returned animation.
|
||||||
|
*
|
||||||
|
* Return value: the displayed animation, or %NULL if the image is empty
|
||||||
|
**/
|
||||||
|
GdkPixbufAnimation*
|
||||||
|
gtk_image_get_animation (GtkImage *image)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);
|
||||||
|
g_return_val_if_fail (image->storage_type == GTK_IMAGE_ANIMATION ||
|
||||||
|
image->storage_type == GTK_IMAGE_EMPTY,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (image->storage_type == GTK_IMAGE_EMPTY)
|
||||||
|
image->data.anim.anim = NULL;
|
||||||
|
|
||||||
|
return image->data.anim.anim;
|
||||||
|
}
|
||||||
|
|
||||||
GtkWidget*
|
GtkWidget*
|
||||||
gtk_image_new (GdkImage *val,
|
gtk_image_new (GdkImage *val,
|
||||||
GdkBitmap *mask)
|
GdkBitmap *mask)
|
||||||
@ -695,6 +809,55 @@ gtk_image_get (GtkImage *image,
|
|||||||
gtk_image_get_image (image, val, mask);
|
gtk_image_get_image (image, val, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_image_unmap (GtkWidget *widget)
|
||||||
|
{
|
||||||
|
GtkImage *image;
|
||||||
|
|
||||||
|
image = GTK_IMAGE (widget);
|
||||||
|
|
||||||
|
if (image->storage_type == GTK_IMAGE_ANIMATION)
|
||||||
|
{
|
||||||
|
/* Reset the animation */
|
||||||
|
|
||||||
|
if (image->data.anim.frame_timeout)
|
||||||
|
{
|
||||||
|
g_source_remove (image->data.anim.frame_timeout);
|
||||||
|
image->data.anim.frame_timeout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image->data.anim.iter)
|
||||||
|
{
|
||||||
|
g_object_unref (G_OBJECT (image->data.anim.iter));
|
||||||
|
image->data.anim.iter = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GTK_WIDGET_CLASS (parent_class)->unmap)
|
||||||
|
GTK_WIDGET_CLASS (parent_class)->unmap (widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
gint
|
||||||
|
animation_timeout (gpointer data)
|
||||||
|
{
|
||||||
|
GtkImage *image;
|
||||||
|
|
||||||
|
image = GTK_IMAGE (data);
|
||||||
|
|
||||||
|
image->data.anim.frame_timeout = 0;
|
||||||
|
|
||||||
|
gdk_pixbuf_animation_iter_advance (image->data.anim.iter, NULL);
|
||||||
|
|
||||||
|
if (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter) >= 0)
|
||||||
|
image->data.anim.frame_timeout =
|
||||||
|
g_timeout_add (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter),
|
||||||
|
animation_timeout,
|
||||||
|
image);
|
||||||
|
|
||||||
|
gtk_widget_queue_draw (GTK_WIDGET (image));
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
gtk_image_expose (GtkWidget *widget,
|
gtk_image_expose (GtkWidget *widget,
|
||||||
@ -778,6 +941,24 @@ gtk_image_expose (GtkWidget *widget,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GTK_IMAGE_ANIMATION:
|
||||||
|
{
|
||||||
|
if (image->data.anim.iter == NULL)
|
||||||
|
{
|
||||||
|
image->data.anim.iter = gdk_pixbuf_animation_get_iter (image->data.anim.anim, NULL);
|
||||||
|
|
||||||
|
if (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter) >= 0)
|
||||||
|
image->data.anim.frame_timeout =
|
||||||
|
g_timeout_add (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter),
|
||||||
|
animation_timeout,
|
||||||
|
image);
|
||||||
|
}
|
||||||
|
|
||||||
|
image_bound.width = gdk_pixbuf_animation_get_width (image->data.anim.anim);
|
||||||
|
image_bound.height = gdk_pixbuf_animation_get_height (image->data.anim.anim);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -849,6 +1030,25 @@ gtk_image_expose (GtkWidget *widget,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GTK_IMAGE_ANIMATION:
|
||||||
|
/* don't advance the anim iter here, or we could get frame changes between two
|
||||||
|
* exposes of different areas.
|
||||||
|
*/
|
||||||
|
|
||||||
|
gdk_pixbuf_render_to_drawable_alpha (gdk_pixbuf_animation_iter_get_pixbuf (image->data.anim.iter),
|
||||||
|
widget->window,
|
||||||
|
image_bound.x - x,
|
||||||
|
image_bound.y - y,
|
||||||
|
image_bound.x,
|
||||||
|
image_bound.y,
|
||||||
|
image_bound.width,
|
||||||
|
image_bound.height,
|
||||||
|
GDK_PIXBUF_ALPHA_FULL,
|
||||||
|
128,
|
||||||
|
GDK_RGB_DITHER_NORMAL,
|
||||||
|
0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -876,9 +1076,6 @@ gtk_image_clear (GtkImage *image)
|
|||||||
if (image->data.pixmap.mask)
|
if (image->data.pixmap.mask)
|
||||||
g_object_unref (G_OBJECT (image->data.pixmap.mask));
|
g_object_unref (G_OBJECT (image->data.pixmap.mask));
|
||||||
|
|
||||||
image->data.pixmap.pixmap = NULL;
|
|
||||||
image->data.pixmap.mask = NULL;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GTK_IMAGE_IMAGE:
|
case GTK_IMAGE_IMAGE:
|
||||||
@ -889,9 +1086,6 @@ gtk_image_clear (GtkImage *image)
|
|||||||
if (image->data.image.mask)
|
if (image->data.image.mask)
|
||||||
g_object_unref (G_OBJECT (image->data.image.mask));
|
g_object_unref (G_OBJECT (image->data.image.mask));
|
||||||
|
|
||||||
image->data.image.image = NULL;
|
|
||||||
image->data.image.mask = NULL;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GTK_IMAGE_PIXBUF:
|
case GTK_IMAGE_PIXBUF:
|
||||||
@ -899,26 +1093,26 @@ gtk_image_clear (GtkImage *image)
|
|||||||
if (image->data.pixbuf.pixbuf)
|
if (image->data.pixbuf.pixbuf)
|
||||||
g_object_unref (G_OBJECT (image->data.pixbuf.pixbuf));
|
g_object_unref (G_OBJECT (image->data.pixbuf.pixbuf));
|
||||||
|
|
||||||
image->data.pixbuf.pixbuf = NULL;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GTK_IMAGE_STOCK:
|
case GTK_IMAGE_STOCK:
|
||||||
|
|
||||||
g_free (image->data.stock.stock_id);
|
g_free (image->data.stock.stock_id);
|
||||||
|
|
||||||
image->data.stock.stock_id = NULL;
|
|
||||||
image->data.stock.size = 0;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GTK_IMAGE_ICON_SET:
|
case GTK_IMAGE_ICON_SET:
|
||||||
if (image->data.icon_set.icon_set)
|
if (image->data.icon_set.icon_set)
|
||||||
gtk_icon_set_unref (image->data.icon_set.icon_set);
|
gtk_icon_set_unref (image->data.icon_set.icon_set);
|
||||||
|
|
||||||
image->data.icon_set.size = 0;
|
break;
|
||||||
image->data.icon_set.icon_set = NULL;
|
|
||||||
|
|
||||||
|
case GTK_IMAGE_ANIMATION:
|
||||||
|
if (image->data.anim.frame_timeout)
|
||||||
|
g_source_remove (image->data.anim.frame_timeout);
|
||||||
|
|
||||||
|
if (image->data.anim.anim)
|
||||||
|
g_object_unref (G_OBJECT (image->data.anim.anim));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GTK_IMAGE_EMPTY:
|
case GTK_IMAGE_EMPTY:
|
||||||
@ -928,6 +1122,8 @@ gtk_image_clear (GtkImage *image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
image->storage_type = GTK_IMAGE_EMPTY;
|
image->storage_type = GTK_IMAGE_EMPTY;
|
||||||
|
|
||||||
|
memset (&image->data, '\0', sizeof (image->data));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -52,6 +52,7 @@ typedef struct _GtkImageImageData GtkImageImageData;
|
|||||||
typedef struct _GtkImagePixbufData GtkImagePixbufData;
|
typedef struct _GtkImagePixbufData GtkImagePixbufData;
|
||||||
typedef struct _GtkImageStockData GtkImageStockData;
|
typedef struct _GtkImageStockData GtkImageStockData;
|
||||||
typedef struct _GtkImageIconSetData GtkImageIconSetData;
|
typedef struct _GtkImageIconSetData GtkImageIconSetData;
|
||||||
|
typedef struct _GtkImageAnimationData GtkImageAnimationData;
|
||||||
|
|
||||||
struct _GtkImagePixmapData
|
struct _GtkImagePixmapData
|
||||||
{
|
{
|
||||||
@ -82,6 +83,13 @@ struct _GtkImageIconSetData
|
|||||||
GtkIconSize size;
|
GtkIconSize size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _GtkImageAnimationData
|
||||||
|
{
|
||||||
|
GdkPixbufAnimation *anim;
|
||||||
|
GdkPixbufAnimationIter *iter;
|
||||||
|
guint frame_timeout;
|
||||||
|
};
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
GTK_IMAGE_EMPTY,
|
GTK_IMAGE_EMPTY,
|
||||||
@ -89,7 +97,8 @@ typedef enum
|
|||||||
GTK_IMAGE_IMAGE,
|
GTK_IMAGE_IMAGE,
|
||||||
GTK_IMAGE_PIXBUF,
|
GTK_IMAGE_PIXBUF,
|
||||||
GTK_IMAGE_STOCK,
|
GTK_IMAGE_STOCK,
|
||||||
GTK_IMAGE_ICON_SET
|
GTK_IMAGE_ICON_SET,
|
||||||
|
GTK_IMAGE_ANIMATION
|
||||||
} GtkImageType;
|
} GtkImageType;
|
||||||
|
|
||||||
struct _GtkImage
|
struct _GtkImage
|
||||||
@ -105,6 +114,7 @@ struct _GtkImage
|
|||||||
GtkImagePixbufData pixbuf;
|
GtkImagePixbufData pixbuf;
|
||||||
GtkImageStockData stock;
|
GtkImageStockData stock;
|
||||||
GtkImageIconSetData icon_set;
|
GtkImageIconSetData icon_set;
|
||||||
|
GtkImageAnimationData anim;
|
||||||
} data;
|
} data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -125,6 +135,7 @@ GtkWidget* gtk_image_new_from_stock (const gchar *stock_id,
|
|||||||
GtkIconSize size);
|
GtkIconSize size);
|
||||||
GtkWidget* gtk_image_new_from_icon_set (GtkIconSet *icon_set,
|
GtkWidget* gtk_image_new_from_icon_set (GtkIconSet *icon_set,
|
||||||
GtkIconSize size);
|
GtkIconSize size);
|
||||||
|
GtkWidget* gtk_image_new_from_animation (GdkPixbufAnimation *animation);
|
||||||
|
|
||||||
void gtk_image_set_from_pixmap (GtkImage *image,
|
void gtk_image_set_from_pixmap (GtkImage *image,
|
||||||
GdkPixmap *pixmap,
|
GdkPixmap *pixmap,
|
||||||
@ -142,6 +153,8 @@ void gtk_image_set_from_stock (GtkImage *image,
|
|||||||
void gtk_image_set_from_icon_set (GtkImage *image,
|
void gtk_image_set_from_icon_set (GtkImage *image,
|
||||||
GtkIconSet *icon_set,
|
GtkIconSet *icon_set,
|
||||||
GtkIconSize size);
|
GtkIconSize size);
|
||||||
|
void gtk_image_set_from_animation (GtkImage *image,
|
||||||
|
GdkPixbufAnimation *animation);
|
||||||
|
|
||||||
GtkImageType gtk_image_get_storage_type (GtkImage *image);
|
GtkImageType gtk_image_get_storage_type (GtkImage *image);
|
||||||
|
|
||||||
@ -158,6 +171,7 @@ void gtk_image_get_stock (GtkImage *image,
|
|||||||
void gtk_image_get_icon_set (GtkImage *image,
|
void gtk_image_get_icon_set (GtkImage *image,
|
||||||
GtkIconSet **icon_set,
|
GtkIconSet **icon_set,
|
||||||
GtkIconSize *size);
|
GtkIconSize *size);
|
||||||
|
GdkPixbufAnimation* gtk_image_get_animation (GtkImage *image);
|
||||||
|
|
||||||
|
|
||||||
#ifndef GTK_DISABLE_DEPRECATED
|
#ifndef GTK_DISABLE_DEPRECATED
|
||||||
|
@ -36,6 +36,7 @@ NONE:INT,INT
|
|||||||
NONE:NONE
|
NONE:NONE
|
||||||
NONE:POINTER
|
NONE:POINTER
|
||||||
NONE:STRING,INT,POINTER
|
NONE:STRING,INT,POINTER
|
||||||
|
STRING:DOUBLE
|
||||||
VOID:BOOLEAN
|
VOID:BOOLEAN
|
||||||
VOID:BOXED
|
VOID:BOXED
|
||||||
VOID:BOXED,BOXED
|
VOID:BOXED,BOXED
|
||||||
|
@ -36,6 +36,7 @@ NONE:INT,INT
|
|||||||
NONE:NONE
|
NONE:NONE
|
||||||
NONE:POINTER
|
NONE:POINTER
|
||||||
NONE:STRING,INT,POINTER
|
NONE:STRING,INT,POINTER
|
||||||
|
STRING:DOUBLE
|
||||||
VOID:BOOLEAN
|
VOID:BOOLEAN
|
||||||
VOID:BOXED
|
VOID:BOXED
|
||||||
VOID:BOXED,BOXED
|
VOID:BOXED,BOXED
|
||||||
|
@ -98,6 +98,7 @@ struct _GtkRangeClass
|
|||||||
GtkTroughType trough);
|
GtkTroughType trough);
|
||||||
|
|
||||||
/* Completely broken virtual functions, please ignore */
|
/* Completely broken virtual functions, please ignore */
|
||||||
|
|
||||||
void (* draw_background) (GtkRange *range);
|
void (* draw_background) (GtkRange *range);
|
||||||
void (* clear_background) (GtkRange *range);
|
void (* clear_background) (GtkRange *range);
|
||||||
void (* draw_trough) (GtkRange *range);
|
void (* draw_trough) (GtkRange *range);
|
||||||
|
109
gtk/gtkscale.c
109
gtk/gtkscale.c
@ -27,6 +27,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "gtkintl.h"
|
#include "gtkintl.h"
|
||||||
#include "gtkscale.h"
|
#include "gtkscale.h"
|
||||||
|
#include "gtkmarshal.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ARG_0,
|
ARG_0,
|
||||||
@ -35,6 +36,12 @@ enum {
|
|||||||
ARG_VALUE_POS
|
ARG_VALUE_POS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FORMAT_VALUE,
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint signals[LAST_SIGNAL];
|
||||||
|
|
||||||
static void gtk_scale_class_init (GtkScaleClass *klass);
|
static void gtk_scale_class_init (GtkScaleClass *klass);
|
||||||
static void gtk_scale_init (GtkScale *scale);
|
static void gtk_scale_init (GtkScale *scale);
|
||||||
@ -78,6 +85,22 @@ gtk_scale_get_type (void)
|
|||||||
return scale_type;
|
return scale_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
single_string_accumulator (GSignalInvocationHint *ihint,
|
||||||
|
GValue *return_accu,
|
||||||
|
const GValue *handler_return,
|
||||||
|
gpointer dummy)
|
||||||
|
{
|
||||||
|
gboolean continue_emission;
|
||||||
|
gchar *str;
|
||||||
|
|
||||||
|
str = g_value_get_string (handler_return);
|
||||||
|
g_value_set_string (return_accu, str);
|
||||||
|
continue_emission = str == NULL;
|
||||||
|
|
||||||
|
return continue_emission;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_scale_class_init (GtkScaleClass *class)
|
gtk_scale_class_init (GtkScaleClass *class)
|
||||||
{
|
{
|
||||||
@ -104,6 +127,16 @@ gtk_scale_class_init (GtkScaleClass *class)
|
|||||||
GTK_ARG_READWRITE,
|
GTK_ARG_READWRITE,
|
||||||
ARG_VALUE_POS);
|
ARG_VALUE_POS);
|
||||||
|
|
||||||
|
signals[FORMAT_VALUE] =
|
||||||
|
g_signal_newc ("format_value",
|
||||||
|
G_TYPE_FROM_CLASS (object_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (GtkScaleClass, format_value),
|
||||||
|
single_string_accumulator, NULL,
|
||||||
|
gtk_marshal_STRING__DOUBLE,
|
||||||
|
G_TYPE_STRING, 1,
|
||||||
|
G_TYPE_DOUBLE);
|
||||||
|
|
||||||
object_class->set_arg = gtk_scale_set_arg;
|
object_class->set_arg = gtk_scale_set_arg;
|
||||||
object_class->get_arg = gtk_scale_get_arg;
|
object_class->get_arg = gtk_scale_get_arg;
|
||||||
|
|
||||||
@ -280,58 +313,27 @@ gtk_scale_get_value_size (GtkScale *scale,
|
|||||||
{
|
{
|
||||||
PangoLayout *layout;
|
PangoLayout *layout;
|
||||||
PangoRectangle logical_rect;
|
PangoRectangle logical_rect;
|
||||||
gchar buffer[128];
|
gchar *txt;
|
||||||
gdouble value;
|
|
||||||
gint digits;
|
|
||||||
gint i, j;
|
|
||||||
|
|
||||||
range = GTK_RANGE (scale);
|
range = GTK_RANGE (scale);
|
||||||
|
|
||||||
layout = gtk_widget_create_pango_layout (GTK_WIDGET (scale), NULL);
|
layout = gtk_widget_create_pango_layout (GTK_WIDGET (scale), NULL);
|
||||||
|
|
||||||
value = ABS (range->adjustment->lower);
|
txt = _gtk_scale_format_value (scale, range->adjustment->lower);
|
||||||
if (value == 0) value = 1;
|
pango_layout_set_text (layout, txt, -1);
|
||||||
digits = log10 (value) + 1;
|
g_free (txt);
|
||||||
if (digits > 13)
|
|
||||||
digits = 13;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
if (range->adjustment->lower < 0)
|
|
||||||
buffer[i++] = '-';
|
|
||||||
for (j = 0; j < digits; j++)
|
|
||||||
buffer[i++] = '0';
|
|
||||||
if (GTK_RANGE (scale)->digits)
|
|
||||||
buffer[i++] = '.';
|
|
||||||
for (j = 0; j < GTK_RANGE (scale)->digits; j++)
|
|
||||||
buffer[i++] = '0';
|
|
||||||
buffer[i] = '\0';
|
|
||||||
|
|
||||||
pango_layout_set_text (layout, buffer, i);
|
|
||||||
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||||||
|
|
||||||
if (width)
|
if (width)
|
||||||
*width = logical_rect.width;
|
*width = logical_rect.width;
|
||||||
if (height)
|
if (height)
|
||||||
*height = logical_rect.width;
|
*height = logical_rect.height;
|
||||||
|
|
||||||
value = ABS (range->adjustment->upper);
|
txt = _gtk_scale_format_value (scale, range->adjustment->upper);
|
||||||
if (value == 0) value = 1;
|
pango_layout_set_text (layout, txt, -1);
|
||||||
digits = log10 (value) + 1;
|
g_free (txt);
|
||||||
if (digits > 13)
|
|
||||||
digits = 13;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
if (range->adjustment->upper < 0)
|
|
||||||
buffer[i++] = '-';
|
|
||||||
for (j = 0; j < digits; j++)
|
|
||||||
buffer[i++] = '0';
|
|
||||||
if (GTK_RANGE (scale)->digits)
|
|
||||||
buffer[i++] = '.';
|
|
||||||
for (j = 0; j < GTK_RANGE (scale)->digits; j++)
|
|
||||||
buffer[i++] = '0';
|
|
||||||
buffer[i] = '\0';
|
|
||||||
|
|
||||||
pango_layout_set_text (layout, buffer, i);
|
|
||||||
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||||||
|
|
||||||
if (width)
|
if (width)
|
||||||
@ -383,3 +385,32 @@ gtk_scale_draw_background (GtkRange *range)
|
|||||||
|
|
||||||
gtk_scale_draw_value (GTK_SCALE (range));
|
gtk_scale_draw_value (GTK_SCALE (range));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _gtk_scale_format_value:
|
||||||
|
* @scale: a #GtkScale
|
||||||
|
* @value: adjustment value
|
||||||
|
*
|
||||||
|
* Emits "format_value" signal to format the value, if no user
|
||||||
|
* signal handlers, falls back to a default format.
|
||||||
|
*
|
||||||
|
* Return value: formatted value
|
||||||
|
**/
|
||||||
|
gchar*
|
||||||
|
_gtk_scale_format_value (GtkScale *scale,
|
||||||
|
gdouble value)
|
||||||
|
{
|
||||||
|
gchar *fmt = NULL;
|
||||||
|
|
||||||
|
g_signal_emit (G_OBJECT (scale),
|
||||||
|
signals[FORMAT_VALUE],
|
||||||
|
0,
|
||||||
|
value,
|
||||||
|
&fmt);
|
||||||
|
|
||||||
|
if (fmt)
|
||||||
|
return fmt;
|
||||||
|
else
|
||||||
|
return g_strdup_printf ("%0.*f", GTK_RANGE (scale)->digits,
|
||||||
|
value);
|
||||||
|
}
|
||||||
|
@ -62,6 +62,9 @@ struct _GtkScaleClass
|
|||||||
|
|
||||||
gint value_spacing;
|
gint value_spacing;
|
||||||
|
|
||||||
|
gchar* (* format_value) (GtkRange *range,
|
||||||
|
gdouble value);
|
||||||
|
|
||||||
void (* draw_value) (GtkScale *scale);
|
void (* draw_value) (GtkScale *scale);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -79,6 +82,9 @@ void gtk_scale_get_value_size (GtkScale *scale,
|
|||||||
|
|
||||||
void gtk_scale_draw_value (GtkScale *scale);
|
void gtk_scale_draw_value (GtkScale *scale);
|
||||||
|
|
||||||
|
gchar *_gtk_scale_format_value (GtkScale *scale,
|
||||||
|
gdouble value);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
@ -2106,6 +2106,127 @@ gtk_text_buffer_remove_tag_by_name (GtkTextBuffer *buffer,
|
|||||||
gtk_text_buffer_emit_tag (buffer, tag, FALSE, start, end);
|
gtk_text_buffer_emit_tag (buffer, tag, FALSE, start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
pointer_cmp (gconstpointer a,
|
||||||
|
gconstpointer b)
|
||||||
|
{
|
||||||
|
if (a < b)
|
||||||
|
return -1;
|
||||||
|
else if (a > b)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_text_buffer_remove_all_tags:
|
||||||
|
* @buffer: a #GtkTextBuffer
|
||||||
|
* @start: one bound of range to be untagged
|
||||||
|
* @end: other bound of range to be untagged
|
||||||
|
*
|
||||||
|
* Removes all tags in the range between @start and @end. Be careful
|
||||||
|
* with this function; it could remove tags added in code unrelated to
|
||||||
|
* the code you're currently writing. That is, using this function is
|
||||||
|
* probably a bad idea if you have two or more unrelated code sections
|
||||||
|
* that add tags.
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
gtk_text_buffer_remove_all_tags (GtkTextBuffer *buffer,
|
||||||
|
const GtkTextIter *start,
|
||||||
|
const GtkTextIter *end)
|
||||||
|
{
|
||||||
|
GtkTextIter first, second, tmp;
|
||||||
|
GSList *tags;
|
||||||
|
GSList *tmp_list;
|
||||||
|
GSList *prev;
|
||||||
|
GtkTextTag *tag;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
|
||||||
|
g_return_if_fail (start != NULL);
|
||||||
|
g_return_if_fail (end != NULL);
|
||||||
|
|
||||||
|
first = *start;
|
||||||
|
second = *end;
|
||||||
|
|
||||||
|
gtk_text_iter_reorder (&first, &second);
|
||||||
|
|
||||||
|
/* Get all tags turned on at the start */
|
||||||
|
tags = gtk_text_iter_get_tags (&first);
|
||||||
|
|
||||||
|
/* Find any that are toggled on within the range */
|
||||||
|
tmp = first;
|
||||||
|
while (gtk_text_iter_forward_to_tag_toggle (&tmp, NULL))
|
||||||
|
{
|
||||||
|
GSList *toggled;
|
||||||
|
GSList *tmp_list2;
|
||||||
|
|
||||||
|
if (gtk_text_iter_compare (&tmp, &second) >= 0)
|
||||||
|
break; /* past the end of the range */
|
||||||
|
|
||||||
|
toggled = gtk_text_iter_get_toggled_tags (&tmp, TRUE);
|
||||||
|
|
||||||
|
/* We could end up with a really big-ass list here.
|
||||||
|
* Fix it someday.
|
||||||
|
*/
|
||||||
|
tmp_list2 = toggled;
|
||||||
|
while (tmp_list2 != NULL)
|
||||||
|
{
|
||||||
|
tags = g_slist_prepend (tags, tmp_list2->data);
|
||||||
|
|
||||||
|
tmp_list2 = g_slist_next (tmp_list2);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_slist_free (toggled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sort the list */
|
||||||
|
tags = g_slist_sort (tags, pointer_cmp);
|
||||||
|
|
||||||
|
/* Strip duplicates */
|
||||||
|
tag = NULL;
|
||||||
|
prev = NULL;
|
||||||
|
tmp_list = tags;
|
||||||
|
while (tmp_list != NULL)
|
||||||
|
{
|
||||||
|
if (tag == tmp_list->data)
|
||||||
|
{
|
||||||
|
/* duplicate */
|
||||||
|
if (prev)
|
||||||
|
prev->next = tmp_list->next;
|
||||||
|
|
||||||
|
tmp_list->next = NULL;
|
||||||
|
|
||||||
|
g_slist_free (tmp_list);
|
||||||
|
|
||||||
|
tmp_list = prev->next;
|
||||||
|
/* prev is unchanged */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* not a duplicate */
|
||||||
|
tag = GTK_TEXT_TAG (tmp_list->data);
|
||||||
|
prev = tmp_list;
|
||||||
|
tmp_list = tmp_list->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_foreach (tags, (GFunc) g_object_ref, NULL);
|
||||||
|
|
||||||
|
tmp_list = tags;
|
||||||
|
while (tmp_list != NULL)
|
||||||
|
{
|
||||||
|
tag = GTK_TEXT_TAG (tmp_list->data);
|
||||||
|
|
||||||
|
gtk_text_buffer_remove_tag (buffer, tag, &first, &second);
|
||||||
|
|
||||||
|
tmp_list = tmp_list->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_foreach (tags, (GFunc) g_object_unref, NULL);
|
||||||
|
|
||||||
|
g_slist_free (tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Obtain various iterators
|
* Obtain various iterators
|
||||||
|
@ -266,6 +266,9 @@ void gtk_text_buffer_remove_tag_by_name (GtkTextBuffer *buffer,
|
|||||||
const gchar *name,
|
const gchar *name,
|
||||||
const GtkTextIter *start,
|
const GtkTextIter *start,
|
||||||
const GtkTextIter *end);
|
const GtkTextIter *end);
|
||||||
|
void gtk_text_buffer_remove_all_tags (GtkTextBuffer *buffer,
|
||||||
|
const GtkTextIter *start,
|
||||||
|
const GtkTextIter *end);
|
||||||
|
|
||||||
|
|
||||||
/* You can either ignore the return value, or use it to
|
/* You can either ignore the return value, or use it to
|
||||||
|
@ -1511,7 +1511,7 @@ gtk_text_iter_is_end (const GtkTextIter *iter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_text_iter_is_first:
|
* gtk_text_iter_is_start:
|
||||||
* @iter: an iterator
|
* @iter: an iterator
|
||||||
*
|
*
|
||||||
* Returns TRUE if @iter is the first iterator in the buffer, that is
|
* Returns TRUE if @iter is the first iterator in the buffer, that is
|
||||||
@ -1520,7 +1520,7 @@ gtk_text_iter_is_end (const GtkTextIter *iter)
|
|||||||
* Return value: whether @iter is the first in the buffer
|
* Return value: whether @iter is the first in the buffer
|
||||||
**/
|
**/
|
||||||
gboolean
|
gboolean
|
||||||
gtk_text_iter_is_first (const GtkTextIter *iter)
|
gtk_text_iter_is_start (const GtkTextIter *iter)
|
||||||
{
|
{
|
||||||
return gtk_text_iter_get_offset (iter) == 0;
|
return gtk_text_iter_get_offset (iter) == 0;
|
||||||
}
|
}
|
||||||
@ -4253,7 +4253,7 @@ lines_window_init (LinesWindow *win,
|
|||||||
/* If we start on line 1, there are 2 lines to search (0 and 1), so
|
/* If we start on line 1, there are 2 lines to search (0 and 1), so
|
||||||
* n_lines can be 2.
|
* n_lines can be 2.
|
||||||
*/
|
*/
|
||||||
if (gtk_text_iter_is_first (start) ||
|
if (gtk_text_iter_is_start (start) ||
|
||||||
gtk_text_iter_get_line (start) + 1 < win->n_lines)
|
gtk_text_iter_get_line (start) + 1 < win->n_lines)
|
||||||
{
|
{
|
||||||
/* Already at the end, or not enough lines to match */
|
/* Already at the end, or not enough lines to match */
|
||||||
|
@ -108,7 +108,8 @@ GSList * gtk_text_iter_get_marks (const GtkTextIter *iter);
|
|||||||
GtkTextChildAnchor* gtk_text_iter_get_child_anchor (const GtkTextIter *iter);
|
GtkTextChildAnchor* gtk_text_iter_get_child_anchor (const GtkTextIter *iter);
|
||||||
|
|
||||||
/* Return list of tags toggled at this point (toggled_on determines
|
/* Return list of tags toggled at this point (toggled_on determines
|
||||||
whether the list is of on-toggles or off-toggles) */
|
* whether the list is of on-toggles or off-toggles)
|
||||||
|
*/
|
||||||
GSList *gtk_text_iter_get_toggled_tags (const GtkTextIter *iter,
|
GSList *gtk_text_iter_get_toggled_tags (const GtkTextIter *iter,
|
||||||
gboolean toggled_on);
|
gboolean toggled_on);
|
||||||
|
|
||||||
@ -145,7 +146,7 @@ gboolean gtk_text_iter_get_attributes (const GtkTextIter *iter,
|
|||||||
GtkTextAttributes *values);
|
GtkTextAttributes *values);
|
||||||
gchar* gtk_text_iter_get_language (const GtkTextIter *iter);
|
gchar* gtk_text_iter_get_language (const GtkTextIter *iter);
|
||||||
gboolean gtk_text_iter_is_end (const GtkTextIter *iter);
|
gboolean gtk_text_iter_is_end (const GtkTextIter *iter);
|
||||||
gboolean gtk_text_iter_is_first (const GtkTextIter *iter);
|
gboolean gtk_text_iter_is_start (const GtkTextIter *iter);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Moving around the buffer
|
* Moving around the buffer
|
||||||
|
@ -1280,6 +1280,16 @@ add_text_attrs (GtkTextLayout *layout,
|
|||||||
attr->end_index = start + byte_count;
|
attr->end_index = start + byte_count;
|
||||||
|
|
||||||
pango_attr_list_insert (attrs, attr);
|
pango_attr_list_insert (attrs, attr);
|
||||||
|
|
||||||
|
if (style->font_scale != 1.0)
|
||||||
|
{
|
||||||
|
attr = pango_attr_scale_new (style->font_scale);
|
||||||
|
|
||||||
|
attr->start_index = start;
|
||||||
|
attr->end_index = start + byte_count;
|
||||||
|
|
||||||
|
pango_attr_list_insert (attrs, attr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -85,6 +85,7 @@ enum {
|
|||||||
PROP_STRETCH,
|
PROP_STRETCH,
|
||||||
PROP_SIZE,
|
PROP_SIZE,
|
||||||
PROP_SIZE_POINTS,
|
PROP_SIZE_POINTS,
|
||||||
|
PROP_SCALE,
|
||||||
PROP_PIXELS_ABOVE_LINES,
|
PROP_PIXELS_ABOVE_LINES,
|
||||||
PROP_PIXELS_BELOW_LINES,
|
PROP_PIXELS_BELOW_LINES,
|
||||||
PROP_PIXELS_INSIDE_WRAP,
|
PROP_PIXELS_INSIDE_WRAP,
|
||||||
@ -114,6 +115,7 @@ enum {
|
|||||||
PROP_WEIGHT_SET,
|
PROP_WEIGHT_SET,
|
||||||
PROP_STRETCH_SET,
|
PROP_STRETCH_SET,
|
||||||
PROP_SIZE_SET,
|
PROP_SIZE_SET,
|
||||||
|
PROP_SCALE_SET,
|
||||||
PROP_PIXELS_ABOVE_LINES_SET,
|
PROP_PIXELS_ABOVE_LINES_SET,
|
||||||
PROP_PIXELS_BELOW_LINES_SET,
|
PROP_PIXELS_BELOW_LINES_SET,
|
||||||
PROP_PIXELS_INSIDE_WRAP_SET,
|
PROP_PIXELS_INSIDE_WRAP_SET,
|
||||||
@ -349,6 +351,16 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
|
|||||||
0,
|
0,
|
||||||
G_PARAM_READABLE | G_PARAM_WRITABLE));
|
G_PARAM_READABLE | G_PARAM_WRITABLE));
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_SCALE,
|
||||||
|
g_param_spec_double ("scale",
|
||||||
|
_("Font scale"),
|
||||||
|
_("Font scale"),
|
||||||
|
0.0,
|
||||||
|
G_MAXDOUBLE,
|
||||||
|
1.0,
|
||||||
|
G_PARAM_READABLE | G_PARAM_WRITABLE));
|
||||||
|
|
||||||
g_object_class_install_property (object_class,
|
g_object_class_install_property (object_class,
|
||||||
PROP_SIZE_POINTS,
|
PROP_SIZE_POINTS,
|
||||||
g_param_spec_double ("size_points",
|
g_param_spec_double ("size_points",
|
||||||
@ -543,6 +555,10 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
|
|||||||
_("Font size set"),
|
_("Font size set"),
|
||||||
_("Whether this tag affects the font size"));
|
_("Whether this tag affects the font size"));
|
||||||
|
|
||||||
|
ADD_SET_PROP ("scale_set", PROP_SCALE_SET,
|
||||||
|
_("Font scale set"),
|
||||||
|
_("Whether this tag scales the font size by a factor"));
|
||||||
|
|
||||||
ADD_SET_PROP ("justification_set", PROP_JUSTIFICATION_SET,
|
ADD_SET_PROP ("justification_set", PROP_JUSTIFICATION_SET,
|
||||||
_("Justification set"),
|
_("Justification set"),
|
||||||
_("Whether this tag affects paragraph justification"));
|
_("Whether this tag affects paragraph justification"));
|
||||||
@ -963,6 +979,12 @@ gtk_text_tag_set_property (GObject *object,
|
|||||||
size_changed = TRUE;
|
size_changed = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_SCALE:
|
||||||
|
text_tag->values->font_scale = g_value_get_double (value);
|
||||||
|
text_tag->scale_set = TRUE;
|
||||||
|
size_changed = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
case PROP_SIZE_POINTS:
|
case PROP_SIZE_POINTS:
|
||||||
text_tag->values->font.size = g_value_get_double (value) * PANGO_SCALE;
|
text_tag->values->font.size = g_value_get_double (value) * PANGO_SCALE;
|
||||||
text_tag->size_set = TRUE;
|
text_tag->size_set = TRUE;
|
||||||
@ -1152,6 +1174,11 @@ gtk_text_tag_set_property (GObject *object,
|
|||||||
size_changed = TRUE;
|
size_changed = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_SCALE_SET:
|
||||||
|
text_tag->scale_set = g_value_get_boolean (value);
|
||||||
|
size_changed = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
case PROP_PIXELS_ABOVE_LINES_SET:
|
case PROP_PIXELS_ABOVE_LINES_SET:
|
||||||
text_tag->pixels_above_lines_set = g_value_get_boolean (value);
|
text_tag->pixels_above_lines_set = g_value_get_boolean (value);
|
||||||
size_changed = TRUE;
|
size_changed = TRUE;
|
||||||
@ -1337,6 +1364,10 @@ gtk_text_tag_get_property (GObject *object,
|
|||||||
g_value_set_double (value, ((double)tag->values->font.size) / (double)PANGO_SCALE);
|
g_value_set_double (value, ((double)tag->values->font.size) / (double)PANGO_SCALE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_SCALE:
|
||||||
|
g_value_set_double (value, tag->values->font_scale);
|
||||||
|
break;
|
||||||
|
|
||||||
case PROP_PIXELS_ABOVE_LINES:
|
case PROP_PIXELS_ABOVE_LINES:
|
||||||
g_value_set_int (value, tag->values->pixels_above_lines);
|
g_value_set_int (value, tag->values->pixels_above_lines);
|
||||||
break;
|
break;
|
||||||
@ -1446,6 +1477,10 @@ gtk_text_tag_get_property (GObject *object,
|
|||||||
g_value_set_boolean (value, tag->size_set);
|
g_value_set_boolean (value, tag->size_set);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_SCALE_SET:
|
||||||
|
g_value_set_boolean (value, tag->scale_set);
|
||||||
|
break;
|
||||||
|
|
||||||
case PROP_PIXELS_ABOVE_LINES_SET:
|
case PROP_PIXELS_ABOVE_LINES_SET:
|
||||||
g_value_set_boolean (value, tag->pixels_above_lines_set);
|
g_value_set_boolean (value, tag->pixels_above_lines_set);
|
||||||
break;
|
break;
|
||||||
@ -1724,6 +1759,8 @@ gtk_text_attributes_new (void)
|
|||||||
|
|
||||||
values->language = gtk_get_default_language ();
|
values->language = gtk_get_default_language ();
|
||||||
|
|
||||||
|
values->font_scale = 1.0;
|
||||||
|
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1965,6 +2002,10 @@ _gtk_text_attributes_fill_from_tags (GtkTextAttributes *dest,
|
|||||||
if (tag->size_set)
|
if (tag->size_set)
|
||||||
dest->font.size = vals->font.size;
|
dest->font.size = vals->font.size;
|
||||||
|
|
||||||
|
/* multiply all the scales together to get a composite */
|
||||||
|
if (tag->scale_set)
|
||||||
|
dest->font_scale *= vals->font_scale;
|
||||||
|
|
||||||
if (tag->justification_set)
|
if (tag->justification_set)
|
||||||
dest->justification = vals->justification;
|
dest->justification = vals->justification;
|
||||||
|
|
||||||
@ -2038,6 +2079,7 @@ _gtk_text_tag_affects_size (GtkTextTag *tag)
|
|||||||
tag->variant_set ||
|
tag->variant_set ||
|
||||||
tag->weight_set ||
|
tag->weight_set ||
|
||||||
tag->size_set ||
|
tag->size_set ||
|
||||||
|
tag->scale_set ||
|
||||||
tag->stretch_set ||
|
tag->stretch_set ||
|
||||||
tag->justification_set ||
|
tag->justification_set ||
|
||||||
tag->left_margin_set ||
|
tag->left_margin_set ||
|
||||||
|
@ -60,6 +60,7 @@ struct _GtkTextTag
|
|||||||
guint weight_set : 1;
|
guint weight_set : 1;
|
||||||
guint stretch_set : 1;
|
guint stretch_set : 1;
|
||||||
guint size_set : 1;
|
guint size_set : 1;
|
||||||
|
guint scale_set : 1;
|
||||||
guint fg_stipple_set : 1;
|
guint fg_stipple_set : 1;
|
||||||
guint justification_set : 1;
|
guint justification_set : 1;
|
||||||
guint left_margin_set : 1;
|
guint left_margin_set : 1;
|
||||||
@ -148,6 +149,8 @@ struct _GtkTextAttributes
|
|||||||
/* Individual chunks of this can be set/unset as a group */
|
/* Individual chunks of this can be set/unset as a group */
|
||||||
PangoFontDescription font;
|
PangoFontDescription font;
|
||||||
|
|
||||||
|
gdouble font_scale;
|
||||||
|
|
||||||
gint left_margin;
|
gint left_margin;
|
||||||
|
|
||||||
gint indent;
|
gint indent;
|
||||||
|
@ -506,6 +506,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
|
|||||||
GTK_ARG_READWRITE, ARG_PIXELS_INSIDE_WRAP);
|
GTK_ARG_READWRITE, ARG_PIXELS_INSIDE_WRAP);
|
||||||
gtk_object_add_arg_type ("GtkTextView::editable", GTK_TYPE_BOOL,
|
gtk_object_add_arg_type ("GtkTextView::editable", GTK_TYPE_BOOL,
|
||||||
GTK_ARG_READWRITE, ARG_EDITABLE);
|
GTK_ARG_READWRITE, ARG_EDITABLE);
|
||||||
|
|
||||||
gtk_object_add_arg_type ("GtkTextView::wrap_mode", GTK_TYPE_WRAP_MODE,
|
gtk_object_add_arg_type ("GtkTextView::wrap_mode", GTK_TYPE_WRAP_MODE,
|
||||||
GTK_ARG_READWRITE, ARG_WRAP_MODE);
|
GTK_ARG_READWRITE, ARG_WRAP_MODE);
|
||||||
gtk_object_add_arg_type ("GtkTextView::justify", GTK_TYPE_JUSTIFICATION,
|
gtk_object_add_arg_type ("GtkTextView::justify", GTK_TYPE_JUSTIFICATION,
|
||||||
|
@ -532,7 +532,6 @@ gtk_vscale_draw_value (GtkScale *scale)
|
|||||||
{
|
{
|
||||||
GtkStateType state_type;
|
GtkStateType state_type;
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
gchar buffer[32];
|
|
||||||
gint width, height;
|
gint width, height;
|
||||||
gint x, y;
|
gint x, y;
|
||||||
|
|
||||||
@ -545,10 +544,14 @@ gtk_vscale_draw_value (GtkScale *scale)
|
|||||||
{
|
{
|
||||||
PangoLayout *layout;
|
PangoLayout *layout;
|
||||||
PangoRectangle logical_rect;
|
PangoRectangle logical_rect;
|
||||||
|
gchar *txt;
|
||||||
|
|
||||||
sprintf (buffer, "%0.*f", GTK_RANGE (scale)->digits, GTK_RANGE (scale)->adjustment->value);
|
txt = _gtk_scale_format_value (scale,
|
||||||
|
GTK_RANGE (scale)->adjustment->value);
|
||||||
|
|
||||||
|
layout = gtk_widget_create_pango_layout (widget, txt);
|
||||||
|
g_free (txt);
|
||||||
|
|
||||||
layout = gtk_widget_create_pango_layout (widget, buffer);
|
|
||||||
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||||||
|
|
||||||
switch (scale->value_pos)
|
switch (scale->value_pos)
|
||||||
|
@ -6511,6 +6511,13 @@ create_event_watcher (void)
|
|||||||
* GtkRange
|
* GtkRange
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static gchar*
|
||||||
|
reformat_value (GtkScale *scale,
|
||||||
|
gdouble value)
|
||||||
|
{
|
||||||
|
return g_strdup_printf ("-->%g<--", value);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
create_range_controls (void)
|
create_range_controls (void)
|
||||||
{
|
{
|
||||||
@ -6563,6 +6570,15 @@ create_range_controls (void)
|
|||||||
gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
|
gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
|
||||||
gtk_widget_show (scrollbar);
|
gtk_widget_show (scrollbar);
|
||||||
|
|
||||||
|
scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
|
||||||
|
gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
|
||||||
|
gtk_signal_connect (GTK_OBJECT (scale),
|
||||||
|
"format_value",
|
||||||
|
GTK_SIGNAL_FUNC (reformat_value),
|
||||||
|
NULL);
|
||||||
|
gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
|
||||||
|
gtk_widget_show (scale);
|
||||||
|
|
||||||
hbox = gtk_hbox_new (FALSE, 0);
|
hbox = gtk_hbox_new (FALSE, 0);
|
||||||
|
|
||||||
scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
|
scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
|
||||||
@ -6580,6 +6596,16 @@ create_range_controls (void)
|
|||||||
gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
|
gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
|
||||||
gtk_widget_show (scale);
|
gtk_widget_show (scale);
|
||||||
|
|
||||||
|
scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
|
||||||
|
gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
|
||||||
|
gtk_signal_connect (GTK_OBJECT (scale),
|
||||||
|
"format_value",
|
||||||
|
GTK_SIGNAL_FUNC (reformat_value),
|
||||||
|
NULL);
|
||||||
|
gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
|
||||||
|
gtk_widget_show (scale);
|
||||||
|
|
||||||
|
|
||||||
gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
|
gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
|
||||||
gtk_widget_show (hbox);
|
gtk_widget_show (hbox);
|
||||||
|
|
||||||
@ -8159,8 +8185,13 @@ configure_event_callback (GtkWidget *widget,
|
|||||||
gchar *msg;
|
gchar *msg;
|
||||||
gint x, y;
|
gint x, y;
|
||||||
|
|
||||||
x = widget->allocation.x;
|
#if 0
|
||||||
y = widget->allocation.y;
|
/* FIXME */
|
||||||
|
gtk_window_get_location (GTK_WINDOW (widget), &x, &y);
|
||||||
|
#else
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
msg = g_strdup_printf ("event: %d,%d %d x %d\n"
|
msg = g_strdup_printf ("event: %d,%d %d x %d\n"
|
||||||
"location: %d, %d",
|
"location: %d, %d",
|
||||||
@ -8235,6 +8266,26 @@ set_location_callback (GtkWidget *widget,
|
|||||||
gtk_widget_set_uposition (g_object_get_data (data, "target"), x, y);
|
gtk_widget_set_uposition (g_object_get_data (data, "target"), x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_geometry_callback (GtkWidget *entry,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
gchar *text;
|
||||||
|
GtkWindow *target;
|
||||||
|
|
||||||
|
target = GTK_WINDOW (g_object_get_data (G_OBJECT (data), "target"));
|
||||||
|
|
||||||
|
text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* FIXME */
|
||||||
|
if (!gtk_window_parse_geometry (target, text))
|
||||||
|
g_print ("Bad geometry string '%s'\n", text);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_free (text);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
allow_shrink_callback (GtkWidget *widget,
|
allow_shrink_callback (GtkWidget *widget,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
@ -8282,6 +8333,7 @@ window_controls (GtkWidget *window)
|
|||||||
GtkWidget *button;
|
GtkWidget *button;
|
||||||
GtkWidget *spin;
|
GtkWidget *spin;
|
||||||
GtkAdjustment *adj;
|
GtkAdjustment *adj;
|
||||||
|
GtkWidget *entry;
|
||||||
GtkWidget *om;
|
GtkWidget *om;
|
||||||
GtkWidget *menu;
|
GtkWidget *menu;
|
||||||
gint i;
|
gint i;
|
||||||
@ -8327,6 +8379,13 @@ window_controls (GtkWidget *window)
|
|||||||
|
|
||||||
g_object_set_data (G_OBJECT (control_window), "spin2", spin);
|
g_object_set_data (G_OBJECT (control_window), "spin2", spin);
|
||||||
|
|
||||||
|
entry = gtk_entry_new ();
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (entry), "changed",
|
||||||
|
GTK_SIGNAL_FUNC (set_geometry_callback),
|
||||||
|
control_window);
|
||||||
|
|
||||||
button = gtk_button_new_with_label ("Queue resize");
|
button = gtk_button_new_with_label ("Queue resize");
|
||||||
gtk_signal_connect_object (GTK_OBJECT (button),
|
gtk_signal_connect_object (GTK_OBJECT (button),
|
||||||
"clicked",
|
"clicked",
|
||||||
@ -8386,6 +8445,20 @@ window_controls (GtkWidget *window)
|
|||||||
GTK_OBJECT (control_window));
|
GTK_OBJECT (control_window));
|
||||||
gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
button = gtk_button_new_with_mnemonic ("_Show");
|
||||||
|
gtk_signal_connect_object (GTK_OBJECT (button),
|
||||||
|
"clicked",
|
||||||
|
GTK_SIGNAL_FUNC (gtk_widget_show),
|
||||||
|
GTK_OBJECT (window));
|
||||||
|
gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
button = gtk_button_new_with_mnemonic ("_Hide");
|
||||||
|
gtk_signal_connect_object (GTK_OBJECT (button),
|
||||||
|
"clicked",
|
||||||
|
GTK_SIGNAL_FUNC (gtk_widget_hide),
|
||||||
|
GTK_OBJECT (window));
|
||||||
|
gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
||||||
|
|
||||||
menu = gtk_menu_new ();
|
menu = gtk_menu_new ();
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
@ -1063,6 +1063,23 @@ do_apply_colors (gpointer callback_data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_remove_tags (gpointer callback_data,
|
||||||
|
guint callback_action,
|
||||||
|
GtkWidget *widget)
|
||||||
|
{
|
||||||
|
View *view = view_from_widget (widget);
|
||||||
|
GtkTextIter start;
|
||||||
|
GtkTextIter end;
|
||||||
|
|
||||||
|
if (gtk_text_buffer_get_selection_bounds (view->buffer->buffer,
|
||||||
|
&start, &end))
|
||||||
|
{
|
||||||
|
gtk_text_buffer_remove_all_tags (view->buffer->buffer,
|
||||||
|
&start, &end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
RESPONSE_FORWARD,
|
RESPONSE_FORWARD,
|
||||||
@ -1235,6 +1252,7 @@ static GtkItemFactoryEntry menu_items[] =
|
|||||||
{ "/Attributes/Default tabs", NULL, do_apply_tabs, TRUE, NULL },
|
{ "/Attributes/Default tabs", NULL, do_apply_tabs, TRUE, NULL },
|
||||||
{ "/Attributes/Color cycles", NULL, do_apply_colors, TRUE, NULL },
|
{ "/Attributes/Color cycles", NULL, do_apply_colors, TRUE, NULL },
|
||||||
{ "/Attributes/No colors", NULL, do_apply_colors, FALSE, NULL },
|
{ "/Attributes/No colors", NULL, do_apply_colors, FALSE, NULL },
|
||||||
|
{ "/Attributes/Remove all tags", NULL, do_remove_tags, 0, NULL },
|
||||||
{ "/_Test", NULL, 0, 0, "<Branch>" },
|
{ "/_Test", NULL, 0, 0, "<Branch>" },
|
||||||
{ "/Test/_Example", NULL, do_example, 0, NULL },
|
{ "/Test/_Example", NULL, do_example, 0, NULL },
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user