summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2011-10-16 12:35:52 -0700
committerBenjamin Otte <otte@redhat.com>2011-10-16 22:32:55 -0700
commit0218e8c635affca4a299cc47b03459688aba2bcf (patch)
tree8b9b8611864ec8c8299f16d1ad5bbdc374483770
parent0871f62b1fc0276e6f40a3273f08e82fbc23b85a (diff)
resource: Add resources for images
-rw-r--r--libgame/Makefile.am2
-rw-r--r--libgame/game-image-resource.c269
-rw-r--r--libgame/game-image-resource.h63
-rw-r--r--libgame/libgame.h1
4 files changed, 335 insertions, 0 deletions
diff --git a/libgame/Makefile.am b/libgame/Makefile.am
index fe88c51..81ccf42 100644
--- a/libgame/Makefile.am
+++ b/libgame/Makefile.am
@@ -31,6 +31,7 @@ libgame_@LIBGAME_VERS@_la_SOURCES = \
game-grid-actor.c \
game-highscore.c \
game-image.c \
+ game-image-resource.c \
game-info.c \
game-marshal.c \
game-match.c \
@@ -70,6 +71,7 @@ basic_headers = \
game-grid-actor.h \
game-highscore.h \
game-image.h \
+ game-image-resource.h \
game-info.h \
game-match.h \
game-network.h \
diff --git a/libgame/game-image-resource.c b/libgame/game-image-resource.c
new file mode 100644
index 0000000..6c00351
--- /dev/null
+++ b/libgame/game-image-resource.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2011 Benjamin Otte <otte@gnome.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "game-private.h"
+
+#include "game-image-resource.h"
+
+#include <cairo-gobject.h>
+
+#include "game-image.h"
+
+
+enum {
+ PROP_0,
+ PROP_DATA,
+ PROP_SIZE,
+ PROP_SURFACE
+};
+
+G_DEFINE_TYPE (GameImageResource, game_image_resource, GAME_TYPE_DATA_RESOURCE)
+
+static const GameRectangle game_image_resource_default_size = { 0, 0, 1, 1 };
+
+static void
+game_image_resource_get_property (GObject *object, guint param_id, GValue *value,
+ GParamSpec * pspec)
+{
+ GameImageResource *resource = GAME_IMAGE_RESOURCE (object);
+
+ switch (param_id) {
+ case PROP_DATA:
+ g_value_set_object (value, resource->data);
+ break;
+ case PROP_SIZE:
+ g_value_set_boxed (value, &resource->size);
+ break;
+ case PROP_SURFACE:
+ g_value_set_boxed (value, resource->surface);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+game_image_resource_set_property (GObject *object, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ GameImageResource *resource = GAME_IMAGE_RESOURCE (object);
+
+ switch (param_id) {
+ case PROP_DATA:
+ game_image_resource_set_data (resource, g_value_get_object (value));
+ break;
+ case PROP_SIZE:
+ game_image_resource_set_size (resource, g_value_get_boxed (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+game_image_resource_dispose (GObject *object)
+{
+ GameImageResource *resource = GAME_IMAGE_RESOURCE (object);
+
+ game_image_resource_set_data (resource, NULL);
+
+ G_OBJECT_CLASS (game_image_resource_parent_class)->dispose (object);
+}
+
+static gboolean
+game_image_resource_load (GameResource *res, GVariantIter *iter)
+{
+ GameImageResource *resource = GAME_IMAGE_RESOURCE (res);
+ GameDataResource *data;
+ GVariant *variant;
+
+ if (!GAME_RESOURCE_CLASS (game_image_resource_parent_class)->load (res, iter))
+ return FALSE;
+
+ if (!g_variant_iter_next (iter, "d", &resource->size.x1) ||
+ !g_variant_iter_next (iter, "d", &resource->size.y1) ||
+ !g_variant_iter_next (iter, "d", &resource->size.x2) ||
+ !g_variant_iter_next (iter, "d", &resource->size.y2) ||
+ !g_variant_iter_next (iter, "v", &variant))
+ return FALSE;
+
+ resource->size.x2 += resource->size.x1;
+ resource->size.y2 += resource->size.y1;
+
+ data = GAME_DATA_RESOURCE (game_resource_load (GAME_OBJECT (resource)->game, variant));
+ game_image_resource_set_data (resource, data);
+ g_object_unref (data);
+ g_variant_unref (variant);
+
+ return TRUE;
+}
+
+static void
+game_image_resource_save (GameResource *res, GVariantBuilder *builder)
+{
+ GameImageResource *resource = GAME_IMAGE_RESOURCE (res);
+ GVariant *variant;
+
+ GAME_RESOURCE_CLASS (game_image_resource_parent_class)->save (res, builder);
+
+ variant = game_resource_save (GAME_RESOURCE (resource->data));
+ g_variant_builder_add (builder, "ddddv",
+ resource->size.x1,
+ resource->size.y1,
+ resource->size.x2 - resource->size.x1,
+ resource->size.y2 - resource->size.y1,
+ variant);
+ g_variant_unref (variant);
+}
+
+static GameObject *
+game_image_resource_spawn (GameResource *res)
+{
+ GameImageResource *resource = GAME_IMAGE_RESOURCE (res);
+
+ return game_game_add_object (GAME_OBJECT (resource)->game,
+ GAME_TYPE_IMAGE,
+ "x", resource->size.x1,
+ "y", resource->size.y1,
+ "width", resource->size.x2 - resource->size.x1,
+ "height", resource->size.y2 - resource->size.y1,
+ "surface", resource->surface,
+ NULL);
+}
+
+static void
+game_image_resource_class_init (GameImageResourceClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GameResourceClass *resource_class = GAME_RESOURCE_CLASS (klass);
+
+ object_class->set_property = game_image_resource_set_property;
+ object_class->get_property = game_image_resource_get_property;
+ object_class->dispose = game_image_resource_dispose;
+
+ g_object_class_install_property (object_class, PROP_DATA,
+ g_param_spec_object ("data", _("data"), _("resource providing image data"),
+ GAME_TYPE_DATA_RESOURCE, G_PARAM_READWRITE));
+ g_object_class_install_property (object_class, PROP_SURFACE,
+ g_param_spec_boxed ("surface", _("surface"), _("surface created from image data"),
+ CAIRO_GOBJECT_TYPE_SURFACE, G_PARAM_READABLE));
+ g_object_class_install_property (object_class, PROP_SIZE,
+ g_param_spec_boxed ("sizee", _("size"), _("size the surface should be scaled to"),
+ GAME_TYPE_RECTANGLE, G_PARAM_READWRITE));
+
+ resource_class->load = game_image_resource_load;
+ resource_class->save = game_image_resource_save;
+ resource_class->spawn = game_image_resource_spawn;
+}
+
+static void
+game_image_resource_init (GameImageResource *resource)
+{
+ resource->size = game_image_resource_default_size;
+}
+
+cairo_surface_t *
+game_image_resource_get_surface (GameImageResource *resource)
+{
+ g_return_val_if_fail (GAME_IS_IMAGE_RESOURCE (resource), NULL);
+
+ return resource->surface;
+}
+
+GameDataResource *
+game_image_resource_get_data (GameImageResource *resource)
+{
+ g_return_val_if_fail (GAME_IS_IMAGE_RESOURCE (resource), NULL);
+
+ return resource->data;
+}
+
+cairo_surface_t *
+game_image_resource_load_surface (GameDataResource *data)
+{
+ GdkPixbufLoader *loader;
+ cairo_surface_t *surface;
+ GError *error = NULL;
+
+ loader = gdk_pixbuf_loader_new ();
+ if (!gdk_pixbuf_loader_write (loader,
+ game_data_resource_get_data (data),
+ game_data_resource_get_size (data),
+ &error) ||
+ !gdk_pixbuf_loader_close (loader, &error))
+ {
+ g_warning ("Could not load image: %s", error->message);
+ g_error_free (error);
+ return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
+ }
+
+ surface = game_cairo_surface_from_pixbuf (gdk_pixbuf_loader_get_pixbuf (loader));
+ g_object_unref (loader);
+
+ return surface;
+}
+
+void
+game_image_resource_set_data (GameImageResource *resource,
+ GameDataResource *data)
+{
+ g_return_if_fail (GAME_IS_IMAGE_RESOURCE (resource));
+ g_return_if_fail (data == NULL || GAME_IS_DATA_RESOURCE (data));
+
+ if (resource->data)
+ {
+ g_object_unref (resource->data);
+ resource->data = NULL;
+ cairo_surface_destroy (resource->surface);
+ resource->surface = NULL;
+ }
+
+ if (data)
+ {
+ resource->data = g_object_ref (data);
+ resource->surface = game_image_resource_load_surface (resource->data);
+ }
+
+ g_object_notify (G_OBJECT (resource), "data");
+ g_object_notify (G_OBJECT (resource), "surface");
+}
+
+const GameRectangle *
+game_image_resource_get_size (GameImageResource *resource)
+{
+ g_return_val_if_fail (GAME_IS_IMAGE_RESOURCE (resource), NULL);
+
+ return &resource->size;
+}
+
+void
+game_image_resource_set_size (GameImageResource * resource,
+ const GameRectangle *rect)
+{
+ g_return_if_fail (GAME_IS_IMAGE_RESOURCE (resource));
+
+ if (rect == NULL)
+ rect = &game_image_resource_default_size;
+
+ resource->size = *rect;
+
+ g_object_notify (G_OBJECT (resource), "size");
+}
+
diff --git a/libgame/game-image-resource.h b/libgame/game-image-resource.h
new file mode 100644
index 0000000..9d6d162
--- /dev/null
+++ b/libgame/game-image-resource.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 Benjamin Otte <otte@gnome.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAME_IMAGE_RESOURCE_H__
+#define __GAME_IMAGE_RESOURCE_H__
+
+#include <cairo.h>
+#include <libgame/game-data-resource.h>
+#include <libgame/game-geom-basics.h>
+
+G_BEGIN_DECLS
+
+#define GAME_TYPE_IMAGE_RESOURCE (game_image_resource_get_type ())
+#define GAME_IMAGE_RESOURCE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GAME_TYPE_IMAGE_RESOURCE, GameImageResource))
+#define GAME_IMAGE_RESOURCE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GAME_TYPE_IMAGE_RESOURCE, GameImageResourceClass))
+#define GAME_IS_IMAGE_RESOURCE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GAME_TYPE_IMAGE_RESOURCE))
+#define GAME_IS_IMAGE_RESOURCE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GAME_TYPE_IMAGE_RESOURCE))
+#define GAME_IMAGE_RESOURCE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GAME_TYPE_IMAGE_RESOURCE, GameImageResourceClass))
+
+typedef struct _GameImageResource GameImageResource;
+typedef struct _GameImageResourceClass GameImageResourceClass;
+
+struct _GameImageResource {
+ GameResource resource;
+
+ /*< private >*/
+ GameDataResource * data;
+ cairo_surface_t * surface;
+ GameRectangle size;
+};
+
+struct _GameImageResourceClass {
+ GameResourceClass resource_class;
+};
+
+GType game_image_resource_get_type (void) G_GNUC_CONST;
+
+GameDataResource * game_image_resource_get_data (GameImageResource * resource);
+void game_image_resource_set_data (GameImageResource * resource,
+ GameDataResource * data);
+cairo_surface_t * game_image_resource_get_surface (GameImageResource * resource);
+const GameRectangle * game_image_resource_get_size (GameImageResource * resource);
+void game_image_resource_set_size (GameImageResource * resource,
+ const GameRectangle * rect);
+
+G_END_DECLS
+
+#endif /* __GAME_IMAGE_RESOURCE_H__ */
diff --git a/libgame/libgame.h b/libgame/libgame.h
index 6e4ba66..0aa68c2 100644
--- a/libgame/libgame.h
+++ b/libgame/libgame.h
@@ -38,6 +38,7 @@
#include <libgame/game-grid-actor.h>
#include <libgame/game-highscore.h>
#include <libgame/game-image.h>
+#include <libgame/game-image-resource.h>
#include <libgame/game-info.h>
#include <libgame/game-network.h>
#include <libgame/game-network-player.h>