summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2011-03-17 13:09:27 +0100
committerBenjamin Otte <otte@redhat.com>2011-03-24 17:32:36 +0100
commit7e303babfaeab3abc2abe07a394ece7f71c6381d (patch)
tree9b1d929dcc145f7498eb1ab833e69a2d6d3aefe8
parente84e31d71bffa164bbc508a5ce1ce156b7d66716 (diff)
pixbuf: Add libpig-pixbuf and infrastructure
This adds a separate library for interfacing with GdkPixbuf. Also, the picture implementation keeping a pixbuf is included.
-rw-r--r--configure.ac2
-rw-r--r--data/pig-pixbuf.pc.in2
-rw-r--r--doc/Makefile.am5
-rw-r--r--doc/pig-docs.sgml7
-rw-r--r--doc/pig-sections.txt24
-rw-r--r--pig/Makefile.am27
-rw-r--r--pig/pig-pixbuf-picture.c520
-rw-r--r--pig/pig-pixbuf-picture.h76
-rw-r--r--pig/pig-pixbuf.h40
9 files changed, 700 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index 7c4b29b..cf2c89d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -105,7 +105,7 @@ if test "$enable_pixbuf" = "yes"; then
else
AC_MSG_NOTICE([pig-pixbuf library will not be built.])
fi
-AM_CONDITIONAL(WITH_, [test "x$HAVE_PIXBUF" = xyes])
+AM_CONDITIONAL(HAVE_PIXBUF, [test "x$HAVE_PIXBUF" = xyes])
dnl
diff --git a/data/pig-pixbuf.pc.in b/data/pig-pixbuf.pc.in
index d9ac34b..62402b1 100644
--- a/data/pig-pixbuf.pc.in
+++ b/data/pig-pixbuf.pc.in
@@ -7,5 +7,5 @@ Name: pig-pixbuf
Description: GdkPixbuf support for libpig
Version: @VERSION@
Requires: glib-2.0 >= @GLIB_VER@ gobject-2.0 >= @GLIB_VER@ cairo >= @CAIRO_VER@ cairo-gobject >= @CAIRO_VER@ pig-@PIG_MAJORMINOR@ >= @VERSION@
-Libs:
+Libs: -L${libdir} -lpig-pixbuf-@PIG_MAJORMINOR@
Cflags: -I${includedir} -DPIG_PIXBUF_ENABLED
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 9e91215..06730ee 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -75,8 +75,13 @@ expand_content_files=
# signals and properties.
# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
+if HAVE_PIXBUF
+INCLUDES=$(PIG_PIXBUF_CFLAGS)
+GTKDOC_LIBS=$(PIG_PIXBUF_LIBS)
+else
INCLUDES=$(PIG_CFLAGS)
GTKDOC_LIBS=$(PIG_LIBS)
+endif
# This includes the standard gtk-doc make rules, copied by gtkdocize.
include $(top_srcdir)/gtk-doc.make
diff --git a/doc/pig-docs.sgml b/doc/pig-docs.sgml
index f81147d..e13b42e 100644
--- a/doc/pig-docs.sgml
+++ b/doc/pig-docs.sgml
@@ -15,11 +15,16 @@
</bookinfo>
<reference id="reference">
- <title>API Reference</title>
+ <title>Pig API Reference</title>
<xi:include href="xml/picture.xml" />
<xi:include href="xml/version.xml" />
</reference>
+ <reference id="pixbuf-reference">
+ <title>Pig-Pixbuf API Reference</title>
+ <xi:include href="xml/pixbuf-picture.xml" />
+ </reference>
+
<index id="api-index-full">
<title>Index of all symbols</title>
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
diff --git a/doc/pig-sections.txt b/doc/pig-sections.txt
index 27f2a40..a08f7e5 100644
--- a/doc/pig-sections.txt
+++ b/doc/pig-sections.txt
@@ -35,3 +35,27 @@ pig_version
pig_version_string
</SECTION>
+<SECTION>
+<FILE>pixbuf-picture</FILE>
+<TITLE>PigPixbufPicture</TITLE>
+PigPixbufPicture
+PigPixbufPictureClass
+pig_pixbuf_picture_get_keep_pixbuf
+pig_pixbuf_picture_get_keep_surface
+pig_pixbuf_picture_get_pixbuf
+pig_pixbuf_picture_new
+pig_pixbuf_picture_set_keep_pixbuf
+pig_pixbuf_picture_set_keep_surface
+pig_pixbuf_picture_set_pixbuf
+pig_pixbuf_create_surface
+pig_pixbuf_get_from_picture
+<SUBSECTION Standard>
+PigPixbufPicturePrivate
+PIG_PIXBUF_PICTURE
+PIG_IS_PIXBUF_PICTURE
+PIG_TYPE_PIXBUF_PICTURE
+pig_pixbuf_picture_get_type
+PIG_PIXBUF_PICTURE_CLASS
+PIG_IS_PIXBUF_PICTURE_CLASS
+PIG_PIXBUF_PICTURE_GET_CLASS
+</SECTION>
diff --git a/pig/Makefile.am b/pig/Makefile.am
index 5d71854..d760e49 100644
--- a/pig/Makefile.am
+++ b/pig/Makefile.am
@@ -22,9 +22,36 @@ public_headers = \
pig.h \
pig-picture.h
+if HAVE_PIXBUF
+lib_LTLIBRARIES += libpig-pixbuf-@PIG_MAJORMINOR@.la
+
+libpig_pixbuf_@PIG_MAJORMINOR@_la_SOURCES = \
+ pig-pixbuf-picture.c
+
+libpig_pixbuf_@PIG_MAJORMINOR@_la_CFLAGS = \
+ $(GLOBAL_CFLAGS) $(PIG_CFLAGS) $(PIXBUF_CFLAGS) \
+ -DG_LOG_DOMAIN=\"Pig-Pixbuf\" \
+ -DPIG_PIXBUF_COMPILATION
+
+libpig_pixbuf_@PIG_MAJORMINOR@_la_LIBS = \
+ libpig-@PIG_MAJORMINOR@.la
+
+libpig_pixbuf_@PIG_MAJORMINOR@_la_LDFLAGS = \
+ -version-info $(PIG_LIBVERSION) \
+ -export-symbols-regex '^(pig_pixbuf_.*)' \
+ $(PIG_LIBS) $(PIXBUF_LIBS)
+
+public_pixbuf_headers = \
+ pig-pixbuf.h \
+ pig-pixbuf-picture.h
+else
+public_pixbuf_headers =
+endif
+
libpig_@PIG_MAJORMINOR@includedir = $(includedir)/pig-@PIG_MAJORMINOR@/pig
libpig_@PIG_MAJORMINOR@include_HEADERS = \
$(public_headers) \
+ $(public_pixbuf_headers) \
pig-enums.h
nodist_libpig_@PIG_MAJORMINOR@include_HEADERS = \
diff --git a/pig/pig-pixbuf-picture.c b/pig/pig-pixbuf-picture.c
new file mode 100644
index 0000000..d00bb76
--- /dev/null
+++ b/pig/pig-pixbuf-picture.c
@@ -0,0 +1,520 @@
+/* Pig
+ * Copyright (C) 2011 Benjamin Otte <otte@gnome.org>
+ *
+ * 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 "pig-pixbuf-picture.h"
+
+#include <cairo-gobject.h>
+#include <glib/gi18n.h>
+
+struct _PigPixbufPicturePrivate {
+ GdkPixbuf *pixbuf;
+ cairo_surface_t *surface;
+ guint keep_pixbuf : 1;
+ guint keep_surface : 1;
+};
+
+G_DEFINE_TYPE (PigPixbufPicture, pig_pixbuf_picture, PIG_TYPE_PICTURE)
+
+enum {
+ PROP_0,
+ PROP_PIXBUF,
+ PROP_KEEP_PIXBUF,
+ PROP_KEEP_SURFACE
+};
+
+/**
+ * SECTION:pixbuf-picture
+ * @Short_description: Pictures for pixbufs
+ * @Title: PigPixbufPicture
+ * @See_also: #PigPicture
+ *
+ * A #PigPixbufPicture is an implementation of #PigPicture for a #GdkPixbuf.
+ * It is meant to help in the porting of applications from #GdkPixbuf use
+ * to #PigPicture use.
+ *
+ * You should try not to use it for newly written code.
+ */
+
+/**
+ * PigPixbufPicture:
+ *
+ * This object represents a pixbuf picture. All object members are private
+ * and must not be accessed.
+ */
+
+/**
+ * PigPixbufPictureClass:
+ *
+ * This object represents the class for a #PigPixbufPicture. All object
+ * members are private and must not be accessed.
+ */
+
+static void
+pig_pixbuf_picture_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PigPixbufPicture *picture = PIG_PIXBUF_PICTURE (object);
+ PigPixbufPicturePrivate *priv = picture->priv;
+
+ switch (prop_id)
+ {
+ case PROP_PIXBUF:
+ g_value_set_object (value, pig_pixbuf_picture_get_pixbuf (picture));
+ break;
+ case PROP_KEEP_PIXBUF:
+ g_value_set_boolean (value, priv->keep_pixbuf);
+ break;
+ case PROP_KEEP_SURFACE:
+ g_value_set_boolean (value, priv->keep_surface);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+pig_pixbuf_picture_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PigPixbufPicture *picture = PIG_PIXBUF_PICTURE (object);
+
+ switch (prop_id)
+ {
+ case PROP_PIXBUF:
+ pig_pixbuf_picture_set_pixbuf (picture, g_value_get_object (value));
+ break;
+ case PROP_KEEP_PIXBUF:
+ pig_pixbuf_picture_set_keep_pixbuf (picture, g_value_get_boolean (value));
+ break;
+ case PROP_KEEP_SURFACE:
+ pig_pixbuf_picture_set_keep_surface (picture, g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+pig_pixbuf_picture_dispose (GObject *object)
+{
+ PigPixbufPicture *picture = PIG_PIXBUF_PICTURE (object);
+
+ pig_pixbuf_picture_set_pixbuf (picture, NULL);
+
+ G_OBJECT_CLASS (pig_pixbuf_picture_parent_class)->dispose (object);
+}
+
+static cairo_surface_t *
+pig_pixbuf_picture_ref_surface (PigPicture *picture)
+{
+ PigPixbufPicture *pixbuf_picture = PIG_PIXBUF_PICTURE (picture);
+ PigPixbufPicturePrivate *priv = pixbuf_picture->priv;
+ cairo_surface_t *surface;
+
+ if (priv->surface)
+ return cairo_surface_reference (priv->surface);
+
+ if (priv->pixbuf)
+ surface = pig_pixbuf_create_surface (priv->pixbuf);
+ else
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
+
+ if (priv->keep_surface)
+ priv->surface = cairo_surface_reference (surface);
+
+ return surface;
+}
+
+static void
+pig_pixbuf_picture_class_init (PigPixbufPictureClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ PigPictureClass *picture_class = PIG_PICTURE_CLASS (klass);
+
+ object_class->get_property = pig_pixbuf_picture_get_property;
+ object_class->set_property = pig_pixbuf_picture_set_property;
+ object_class->dispose = pig_pixbuf_picture_dispose;
+
+ picture_class->ref_surface = pig_pixbuf_picture_ref_surface;
+
+ /**
+ * PigPixbufPicture:pixbuf:
+ *
+ * The pixbuf to be drawn or %NULL if none was set or PigPixbufPicture:keep-pixbuf
+ * is %FALSE.
+ *
+ * Since: 3.2
+ */
+ g_object_class_install_property (object_class,
+ PROP_PIXBUF,
+ g_param_spec_object ("pixbuf",
+ _("pixbuf"),
+ _("the pixbuf to display"),
+ GDK_TYPE_PIXBUF,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * PigPixbufPicture:keep-pixbuf:
+ *
+ * Whether to cache the pixbuf internally or to convert it into a #cairo_surface_t immediately.
+ *
+ * Since: 3.2
+ */
+ g_object_class_install_property (object_class,
+ PROP_KEEP_PIXBUF,
+ g_param_spec_boolean ("keep-pixbuf",
+ _("keep pixbuf"),
+ _("TRUE to keep the pixbuf around"),
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * PigPixbufPicture:keep-surface:
+ *
+ * Whether to keep the #cairo_surface_t internally that was created when drawing the picture.
+ *
+ * Since: 3.2
+ */
+ g_object_class_install_property (object_class,
+ PROP_KEEP_SURFACE,
+ g_param_spec_boolean ("keep-surface",
+ _("keep surface"),
+ _("TRUE to keep the surface around"),
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_type_class_add_private (klass, sizeof (PigPixbufPicturePrivate));
+}
+
+static void
+pig_pixbuf_picture_init (PigPixbufPicture *picture)
+{
+ PigPixbufPicturePrivate *priv;
+
+ picture->priv = G_TYPE_INSTANCE_GET_PRIVATE (picture,
+ PIG_TYPE_PIXBUF_PICTURE,
+ PigPixbufPicturePrivate);
+ priv = picture->priv;
+
+ priv->keep_pixbuf = TRUE;
+}
+
+/**
+ * pig_pixbuf_create_surface:
+ * @pixbuf: pixbuf to create the surface from
+ *
+ * Creates a #cairo_surface_t displaying the same image data as @pixbuf.
+ *
+ * Returns: A new #cairo_surface_t
+ **/
+cairo_surface_t *
+pig_pixbuf_create_surface (const GdkPixbuf *pixbuf)
+{
+ gint width, height;
+ guchar *gdk_pixels;
+ int gdk_rowstride, n_channels, cairo_stride;
+ guchar *cairo_pixels;
+ cairo_format_t format;
+ cairo_surface_t *surface;
+ static const cairo_user_data_key_t key;
+ int j;
+
+ g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ gdk_pixels = gdk_pixbuf_get_pixels (pixbuf);
+ gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+ n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+ if (n_channels == 3)
+ format = CAIRO_FORMAT_RGB24;
+ else
+ format = CAIRO_FORMAT_ARGB32;
+
+ cairo_stride = cairo_format_stride_for_width (format, width);
+ cairo_pixels = g_malloc (height * cairo_stride);
+ surface = cairo_image_surface_create_for_data ((unsigned char *)cairo_pixels,
+ format,
+ width, height, cairo_stride);
+
+ cairo_surface_set_user_data (surface, &key,
+ cairo_pixels, (cairo_destroy_func_t)g_free);
+
+ for (j = height; j; j--)
+ {
+ guchar *p = gdk_pixels;
+ guchar *q = cairo_pixels;
+
+ if (n_channels == 3)
+ {
+ guchar *end = p + 3 * width;
+
+ while (p < end)
+ {
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ q[0] = p[2];
+ q[1] = p[1];
+ q[2] = p[0];
+#else
+ q[1] = p[0];
+ q[2] = p[1];
+ q[3] = p[2];
+#endif
+ p += 3;
+ q += 4;
+ }
+ }
+ else
+ {
+ guchar *end = p + 4 * width;
+ guint t1,t2,t3;
+
+#define MULT(d,c,a,t) G_STMT_START { t = c * a + 0x7f; d = ((t >> 8) + t) >> 8; } G_STMT_END
+
+ while (p < end)
+ {
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ MULT(q[0], p[2], p[3], t1);
+ MULT(q[1], p[1], p[3], t2);
+ MULT(q[2], p[0], p[3], t3);
+ q[3] = p[3];
+#else
+ q[0] = p[3];
+ MULT(q[1], p[0], p[3], t1);
+ MULT(q[2], p[1], p[3], t2);
+ MULT(q[3], p[2], p[3], t3);
+#endif
+
+ p += 4;
+ q += 4;
+ }
+
+#undef MULT
+ }
+
+ gdk_pixels += gdk_rowstride;
+ cairo_pixels += cairo_stride;
+ }
+
+ return surface;
+}
+
+/**
+ * pig_pixbuf_picture_new:
+ * @pixbuf: the pixbuf to create the picture with or %NULL
+ *
+ * Creates a new #PigPixbufPicture displaying the given @pixbuf.
+ *
+ * Returns: a new picture
+ **/
+PigPicture *
+pig_pixbuf_picture_new (GdkPixbuf *pixbuf)
+{
+ g_return_val_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf), NULL);
+
+ return g_object_new (PIG_TYPE_PIXBUF_PICTURE, "pixbuf", pixbuf, NULL);
+}
+
+/**
+ * pig_pixbuf_picture_set_pixbuf:
+ * @picture: the picture to set the pixbuf for
+ * @pixbuf: the pixbuf to use or %NULL for none
+ *
+ * Sets the #GdkPixbuf to be displayed by @picture.
+ **/
+void
+pig_pixbuf_picture_set_pixbuf (PigPixbufPicture *picture,
+ GdkPixbuf * pixbuf)
+{
+ PigPixbufPicturePrivate *priv;
+
+ g_return_if_fail (PIG_IS_PIXBUF_PICTURE (picture));
+ g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
+
+ priv = picture->priv;
+
+ if (pixbuf)
+ g_object_ref (pixbuf);
+
+ if (priv->surface)
+ {
+ cairo_surface_destroy (priv->surface);
+ priv->surface = NULL;
+ }
+ if (priv->pixbuf)
+ {
+ g_object_unref (priv->pixbuf);
+ priv->pixbuf = NULL;
+ }
+
+ if (priv->keep_pixbuf)
+ {
+ priv->pixbuf = pixbuf;
+ }
+ else
+ {
+ if (pixbuf)
+ priv->surface = pig_pixbuf_create_surface (pixbuf);
+ }
+
+ g_object_notify (G_OBJECT (picture), "pixbuf");
+
+ if (pixbuf)
+ {
+ pig_picture_resized (PIG_PICTURE (picture),
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf));
+ }
+ else
+ pig_picture_resized (PIG_PICTURE (picture), 0, 0);
+}
+
+/**
+ * pig_pixbuf_picture_get_pixbuf:
+ * @picture: the picture to query
+ *
+ * Queries @picture for the #GdkPixbuf that is currently displayed.
+ * If GdkPixbufPicture:keep-pixbuf is %FALSE, %NULL will always
+ * be returned.
+ *
+ * Returns: the #GdkPixbuf currently displayed by @picture or %NULL.
+ **/
+GdkPixbuf *
+pig_pixbuf_picture_get_pixbuf (PigPixbufPicture *picture)
+{
+ g_return_val_if_fail (PIG_IS_PIXBUF_PICTURE (picture), NULL);
+
+ return picture->priv->pixbuf;
+}
+
+/**
+ * pig_pixbuf_picture_set_keep_pixbuf:
+ * @picture: the picture
+ * @keep_pixbuf: %TRUE to keep the pixbuf around
+ *
+ * Utility function to set the caching behavior of @picture. If
+ * @keep_pixbuf is set to %FALSE, the #GdkPixbuf set with
+ * pig_pixbuf_picture_set_pixbuf() will be converted to a
+ * #cairo_surface_t immediately and not be kept around. If set to
+ * %FALSE, pig_pixbuf_picture_get_pixbuf() will always return %NULL.
+ *
+ * <note><para>This function clears any pixbuf previously set with
+ * pig_pixbuf_picture_set_pixbuf(). You likely only want to call
+ * it when initializing the @picture.</para></note>
+ **/
+void
+pig_pixbuf_picture_set_keep_pixbuf (PigPixbufPicture *picture,
+ gboolean keep_pixbuf)
+{
+ PigPixbufPicturePrivate *priv;
+
+ g_return_if_fail (PIG_IS_PIXBUF_PICTURE (picture));
+
+ pig_pixbuf_picture_set_pixbuf (picture, NULL);
+
+ priv = picture->priv;
+
+ if (priv->keep_pixbuf == keep_pixbuf)
+ return;
+
+ priv->keep_pixbuf = keep_pixbuf;
+ if (!keep_pixbuf)
+ pig_pixbuf_picture_set_keep_surface (picture, TRUE);
+
+ g_object_notify (G_OBJECT (picture), "keep-pixbuf");
+}
+
+/**
+ * pig_pixbuf_picture_get_keep_pixbuf:
+ * @picture: the picture to query
+ *
+ * Queries if the @picture keeps the pixbuf around. By default, the
+ * value is %TRUE. For details, see pig_pixbuf_picture_set_keep_pixbuf().
+ *
+ * Returns: %TRUE if the @picture keeps its pixbuf around
+ **/
+gboolean
+pig_pixbuf_picture_get_keep_pixbuf (PigPixbufPicture *picture)
+{
+ g_return_val_if_fail (PIG_IS_PIXBUF_PICTURE (picture), FALSE);
+
+ return picture->priv->keep_pixbuf;
+}
+
+/**
+ * pig_pixbuf_picture_set_keep_surface:
+ * @picture: the picture
+ * @keep_surface: %TRUE to keep the surface around
+ *
+ * Sets the caching behavior of @picture. If set to %TRUE, a
+ * #cairo_surface_t representing the contents of @picture will be
+ * cached instead of converting it from a pixbuf on-demand. This
+ * increases memory use but improves performance.
+ *
+ * <note><para>This function clears any pixbuf previously set with
+ * pig_pixbuf_picture_set_pixbuf(). You likely only want to call
+ * it when initializing the @picture.</para></note>
+ **/
+void
+pig_pixbuf_picture_set_keep_surface (PigPixbufPicture *picture,
+ gboolean keep_surface)
+{
+ PigPixbufPicturePrivate *priv;
+
+ g_return_if_fail (PIG_IS_PIXBUF_PICTURE (picture));
+
+ priv = picture->priv;
+
+ pig_pixbuf_picture_set_pixbuf (picture, NULL);
+
+ if (priv->keep_surface == keep_surface)
+ return;
+
+ priv->keep_surface = keep_surface;
+ if (!keep_surface)
+ pig_pixbuf_picture_set_keep_pixbuf (picture, TRUE);
+
+ g_object_notify (G_OBJECT (picture), "keep-surface");
+}
+
+/**
+ * pig_pixbuf_picture_get_keep_surface:
+ * @picture: the picture to query
+ *
+ * Queries if the @picture keeps a surface cache. By default, the
+ * value is %FALSE. For details, see pig_pixbuf_picture_set_keep_surface().
+ *
+ * Returns: %TRUE if a #cairo_surface_t is cached internally.
+ **/
+gboolean
+pig_pixbuf_picture_get_keep_surface (PigPixbufPicture *picture)
+{
+ g_return_val_if_fail (PIG_IS_PIXBUF_PICTURE (picture), FALSE);
+
+ return picture->priv->keep_surface;
+}
+
diff --git a/pig/pig-pixbuf-picture.h b/pig/pig-pixbuf-picture.h
new file mode 100644
index 0000000..7d45937
--- /dev/null
+++ b/pig/pig-pixbuf-picture.h
@@ -0,0 +1,76 @@
+/* Pig
+ * Copyright (C) 2011 Benjamin Otte <otte@gnome.org>
+ *
+ * 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.
+ */
+
+#if !defined (__PIG_PIXBUF_H_INSIDE__) && !defined (PIG_PIXBUF_COMPILATION)
+#error "Only <pig/pig-pixbuf.h> can be included directly."
+#endif
+
+#ifndef __PIG_PIXBUF_PICTURE_H__
+#define __PIG_PIXBUF_PICTURE_H__
+
+#include <pig/pig.h>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+
+G_BEGIN_DECLS
+
+#define PIG_TYPE_PIXBUF_PICTURE (pig_pixbuf_picture_get_type ())
+#define PIG_PIXBUF_PICTURE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PIG_TYPE_PIXBUF_PICTURE, PigPixbufPicture))
+#define PIG_PIXBUF_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PIG_TYPE_PIXBUF_PICTURE, PigPixbufPictureClass))
+#define PIG_IS_PIXBUF_PICTURE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PIG_TYPE_PIXBUF_PICTURE))
+#define PIG_IS_PIXBUF_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIG_TYPE_PIXBUF_PICTURE))
+#define PIG_PIXBUF_PICTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PIG_TYPE_PIXBUF_PICTURE, PigPixbufPictureClass))
+
+typedef struct _PigPixbufPicture PigPixbufPicture;
+typedef struct _PigPixbufPicturePrivate PigPixbufPicturePrivate;
+typedef struct _PigPixbufPictureClass PigPixbufPictureClass;
+
+struct _PigPixbufPicture {
+ /*< private >*/
+ PigPicture parent_picture;
+
+ PigPixbufPicturePrivate *priv;
+};
+
+struct _PigPixbufPictureClass {
+ /*< private >*/
+ PigPictureClass parent_class;
+};
+
+GType pig_pixbuf_picture_get_type (void);
+
+PigPicture * pig_pixbuf_picture_new (GdkPixbuf *pixbuf);
+
+void pig_pixbuf_picture_set_pixbuf (PigPixbufPicture *picture,
+ GdkPixbuf * pixbuf);
+GdkPixbuf * pig_pixbuf_picture_get_pixbuf (PigPixbufPicture *picture);
+void pig_pixbuf_picture_set_keep_pixbuf (PigPixbufPicture *picture,
+ gboolean keep_pixbuf);
+gboolean pig_pixbuf_picture_get_keep_pixbuf (PigPixbufPicture *picture);
+void pig_pixbuf_picture_set_keep_surface (PigPixbufPicture *picture,
+ gboolean keep_surface);
+gboolean pig_pixbuf_picture_get_keep_surface (PigPixbufPicture *picture);
+
+
+cairo_surface_t * pig_pixbuf_create_surface (const GdkPixbuf * pixbuf);
+
+G_END_DECLS
+
+#endif /* __PIG_PIXBUF_PICTURE_H__ */
diff --git a/pig/pig-pixbuf.h b/pig/pig-pixbuf.h
new file mode 100644
index 0000000..9a1dd1f
--- /dev/null
+++ b/pig/pig-pixbuf.h
@@ -0,0 +1,40 @@
+/* Pig
+ * Copyright (C) 2011 Benjamin Otte <otte@gnome.org>
+ *
+ * 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 __PIG_PIXBUF_H__
+#define __PIG_PIXBUF_H__
+
+/* This check only exists to make sure people don't include this file
+ * without checking for pig-pixbuf.pc in configure */
+#if !defined (PIG_PIXBUF_ENABLED)
+#error "You cannot include <pig/pig-pixbuf.h> without checking for pig-pixbuf."
+#endif
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <pig.h>
+
+#define __PIG_PIXBUF_H_INSIDE__
+
+
+#include <pig-pixbuf-picture.h>
+
+
+#undef __PIG_PIXBUF_H_INSIDE__
+
+#endif /* __PIG_PIXBUF_H__ */