diff options
author | Benjamin Otte <otte@redhat.com> | 2011-02-03 18:24:56 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2011-02-14 19:32:59 +0100 |
commit | e56f0136984e46e77a07c1213a2e6d25301107f5 (patch) | |
tree | 84b0c0a9c196f670aa6f9a82ca6e68cb11109630 | |
parent | ad7ab0f781651c1f9d566ad1908df07a2da77aa4 (diff) | |
download | gtk+-e56f0136984e46e77a07c1213a2e6d25301107f5.tar.gz |
gdk: Add GdkPixbufPicture
This allows an easy transition from pixbufs to pictures.
I probably went a bit overboard with the keep-pixbuf and keep-surface
settings, but oh well...
xxx: pixbufpicture
-rw-r--r-- | gdk/Makefile.am | 2 | ||||
-rw-r--r-- | gdk/gdk.h | 1 | ||||
-rw-r--r-- | gdk/gdkpixbufpicture.c | 363 | ||||
-rw-r--r-- | gdk/gdkpixbufpicture.h | 71 |
4 files changed, 437 insertions, 0 deletions
diff --git a/gdk/Makefile.am b/gdk/Makefile.am index 96b6b0e86a..36b56c0cf8 100644 --- a/gdk/Makefile.am +++ b/gdk/Makefile.am @@ -81,6 +81,7 @@ gdk_public_h_sources = \ gdkpango.h \ gdkpicture.h \ gdkpixbuf.h \ + gdkpixbufpicture.h \ gdkprivate.h \ gdkproperty.h \ gdkrectangle.h \ @@ -131,6 +132,7 @@ gdk_c_sources = \ gdkpango.c \ gdkpicture.c \ gdkpixbuf-drawable.c \ + gdkpixbufpicture.c \ gdkrectangle.c \ gdkrgba.c \ gdkscreen.c \ @@ -47,6 +47,7 @@ #include <gdk/gdkpango.h> #include <gdk/gdkpicture.h> #include <gdk/gdkpixbuf.h> +#include <gdk/gdkpixbufpicture.h> #include <gdk/gdkproperty.h> #include <gdk/gdkrectangle.h> #include <gdk/gdkrgba.h> diff --git a/gdk/gdkpixbufpicture.c b/gdk/gdkpixbufpicture.c new file mode 100644 index 0000000000..6e18050173 --- /dev/null +++ b/gdk/gdkpixbufpicture.c @@ -0,0 +1,363 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2010 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 "gdkpixbufpicture.h" + +#include <cairo-gobject.h> + +#include "gdkintl.h" +#include "gdkinternals.h" + +struct _GdkPixbufPicturePrivate { + GdkPixbuf *pixbuf; + cairo_surface_t *surface; + guint keep_pixbuf : 1; + guint keep_surface : 1; +}; + +G_DEFINE_TYPE (GdkPixbufPicture, gdk_pixbuf_picture, GDK_TYPE_PICTURE) + +enum { + PROP_0, + PROP_PIXBUF, + PROP_KEEP_PIXBUF, + PROP_KEEP_SURFACE +}; + +/** + * SECTION:gdkpixbufpicture + * @Short_description: Pictures for pixbufs + * @Title: GdkPixbufPicture + * @See_also: #GdkPicture + * + * A #GdkPixbufPicture is an implementation of #GdkPicture for a #GdkPixbuf. + * It is meant to help in the porting of applications from #GdkPixbuf use + * to #GdkPicture use. + * + * You should try not to use it for newly written code. + */ + +static void +gdk_pixbuf_picture_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdkPixbufPicture *picture = GDK_PIXBUF_PICTURE (object); + GdkPixbufPicturePrivate *priv = picture->priv; + + switch (prop_id) + { + case PROP_PIXBUF: + g_value_set_object (value, gdk_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 +gdk_pixbuf_picture_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdkPixbufPicture *picture = GDK_PIXBUF_PICTURE (object); + + switch (prop_id) + { + case PROP_PIXBUF: + gdk_pixbuf_picture_set_pixbuf (picture, g_value_get_object (value)); + break; + case PROP_KEEP_PIXBUF: + gdk_pixbuf_picture_set_keep_pixbuf (picture, g_value_get_boolean (value)); + break; + case PROP_KEEP_SURFACE: + gdk_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 +gdk_pixbuf_picture_dispose (GObject *object) +{ + GdkPixbufPicture *picture = GDK_PIXBUF_PICTURE (object); + + gdk_pixbuf_picture_set_pixbuf (picture, NULL); + + G_OBJECT_CLASS (gdk_pixbuf_picture_parent_class)->dispose (object); +} + +static cairo_surface_t * +gdk_pixbuf_picture_ref_surface (GdkPicture *picture) +{ + GdkPixbufPicture *pixbuf_picture = GDK_PIXBUF_PICTURE (picture); + GdkPixbufPicturePrivate *priv = pixbuf_picture->priv; + cairo_surface_t *surface; + + if (priv->surface) + return cairo_surface_reference (priv->surface); + + if (priv->pixbuf) + surface = _gdk_cairo_create_surface_for_pixbuf (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 +gdk_pixbuf_picture_class_init (GdkPixbufPictureClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdkPictureClass *picture_class = GDK_PICTURE_CLASS (klass); + + object_class->get_property = gdk_pixbuf_picture_get_property; + object_class->set_property = gdk_pixbuf_picture_set_property; + object_class->dispose = gdk_pixbuf_picture_dispose; + + picture_class->ref_surface = gdk_pixbuf_picture_ref_surface; + + /** + * GdkPixbufPicture:pixbuf: + * + * The pixbuf to be drawn or %NULL if none was set or GdkPixbufPicture:keep-pixbuf + * is %FALSE. + * + * Since: 3.2 + */ + g_object_class_install_property (object_class, + PROP_PIXBUF, + g_param_spec_object ("pixbuf", + P_("pixbuf"), + P_("the pixbuf to display"), + GDK_TYPE_PIXBUF, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GdkPixbufPicture: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", + P_("keep pixbuf"), + P_("TRUE to keep the pixbuf around"), + TRUE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GdkPixbufPicture: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", + P_("keep surface"), + P_("TRUE to keep the surface around"), + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_type_class_add_private (klass, sizeof (GdkPixbufPicturePrivate)); +} + +static void +gdk_pixbuf_picture_init (GdkPixbufPicture *picture) +{ + GdkPixbufPicturePrivate *priv; + + picture->priv = G_TYPE_INSTANCE_GET_PRIVATE (picture, + GDK_TYPE_PIXBUF_PICTURE, + GdkPixbufPicturePrivate); + priv = picture->priv; + + priv->keep_pixbuf = TRUE; +} + +/** + * gdk_pixbuf_picture_new: + * @pixbuf: the pixbuf to create the picture with or %NULL + * + * Creates a new #GdkPixbufPicture displaying the given @pixbuf. + * + * Returns: a new picture + **/ +GdkPicture * +gdk_pixbuf_picture_new (GdkPixbuf *pixbuf) +{ + g_return_val_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf), NULL); + + return g_object_new (GDK_TYPE_PIXBUF_PICTURE, "pixbuf", pixbuf, NULL); +} + +void +gdk_pixbuf_picture_set_pixbuf (GdkPixbufPicture *picture, + GdkPixbuf * pixbuf) +{ + GdkPixbufPicturePrivate *priv; + + g_return_if_fail (GDK_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 = _gdk_cairo_create_surface_for_pixbuf (pixbuf); + } + + g_object_notify (G_OBJECT (picture), "pixbuf"); + + if (pixbuf) + { + gdk_picture_resized (GDK_PICTURE (picture), + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf)); + } + else + gdk_picture_resized (GDK_PICTURE (picture), 0, 0); +} + +GdkPixbuf * +gdk_pixbuf_picture_get_pixbuf (GdkPixbufPicture *picture) +{ + g_return_val_if_fail (GDK_IS_PIXBUF_PICTURE (picture), NULL); + + return picture->priv->pixbuf; +} + +void +gdk_pixbuf_picture_set_keep_pixbuf (GdkPixbufPicture *picture, + gboolean keep_pixbuf) +{ + GdkPixbufPicturePrivate *priv; + + g_return_if_fail (GDK_IS_PIXBUF_PICTURE (picture)); + + priv = picture->priv; + + if (priv->keep_pixbuf == keep_pixbuf) + return; + + priv->keep_pixbuf = keep_pixbuf; + if (keep_pixbuf) + { + /* This is equal to setting the pixbuf to NULL because + * there's no pixbuf we could keep now. */ + gdk_pixbuf_picture_set_pixbuf (picture, NULL); + } + else + { + gdk_pixbuf_picture_set_keep_surface (picture, TRUE); + + if (priv->pixbuf) + { + priv->surface = _gdk_cairo_create_surface_for_pixbuf (priv->pixbuf); + g_object_unref (priv->pixbuf); + priv->pixbuf = NULL; + } + } + + g_object_notify (G_OBJECT (picture), "keep-pixbuf"); +} + +gboolean +gdk_pixbuf_picture_get_keep_pixbuf (GdkPixbufPicture *picture) +{ + g_return_val_if_fail (GDK_IS_PIXBUF_PICTURE (picture), FALSE); + + return picture->priv->keep_pixbuf; +} + +void +gdk_pixbuf_picture_set_keep_surface (GdkPixbufPicture *picture, + gboolean keep_surface) +{ + GdkPixbufPicturePrivate *priv; + + g_return_if_fail (GDK_IS_PIXBUF_PICTURE (picture)); + + priv = picture->priv; + + if (priv->keep_surface == keep_surface) + return; + + priv->keep_surface = keep_surface; + if (!keep_surface) + { + if (priv->surface) + { + cairo_surface_destroy (priv->surface); + priv->surface = NULL; + } + + gdk_pixbuf_picture_set_keep_pixbuf (picture, TRUE); + } + + g_object_notify (G_OBJECT (picture), "keep-surface"); +} + +gboolean +gdk_pixbuf_picture_get_keep_surface (GdkPixbufPicture *picture) +{ + g_return_val_if_fail (GDK_IS_PIXBUF_PICTURE (picture), FALSE); + + return picture->priv->keep_surface; +} + diff --git a/gdk/gdkpixbufpicture.h b/gdk/gdkpixbufpicture.h new file mode 100644 index 0000000000..b8aa71e2d4 --- /dev/null +++ b/gdk/gdkpixbufpicture.h @@ -0,0 +1,71 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2010 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 (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION) +#error "Only <gdk/gdk.h> can be included directly." +#endif + +#ifndef __GDK_PIXBUF_PICTURE_H__ +#define __GDK_PIXBUF_PICTURE_H__ + +#include <gdk/gdkpicture.h> + +#include <gdk-pixbuf/gdk-pixbuf.h> + + +G_BEGIN_DECLS + +#define GDK_TYPE_PIXBUF_PICTURE (gdk_pixbuf_picture_get_type ()) +#define GDK_PIXBUF_PICTURE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_PIXBUF_PICTURE, GdkPixbufPicture)) +#define GDK_PIXBUF_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_PICTURE, GdkPixbufPictureClass)) +#define GDK_IS_PIXBUF_PICTURE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_PICTURE)) +#define GDK_IS_PIXBUF_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_PICTURE)) +#define GDK_PIXBUF_PICTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_PICTURE, GdkPixbufPictureClass)) + +typedef struct _GdkPixbufPicture GdkPixbufPicture; +typedef struct _GdkPixbufPicturePrivate GdkPixbufPicturePrivate; +typedef struct _GdkPixbufPictureClass GdkPixbufPictureClass; + +struct _GdkPixbufPicture { + GdkPicture parent_picture; + + GdkPixbufPicturePrivate *priv; +}; + +struct _GdkPixbufPictureClass { + GdkPictureClass parent_class; +}; + +GType gdk_pixbuf_picture_get_type (void); + +GdkPicture * gdk_pixbuf_picture_new (GdkPixbuf *pixbuf); + +void gdk_pixbuf_picture_set_pixbuf (GdkPixbufPicture *picture, + GdkPixbuf * pixbuf); +GdkPixbuf * gdk_pixbuf_picture_get_pixbuf (GdkPixbufPicture *picture); +void gdk_pixbuf_picture_set_keep_pixbuf (GdkPixbufPicture *picture, + gboolean keep_pixbuf); +gboolean gdk_pixbuf_picture_get_keep_pixbuf (GdkPixbufPicture *picture); +void gdk_pixbuf_picture_set_keep_surface (GdkPixbufPicture *picture, + gboolean keep_surface); +gboolean gdk_pixbuf_picture_get_keep_surface (GdkPixbufPicture *picture); + +G_END_DECLS + +#endif /* __GDK_PIXBUF_PICTURE_H__ */ |