[libshumate] vector: Add sprite and fill-pattern support
- From: Corentin Noël <corentinnoel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libshumate] vector: Add sprite and fill-pattern support
- Date: Tue, 2 Aug 2022 10:15:53 +0000 (UTC)
commit 645f061963d1ec0da9353aa383344a42393146b0
Author: James Westman <james jwestman net>
Date: Tue Jun 7 22:09:09 2022 -0500
vector: Add sprite and fill-pattern support
demos/map-style.json | 9 +
demos/org.gnome.Shumate.Demo.gresources.xml | 2 +
demos/shumate-demo-window.c | 17 ++
demos/sprites.json | 9 +
demos/sprites.svg | 57 +++++
shumate/meson.build | 2 +
shumate/shumate-vector-renderer.c | 44 ++++
shumate/shumate-vector-renderer.h | 4 +
shumate/vector/shumate-vector-fill-layer.c | 35 ++-
.../vector/shumate-vector-render-scope-private.h | 3 +
.../vector/shumate-vector-sprite-sheet-private.h | 35 +++
shumate/vector/shumate-vector-sprite-sheet.c | 237 +++++++++++++++++++++
12 files changed, 452 insertions(+), 2 deletions(-)
---
diff --git a/demos/map-style.json b/demos/map-style.json
index 3fed433..f620544 100644
--- a/demos/map-style.json
+++ b/demos/map-style.json
@@ -32,6 +32,15 @@
}
}
},
+ {
+ "id": "water-pattern",
+ "type": "fill",
+ "source-layer": "water",
+ "paint": {
+ "fill-pattern": "ocean",
+ "fill-opacity": 0.1
+ }
+ },
{
"id": "country_boundary",
"type": "line",
diff --git a/demos/org.gnome.Shumate.Demo.gresources.xml b/demos/org.gnome.Shumate.Demo.gresources.xml
index 1ebd6cf..d839b5b 100644
--- a/demos/org.gnome.Shumate.Demo.gresources.xml
+++ b/demos/org.gnome.Shumate.Demo.gresources.xml
@@ -8,5 +8,7 @@
</gresource>
<gresource prefix="/org/gnome/Shumate/Demo/styles">
<file preprocess="json-stripblanks">map-style.json</file>
+ <file preprocess="json-stripblanks">sprites.json</file>
+ <file>sprites.svg</file>
</gresource>
</gresources>
diff --git a/demos/shumate-demo-window.c b/demos/shumate-demo-window.c
index 1b1feaf..4067fb1 100644
--- a/demos/shumate-demo-window.c
+++ b/demos/shumate-demo-window.c
@@ -162,6 +162,23 @@ shumate_demo_window_init (ShumateDemoWindow *self)
}
else
{
+ g_autoptr(GdkPixbuf) sprites_pixbuf = NULL;
+ g_autoptr(GBytes) sprites_json = NULL;
+
+ sprites_json = g_resources_lookup_data ("/org/gnome/Shumate/Demo/styles/sprites.json",
G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
+ sprites_pixbuf = gdk_pixbuf_new_from_resource ("/org/gnome/Shumate/Demo/styles/sprites.svg", NULL);
+
+ shumate_vector_renderer_set_sprite_sheet_data (renderer,
+ sprites_pixbuf,
+ g_bytes_get_data (sprites_json, NULL),
+ &error);
+
+ if (error)
+ {
+ g_warning ("Failed to create spritesheet for vector map style: %s", error->message);
+ g_clear_error (&error);
+ }
+
shumate_map_source_set_license (SHUMATE_MAP_SOURCE (renderer), "© OpenStreetMap contributors");
shumate_map_source_registry_add (self->registry, SHUMATE_MAP_SOURCE (renderer));
}
diff --git a/demos/sprites.json b/demos/sprites.json
new file mode 100644
index 0000000..469fefb
--- /dev/null
+++ b/demos/sprites.json
@@ -0,0 +1,9 @@
+{
+ "ocean": {
+ "height": 8,
+ "pixelRatio": 1,
+ "width": 16,
+ "x": 0,
+ "y": 0
+ }
+}
\ No newline at end of file
diff --git a/demos/sprites.svg b/demos/sprites.svg
new file mode 100644
index 0000000..c8328cd
--- /dev/null
+++ b/demos/sprites.svg
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="16"
+ height="8"
+ viewBox="0 0 16 8"
+ version="1.1"
+ id="svg5"
+ inkscape:version="1.2 (dc2aedaf03, 2022-05-15)"
+ sodipodi:docname="sprites.svg"
+ inkscape:export-filename="sprites.png"
+ inkscape:export-xdpi="96"
+ inkscape:export-ydpi="96"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview7"
+ pagecolor="#505050"
+ bordercolor="#eeeeee"
+ borderopacity="1"
+ inkscape:showpageshadow="0"
+ inkscape:pageopacity="0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#505050"
+ inkscape:document-units="px"
+ showgrid="true"
+ inkscape:zoom="24.4375"
+ inkscape:cx="9.8005115"
+ inkscape:cy="5.2378517"
+ inkscape:window-width="1920"
+ inkscape:window-height="1011"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="layer1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid1050"
+ empspacing="4"
+ originx="0"
+ originy="0" />
+ </sodipodi:namedview>
+ <defs
+ id="defs2" />
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <path
+ id="path1104"
+ style="color:#000000;fill:#fefefe;stroke-linecap:square;-inkscape-stroke:none"
+ d="M 7.5,1 C 7.5,1.8343462 6.790313,2.7024995 5.4335938,3.3808594 4.0768734,4.0592192 2.1415758,4.5
0,4.5 v 1 C 2.2766854,5.5 4.3421614,5.0447404 5.8808594,4.2753906 6.7921632,3.8197391 7.5394361,3.2357286
8,2.5507812 8.460564,3.2357286 9.2078367,3.8197391 10.119141,4.2753906 11.657839,5.0447404 13.723315,5.5
16,5.5 v -1 C 13.858424,4.5 11.923127,4.0592192 10.566406,3.3808594 9.2096868,2.7024995 8.5,1.8343462 8.5,1
Z" />
+ </g>
+</svg>
diff --git a/shumate/meson.build b/shumate/meson.build
index 94a5257..1e02f8a 100644
--- a/shumate/meson.build
+++ b/shumate/meson.build
@@ -43,6 +43,7 @@ libshumate_private_h = [
'vector/shumate-vector-layer-private.h',
'vector/shumate-vector-line-layer-private.h',
'vector/shumate-vector-render-scope-private.h',
+ 'vector/shumate-vector-sprite-sheet-private.h',
'vector/shumate-vector-symbol-private.h',
'vector/shumate-vector-symbol-container-private.h',
'vector/shumate-vector-symbol-info-private.h',
@@ -170,6 +171,7 @@ if get_option('vector_renderer')
'vector/shumate-vector-layer.c',
'vector/shumate-vector-line-layer.c',
'vector/shumate-vector-render-scope.c',
+ 'vector/shumate-vector-sprite-sheet.c',
'vector/shumate-vector-symbol.c',
'vector/shumate-vector-symbol-container.c',
'vector/shumate-vector-symbol-info.c',
diff --git a/shumate/shumate-vector-renderer.c b/shumate/shumate-vector-renderer.c
index ab1cd49..aa8d2ab 100644
--- a/shumate/shumate-vector-renderer.c
+++ b/shumate/shumate-vector-renderer.c
@@ -42,6 +42,10 @@ struct _ShumateVectorRenderer
ShumateDataSource *data_source;
GPtrArray *tiles;
+#ifdef SHUMATE_HAS_VECTOR_RENDERER
+ ShumateVectorSpriteSheet *sprites;
+#endif
+
char *style_json;
GPtrArray *layers;
@@ -132,6 +136,9 @@ shumate_vector_renderer_finalize (GObject *object)
g_clear_pointer (&self->source_name, g_free);
g_clear_object (&self->data_source);
g_clear_pointer (&self->tiles, g_ptr_array_unref);
+#ifdef SHUMATE_HAS_VECTOR_RENDERER
+ g_clear_object (&self->sprites);
+#endif
G_OBJECT_CLASS (shumate_vector_renderer_parent_class)->finalize (object);
}
@@ -424,6 +431,42 @@ shumate_vector_renderer_get_style_json (ShumateVectorRenderer *self)
}
+/**
+ * shumate_vector_renderer_set_sprite_sheet_data:
+ * @self: a [class@VectorRenderer]
+ * @sprites_pixbuf: a [class@Gdk.Pixbuf]
+ * @sprites_json: a JSON string
+ * @error: return location for a #GError, or %NULL
+ *
+ * Sets the sprite sheet used by the style JSON to render icons and textures.
+ *
+ * See <https://maplibre.org/maplibre-gl-js-docs/style-spec/sprite/> for
+ * details about the spritesheet format. Most stylesheets provide these files
+ * along with the main style JSON.
+ */
+void
+shumate_vector_renderer_set_sprite_sheet_data (ShumateVectorRenderer *self,
+ GdkPixbuf *sprites_pixbuf,
+ const char *sprites_json,
+ GError **error)
+{
+ g_return_if_fail (SHUMATE_IS_VECTOR_RENDERER (self));
+ g_return_if_fail (GDK_IS_PIXBUF (sprites_pixbuf));
+ g_return_if_fail (sprites_json != NULL);
+
+#ifdef SHUMATE_HAS_VECTOR_RENDERER
+ g_clear_object (&self->sprites);
+ self->sprites = shumate_vector_sprite_sheet_new (sprites_pixbuf, sprites_json, NULL, error);
+#else
+ g_set_error (error,
+ SHUMATE_STYLE_ERROR,
+ SHUMATE_STYLE_ERROR_SUPPORT_OMITTED,
+ "Libshumate was compiled without support for vector tiles.");
+ return FALSE;
+#endif
+}
+
+
#ifdef SHUMATE_HAS_VECTOR_RENDERER
static GdkTexture *
texture_new_for_surface (cairo_surface_t *surface)
@@ -540,6 +583,7 @@ render (ShumateVectorRenderer *self,
scope.target_size = texture_size;
scope.zoom_level = zoom_level;
scope.symbols = symbols;
+ scope.sprites = self->sprites;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, texture_size, texture_size);
scope.cr = cairo_create (surface);
diff --git a/shumate/shumate-vector-renderer.h b/shumate/shumate-vector-renderer.h
index 1e62f2b..fddabd0 100644
--- a/shumate/shumate-vector-renderer.h
+++ b/shumate/shumate-vector-renderer.h
@@ -35,6 +35,10 @@ ShumateVectorRenderer *shumate_vector_renderer_new (const char *id,
const char *style_json,
GError **error);
+void shumate_vector_renderer_set_sprite_sheet_data (ShumateVectorRenderer *self,
+ GdkPixbuf *sprites_pixbuf,
+ const char *sprites_json,
+ GError **error);
/**
* SHUMATE_STYLE_ERROR:
diff --git a/shumate/vector/shumate-vector-fill-layer.c b/shumate/vector/shumate-vector-fill-layer.c
index 2e49ecd..e1384e0 100644
--- a/shumate/vector/shumate-vector-fill-layer.c
+++ b/shumate/vector/shumate-vector-fill-layer.c
@@ -18,6 +18,7 @@
#include <gtk/gtk.h>
#include "shumate-vector-expression-private.h"
#include "shumate-vector-fill-layer-private.h"
+#include "shumate-vector-sprite-sheet-private.h"
#include "shumate-vector-utils-private.h"
#include "shumate-vector-value-private.h"
@@ -27,6 +28,7 @@ struct _ShumateVectorFillLayer
ShumateVectorExpression *color;
ShumateVectorExpression *opacity;
+ ShumateVectorExpression *pattern;
};
G_DEFINE_TYPE (ShumateVectorFillLayer, shumate_vector_fill_layer, SHUMATE_TYPE_VECTOR_LAYER)
@@ -50,6 +52,9 @@ shumate_vector_fill_layer_create_from_json (JsonObject *object, GError **error)
if (!(layer->opacity = shumate_vector_expression_from_json (json_object_get_member (paint,
"fill-opacity"), error)))
return NULL;
+
+ if (!(layer->pattern = shumate_vector_expression_from_json (json_object_get_member (paint,
"fill-pattern"), error)))
+ return NULL;
}
return (ShumateVectorLayer *)layer;
@@ -62,14 +67,40 @@ shumate_vector_fill_layer_render (ShumateVectorLayer *layer, ShumateVectorRender
ShumateVectorFillLayer *self = SHUMATE_VECTOR_FILL_LAYER (layer);
GdkRGBA color = SHUMATE_VECTOR_COLOR_BLACK;
double opacity;
+ g_autofree char *pattern;
shumate_vector_expression_eval_color (self->color, scope, &color);
opacity = shumate_vector_expression_eval_number (self->opacity, scope, 1.0);
+ pattern = shumate_vector_expression_eval_string (self->pattern, scope, NULL);
shumate_vector_render_scope_exec_geometry (scope);
- cairo_set_source_rgba (scope->cr, color.red, color.green, color.blue, color.alpha * opacity);
- cairo_fill (scope->cr);
+ if (pattern != NULL)
+ {
+ GdkPixbuf *sprite = shumate_vector_sprite_sheet_get_icon (scope->sprites, pattern);
+ if (sprite != NULL)
+ {
+ cairo_pattern_t *cr_pattern;
+ cairo_matrix_t matrix;
+
+ gdk_cairo_set_source_pixbuf (scope->cr, sprite, 0, 0);
+ cr_pattern = cairo_get_source (scope->cr);
+ cairo_matrix_init_scale (&matrix, 1 / scope->scale, 1 / scope->scale);
+ cairo_pattern_set_matrix (cr_pattern, &matrix);
+ cairo_pattern_set_extend (cr_pattern, CAIRO_EXTEND_REPEAT);
+
+ /* Use cairo_paint_with_alpha so that we can set fill-opacity correctly. */
+ cairo_save (scope->cr);
+ cairo_clip (scope->cr);
+ cairo_paint_with_alpha (scope->cr, opacity);
+ cairo_restore (scope->cr);
+ }
+ }
+ else
+ {
+ cairo_set_source_rgba (scope->cr, color.red, color.green, color.blue, color.alpha * opacity);
+ cairo_fill (scope->cr);
+ }
}
diff --git a/shumate/vector/shumate-vector-render-scope-private.h
b/shumate/vector/shumate-vector-render-scope-private.h
index eb121b3..a2797c6 100644
--- a/shumate/vector/shumate-vector-render-scope-private.h
+++ b/shumate/vector/shumate-vector-render-scope-private.h
@@ -20,6 +20,7 @@
#include <glib-object.h>
#include <cairo/cairo.h>
#include "vector_tile.pb-c.h"
+#include "shumate-vector-sprite-sheet-private.h"
#include "shumate-vector-value-private.h"
#include "shumate-vector-utils-private.h"
@@ -31,6 +32,8 @@ typedef struct {
GPtrArray *symbols;
+ ShumateVectorSpriteSheet *sprites;
+
VectorTile__Tile *tile;
VectorTile__Tile__Layer *layer;
VectorTile__Tile__Feature *feature;
diff --git a/shumate/vector/shumate-vector-sprite-sheet-private.h
b/shumate/vector/shumate-vector-sprite-sheet-private.h
new file mode 100644
index 0000000..4201605
--- /dev/null
+++ b/shumate/vector/shumate-vector-sprite-sheet-private.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 James Westman <james jwestman net>
+ *
+ * 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.1 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, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+#define SHUMATE_TYPE_VECTOR_SPRITE_SHEET (shumate_vector_sprite_sheet_get_type())
+G_DECLARE_FINAL_TYPE (ShumateVectorSpriteSheet, shumate_vector_sprite_sheet, SHUMATE, VECTOR_SPRITE_SHEET,
GObject)
+
+ShumateVectorSpriteSheet *shumate_vector_sprite_sheet_new (GdkPixbuf *pixbuf,
+ const char *json,
+ GCancellable *cancellable,
+ GError **error);
+
+GdkPixbuf *shumate_vector_sprite_sheet_get_icon (ShumateVectorSpriteSheet *self,
+ const char *name);
+
+G_END_DECLS
diff --git a/shumate/vector/shumate-vector-sprite-sheet.c b/shumate/vector/shumate-vector-sprite-sheet.c
new file mode 100644
index 0000000..d36506e
--- /dev/null
+++ b/shumate/vector/shumate-vector-sprite-sheet.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2022 James Westman <james jwestman net>
+ *
+ * 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.1 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, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <json-glib/json-glib.h>
+#include "shumate-vector-sprite-sheet-private.h"
+#include "shumate-vector-utils-private.h"
+
+struct _ShumateVectorSpriteSheet
+{
+ GObject parent_instance;
+
+ char *json;
+ GdkPixbuf *pixbuf;
+ GHashTable *sprites;
+};
+
+enum {
+ PROP_0,
+ PROP_PIXBUF,
+ PROP_JSON,
+ N_PROPS,
+};
+
+static GParamSpec *properties [N_PROPS];
+
+static void shumate_vector_sprite_sheet_initable_iface_init (GInitableIface *iface);
+
+G_DEFINE_FINAL_TYPE_WITH_CODE (ShumateVectorSpriteSheet, shumate_vector_sprite_sheet, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
shumate_vector_sprite_sheet_initable_iface_init))
+
+
+typedef struct {
+ int x, y;
+ int width, height;
+ GdkPixbuf *pixbuf;
+} Sprite;
+
+static void
+sprite_free (Sprite *sprite)
+{
+ g_clear_object (&sprite->pixbuf);
+ g_free (sprite);
+}
+
+
+ShumateVectorSpriteSheet *
+shumate_vector_sprite_sheet_new (GdkPixbuf *pixbuf,
+ const char *json,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return g_initable_new (SHUMATE_TYPE_VECTOR_SPRITE_SHEET, cancellable, error,
+ "json", json,
+ "pixbuf", pixbuf,
+ NULL);
+}
+
+static void
+shumate_vector_sprite_sheet_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ShumateVectorSpriteSheet *self = SHUMATE_VECTOR_SPRITE_SHEET (object);
+
+ switch (prop_id)
+ {
+ case PROP_PIXBUF:
+ g_value_set_object (value, self->pixbuf);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+shumate_vector_sprite_sheet_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ShumateVectorSpriteSheet *self = SHUMATE_VECTOR_SPRITE_SHEET (object);
+
+ switch (prop_id)
+ {
+ case PROP_PIXBUF:
+ /* Property is construct only, so it should only be set once */
+ g_assert (self->pixbuf == NULL);
+ self->pixbuf = g_value_dup_object (value);
+ break;
+ case PROP_JSON:
+ /* Property is construct only, so it should only be set once */
+ g_assert (self->json == NULL);
+ self->json = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+shumate_vector_sprite_sheet_finalize (GObject *object)
+{
+ ShumateVectorSpriteSheet *self = (ShumateVectorSpriteSheet *)object;
+
+ g_clear_pointer (&self->json, g_free);
+ g_clear_object (&self->pixbuf);
+ g_clear_pointer (&self->sprites, g_hash_table_unref);
+
+ G_OBJECT_CLASS (shumate_vector_sprite_sheet_parent_class)->finalize (object);
+}
+
+static void
+shumate_vector_sprite_sheet_class_init (ShumateVectorSpriteSheetClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = shumate_vector_sprite_sheet_finalize;
+ object_class->get_property = shumate_vector_sprite_sheet_get_property;
+ object_class->set_property = shumate_vector_sprite_sheet_set_property;
+
+ properties[PROP_JSON] =
+ g_param_spec_string ("json",
+ "JSON",
+ "JSON",
+ NULL,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY |
G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_PIXBUF] =
+ g_param_spec_object ("pixbuf",
+ "Pixbuf",
+ "Pixbuf",
+ GDK_TYPE_PIXBUF,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY |
G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static gboolean
+shumate_vector_sprite_sheet_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ ShumateVectorSpriteSheet *self = (ShumateVectorSpriteSheet *)initable;
+ g_autoptr(JsonNode) json_node = NULL;
+ JsonObject *sprites;
+ JsonObjectIter iter;
+ const char *sprite_name;
+ JsonNode *sprite_node;
+
+ json_node = json_from_string (self->json, error);
+ g_clear_pointer (&self->json, g_free);
+
+ if (json_node == NULL)
+ return FALSE;
+
+ if (!shumate_vector_json_get_object (json_node, &sprites, error))
+ return FALSE;
+
+ json_object_iter_init (&iter, sprites);
+ while (json_object_iter_next (&iter, &sprite_name, &sprite_node))
+ {
+ Sprite *sprite;
+ JsonObject *sprite_object;
+
+ if (!shumate_vector_json_get_object (sprite_node, &sprite_object, error))
+ return FALSE;
+
+ sprite = g_new0 (Sprite, 1);
+ sprite->x = json_object_get_int_member_with_default (sprite_object, "x", 0);
+ sprite->y = json_object_get_int_member_with_default (sprite_object, "y", 0);
+ sprite->width = json_object_get_int_member_with_default (sprite_object, "width", 0);
+ sprite->height = json_object_get_int_member_with_default (sprite_object, "height", 0);
+
+ g_hash_table_insert (self->sprites, g_strdup (sprite_name), sprite);
+ }
+
+ return TRUE;
+}
+
+static void
+shumate_vector_sprite_sheet_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = shumate_vector_sprite_sheet_initable_init;
+}
+
+static void
+shumate_vector_sprite_sheet_init (ShumateVectorSpriteSheet *self)
+{
+ self->sprites = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)sprite_free);
+}
+
+/*< private >
+ * shumate_vector_sprite_sheet_get_icon:
+ * @self: a [class@VectorSpriteSheet]
+ * @name: an icon name
+ *
+ * Gets an icon's image from the spritesheet.
+ *
+ * Returns: (transfer none) (nullable): a [class@Gdk.Pixbuf], or %NULL if the
+ * icon does not exist.
+ */
+GdkPixbuf *
+shumate_vector_sprite_sheet_get_icon (ShumateVectorSpriteSheet *self,
+ const char *name)
+{
+ Sprite *sprite;
+
+ sprite = g_hash_table_lookup (self->sprites, name);
+ if (sprite == NULL)
+ return NULL;
+
+ if (sprite->pixbuf != NULL)
+ return sprite->pixbuf;
+
+ sprite->pixbuf = gdk_pixbuf_new_subpixbuf (self->pixbuf,
+ sprite->x,
+ sprite->y,
+ sprite->width,
+ sprite->height);
+
+ return sprite->pixbuf;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]