diff options
author | Benjamin Otte <otte@redhat.com> | 2011-10-16 12:35:52 -0700 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2011-10-16 22:32:55 -0700 |
commit | 0218e8c635affca4a299cc47b03459688aba2bcf (patch) | |
tree | 8b9b8611864ec8c8299f16d1ad5bbdc374483770 | |
parent | 0871f62b1fc0276e6f40a3273f08e82fbc23b85a (diff) |
resource: Add resources for images
-rw-r--r-- | libgame/Makefile.am | 2 | ||||
-rw-r--r-- | libgame/game-image-resource.c | 269 | ||||
-rw-r--r-- | libgame/game-image-resource.h | 63 | ||||
-rw-r--r-- | libgame/libgame.h | 1 |
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> |