[libshumate] vector: Add ShumateVectorStyle
- From: Marcus Lundblad <mlundblad src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libshumate] vector: Add ShumateVectorStyle
- Date: Mon, 1 Nov 2021 22:00:05 +0000 (UTC)
commit 5d2d232a719ceb867eaa940a03e04d428e1875c7
Author: James Westman <james jwestman net>
Date: Mon Aug 23 01:23:22 2021 -0500
vector: Add ShumateVectorStyle
Here begins the epic vector tiles merge request...
ShumateVectorStyle is the main entry point of the vector renderer. By
setting the `style` property of a ShumateNetworkTileSource, tiles will
be interpreted as protobuf/Mapbox Vector Tile formatted files rather
than raster images.
So far, though, none of that is implemented and ShumateVectorStyle
contains a dummy renderer.
demos/shumate-demo-window.c | 13 +++
shumate/meson.build | 2 +
shumate/shumate-network-tile-source.c | 201 +++++++++++++++++++++++++++-----
shumate/shumate-network-tile-source.h | 14 +++
shumate/shumate-vector-style.c | 208 ++++++++++++++++++++++++++++++++++
shumate/shumate-vector-style.h | 33 ++++++
shumate/shumate.h | 2 +
7 files changed, 443 insertions(+), 30 deletions(-)
---
diff --git a/demos/shumate-demo-window.c b/demos/shumate-demo-window.c
index 88b6e5c..311e42e 100644
--- a/demos/shumate-demo-window.c
+++ b/demos/shumate-demo-window.c
@@ -138,6 +138,8 @@ shumate_demo_window_init (ShumateDemoWindow *self)
{
ShumateViewport *viewport;
GtkExpression *expression;
+ g_autoptr(ShumateVectorStyle) style = NULL;
+ ShumateMapSource *map_source = NULL;
gtk_widget_init_template (GTK_WIDGET (self));
@@ -148,6 +150,17 @@ shumate_demo_window_init (ShumateDemoWindow *self)
gtk_drop_down_set_expression (self->layers_dropdown, expression);
gtk_drop_down_set_model (self->layers_dropdown, G_LIST_MODEL (self->registry));
+ style = shumate_vector_style_create ("{}", NULL);
+
+ map_source = SHUMATE_MAP_SOURCE (shumate_network_tile_source_new_vector_full (
+ "vector-tiles",
+ "Vector Tiles",
+ "© OpenStreetMap contributors", NULL, 0, 14, 512,
+ SHUMATE_MAP_PROJECTION_MERCATOR,
+ "https://jwestman.pages.gitlab.gnome.org/vector-tile-test-data/world_overview/#Z#/#X#/#Y#.pbf",
+ style
+ ));
+ shumate_map_source_registry_add (self->registry, map_source);
viewport = shumate_map_get_viewport (self->map);
diff --git a/shumate/meson.build b/shumate/meson.build
index 4c9542a..0326fd4 100644
--- a/shumate/meson.build
+++ b/shumate/meson.build
@@ -17,6 +17,7 @@ libshumate_public_h = [
'shumate-point.h',
'shumate-scale.h',
'shumate-tile.h',
+ 'shumate-vector-style.h',
'shumate-viewport.h',
'shumate.h',
]
@@ -46,6 +47,7 @@ libshumate_sources = [
'shumate-point.c',
'shumate-scale.c',
'shumate-tile.c',
+ 'shumate-vector-style.c',
'shumate-viewport.c',
]
diff --git a/shumate/shumate-network-tile-source.c b/shumate/shumate-network-tile-source.c
index a25d090..1a18a16 100644
--- a/shumate/shumate-network-tile-source.c
+++ b/shumate/shumate-network-tile-source.c
@@ -56,6 +56,7 @@ enum
PROP_MAX_CONNS,
PROP_USER_AGENT,
PROP_FILE_CACHE,
+ PROP_STYLE,
N_PROPERTIES,
};
@@ -69,6 +70,7 @@ typedef struct
SoupSession *soup_session;
int max_conns;
ShumateFileCache *file_cache;
+ ShumateVectorStyle *style;
} ShumateNetworkTileSourcePrivate;
G_DEFINE_TYPE_WITH_PRIVATE (ShumateNetworkTileSource, shumate_network_tile_source, SHUMATE_TYPE_MAP_SOURCE);
@@ -136,6 +138,10 @@ shumate_network_tile_source_get_property (GObject *object,
g_value_set_object (value, priv->file_cache);
break;
+ case PROP_STYLE:
+ g_value_set_object (value, priv->style);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -149,6 +155,7 @@ shumate_network_tile_source_set_property (GObject *object,
GParamSpec *pspec)
{
ShumateNetworkTileSource *tile_source = SHUMATE_NETWORK_TILE_SOURCE (object);
+ ShumateNetworkTileSourcePrivate *priv = shumate_network_tile_source_get_instance_private (tile_source);
switch (prop_id)
{
@@ -172,6 +179,10 @@ shumate_network_tile_source_set_property (GObject *object,
shumate_network_tile_source_set_user_agent (tile_source, g_value_get_string (value));
break;
+ case PROP_STYLE:
+ g_set_object (&priv->style, g_value_get_object (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -300,6 +311,18 @@ shumate_network_tile_source_class_init (ShumateNetworkTileSourceClass *klass)
SHUMATE_TYPE_FILE_CACHE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+ /**
+ * ShumateNetworkTileSource:style:
+ *
+ * The style for rendering vector tiles.
+ */
+ obj_properties[PROP_STYLE] =
+ g_param_spec_object("style",
+ "Style",
+ "Style",
+ SHUMATE_TYPE_VECTOR_STYLE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (object_class, N_PROPERTIES, obj_properties);
}
@@ -375,6 +398,53 @@ shumate_network_tile_source_new_full (const char *id,
}
+/**
+ * shumate_network_tile_source_new_vector_full:
+ * @id: the map source's id
+ * @name: the map source's name
+ * @license: the map source's license
+ * @license_uri: the map source's license URI
+ * @min_zoom: the map source's minimum zoom level
+ * @max_zoom: the map source's maximum zoom level
+ * @tile_size: the map source's tile size (in pixels)
+ * @projection: the map source's projection
+ * @uri_format: the URI to fetch the tiles from, see #shumate_network_tile_source_set_uri_format
+ * @style: the style with which to render tiles
+ *
+ * Creates a [class@NetworkTileSource] that renders tiles with a [class@VectorStyle].
+ *
+ * Returns: a constructed [class@NetworkTileSource] object
+ */
+ShumateNetworkTileSource *
+shumate_network_tile_source_new_vector_full (const char *id,
+ const char *name,
+ const char *license,
+ const char *license_uri,
+ guint min_zoom,
+ guint max_zoom,
+ guint tile_size,
+ ShumateMapProjection projection,
+ const char *uri_format,
+ ShumateVectorStyle *style)
+{
+ ShumateNetworkTileSource *source;
+
+ source = g_object_new (SHUMATE_TYPE_NETWORK_TILE_SOURCE,
+ "id", id,
+ "name", name,
+ "license", license,
+ "license-uri", license_uri,
+ "min-zoom-level", min_zoom,
+ "max-zoom-level", max_zoom,
+ "tile-size", tile_size,
+ "projection", projection,
+ "uri-format", uri_format,
+ "style", style,
+ NULL);
+ return source;
+}
+
+
/**
* shumate_network_tile_source_get_uri_format:
* @tile_source: the #ShumateNetworkTileSource
@@ -593,6 +663,24 @@ shumate_network_tile_source_set_user_agent (
}
+/**
+ * shumate_network_tile_source_get_style:
+ * @self: a [class@NetworkTileSource]
+ *
+ * Gets the vector style used to render vector tiles, or %NULL if the source
+ * uses raster tiles.
+ *
+ * Returns: (transfer none): the source's vector rendering style
+ */
+ShumateVectorStyle *
+shumate_network_tile_source_get_style (ShumateNetworkTileSource *self)
+{
+ ShumateNetworkTileSourcePrivate *priv = shumate_network_tile_source_get_instance_private (self);
+ g_return_val_if_fail (SHUMATE_IS_NETWORK_TILE_SOURCE (self), NULL);
+ return priv->style;
+}
+
+
#define SIZE 8
static char *
get_tile_uri (ShumateNetworkTileSource *tile_source,
@@ -646,11 +734,12 @@ get_tile_uri (ShumateNetworkTileSource *tile_source,
}
static void on_file_cache_get_tile (GObject *source_object, GAsyncResult *res, gpointer user_data);
-static void on_pixbuf_created_from_cache (GObject *source_object, GAsyncResult *res, gpointer user_data);
+static void on_tile_rendered_from_cache (GObject *source_object, GAsyncResult *res, gpointer user_data);
static void fetch_from_network (GTask *task);
static void on_message_sent (GObject *source_object, GAsyncResult *res, gpointer user_data);
static void on_message_read (GObject *source_object, GAsyncResult *res, gpointer user_data);
static void on_pixbuf_created (GObject *source_object, GAsyncResult *res, gpointer user_data);
+static void on_tile_rendered (GObject *source_object, GAsyncResult *res, gpointer user_data);
typedef struct {
ShumateNetworkTileSource *self;
@@ -692,6 +781,77 @@ get_modified_time_string (GDateTime *modified_time)
}
+static void
+render_tile_async (ShumateNetworkTileSource *self,
+ ShumateTile *tile,
+ GBytes *bytes,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ ShumateNetworkTileSourcePrivate *priv = shumate_network_tile_source_get_instance_private (self);
+
+ g_autoptr(GTask) task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_source_tag (task, render_tile_async);
+
+ if (priv->style)
+ {
+ g_autoptr(GdkTexture) texture = NULL;
+ g_autoptr(GError) error = NULL;
+
+ texture = shumate_vector_style_render (priv->style, shumate_tile_get_size (tile));
+ if (error != NULL)
+ {
+ g_task_return_error (task, g_steal_pointer (&error));
+ return;
+ }
+
+ shumate_tile_set_texture (tile, texture);
+ shumate_tile_set_fade_in (tile, TRUE);
+
+ g_task_return_boolean (task, TRUE);
+ }
+ else
+ {
+ g_autoptr(GInputStream) input_stream = g_memory_input_stream_new_from_bytes (bytes);
+
+ g_task_set_task_data (task, g_object_ref (tile), g_object_unref);
+
+ gdk_pixbuf_new_from_stream_async (input_stream, cancellable, on_pixbuf_created, g_object_ref (task));
+ }
+}
+
+static void
+on_pixbuf_created (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ g_autoptr(GTask) task = user_data;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GdkPixbuf) pixbuf = NULL;
+ g_autoptr(GdkTexture) texture = NULL;
+ ShumateTile *tile = SHUMATE_TILE (g_task_get_task_data (task));
+
+ pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
+ if (error != NULL)
+ {
+ g_task_return_error (task, g_steal_pointer (&error));
+ return;
+ }
+
+ texture = gdk_texture_new_for_pixbuf (pixbuf);
+ shumate_tile_set_texture (tile, texture);
+ shumate_tile_set_fade_in (tile, TRUE);
+
+ g_task_return_boolean (task, TRUE);
+}
+
+gboolean
+render_tile_finish (ShumateNetworkTileSource *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
static void
fill_tile_async (ShumateMapSource *self,
ShumateTile *tile,
@@ -740,23 +900,17 @@ on_file_cache_get_tile (GObject *source_object, GAsyncResult *res, gpointer user
&data->etag, &data->modtime, res, NULL);
if (data->bytes != NULL)
- {
- g_autoptr(GInputStream) input_stream = g_memory_input_stream_new_from_bytes (data->bytes);
-
- /* When on_pixbuf_created_from_cache() is called, it will call
- * fetch_from_network() if needed */
- gdk_pixbuf_new_from_stream_async (input_stream, cancellable, on_pixbuf_created_from_cache,
g_object_ref (task));
- }
+ /* When on_pixbuf_created_from_cache() is called, it will call
+ * fetch_from_network() if needed */
+ render_tile_async (data->self, data->tile, data->bytes, cancellable, on_tile_rendered_from_cache,
g_object_ref (task));
else
- {
- fetch_from_network (task);
- }
+ fetch_from_network (task);
}
/* Fill the tile from the pixbuf, created from the cache. Then, if the cache
* data is potentially out of date, fetch from the network. */
static void
-on_pixbuf_created_from_cache (GObject *source_object, GAsyncResult *res, gpointer user_data)
+on_tile_rendered_from_cache (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
g_autoptr(GTask) task = user_data;
FillTileData *data = g_task_get_task_data (task);
@@ -764,18 +918,12 @@ on_pixbuf_created_from_cache (GObject *source_object, GAsyncResult *res, gpointe
g_autoptr(GdkPixbuf) pixbuf = NULL;
g_autoptr(GError) error = NULL;
- pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
-
- if (error != NULL)
+ if (!render_tile_finish (data->self, res, &error))
{
g_task_return_error (task, g_steal_pointer (&error));
return;
}
- texture = gdk_texture_new_for_pixbuf (pixbuf);
- shumate_tile_set_texture (data->tile, texture);
- shumate_tile_set_fade_in (data->tile, TRUE);
-
if (data->bytes != NULL && !tile_is_expired (data->modtime))
{
shumate_tile_set_state (data->tile, SHUMATE_STATE_DONE);
@@ -921,9 +1069,7 @@ on_message_read (GObject *source_object, GAsyncResult *res, gpointer user_data)
GOutputStream *output_stream = G_OUTPUT_STREAM (source_object);
g_autoptr(GTask) task = user_data;
FillTileData *data = g_task_get_task_data (task);
- GCancellable *cancellable = g_task_get_cancellable (task);
g_autoptr(GError) error = NULL;
- g_autoptr(GInputStream) input_stream = NULL;
g_output_stream_splice_finish (output_stream, res, &error);
if (error != NULL)
@@ -935,15 +1081,14 @@ on_message_read (GObject *source_object, GAsyncResult *res, gpointer user_data)
g_bytes_unref (data->bytes);
data->bytes = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (output_stream));
- input_stream = g_memory_input_stream_new_from_bytes (data->bytes);
- gdk_pixbuf_new_from_stream_async (input_stream, cancellable, on_pixbuf_created, g_object_ref (task));
+ render_tile_async (data->self, data->tile, data->bytes, NULL, on_tile_rendered, g_object_ref (task));
}
/* Fill the tile from the pixbuf, created from the network response. Begin
* storing the data in the cache (but don't wait for that to finish). Then
* return. */
static void
-on_pixbuf_created (GObject *source_object, GAsyncResult *res, gpointer user_data)
+on_tile_rendered (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
g_autoptr(GTask) task = user_data;
FillTileData *data = g_task_get_task_data (task);
@@ -953,8 +1098,7 @@ on_pixbuf_created (GObject *source_object, GAsyncResult *res, gpointer user_data
g_autoptr(GdkPixbuf) pixbuf = NULL;
g_autoptr(GdkTexture) texture = NULL;
- pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
- if (error != NULL)
+ if (!render_tile_finish (data->self, res, &error))
{
g_task_return_error (task, g_steal_pointer (&error));
return;
@@ -962,11 +1106,8 @@ on_pixbuf_created (GObject *source_object, GAsyncResult *res, gpointer user_data
shumate_file_cache_store_tile_async (priv->file_cache, data->tile, data->bytes, data->etag, cancellable,
NULL, NULL);
- texture = gdk_texture_new_for_pixbuf (pixbuf);
- shumate_tile_set_texture (data->tile, texture);
- shumate_tile_set_fade_in (data->tile, TRUE);
-
shumate_tile_set_state (data->tile, SHUMATE_STATE_DONE);
+
g_task_return_boolean (task, TRUE);
}
diff --git a/shumate/shumate-network-tile-source.h b/shumate/shumate-network-tile-source.h
index 0332a97..062ec11 100644
--- a/shumate/shumate-network-tile-source.h
+++ b/shumate/shumate-network-tile-source.h
@@ -25,6 +25,7 @@
#ifndef _SHUMATE_NETWORK_TILE_SOURCE_H_
#define _SHUMATE_NETWORK_TILE_SOURCE_H_
+#include <shumate/shumate-vector-style.h>
#include <shumate/shumate-map-source.h>
G_BEGIN_DECLS
@@ -77,6 +78,17 @@ ShumateNetworkTileSource *shumate_network_tile_source_new_full (const char *id,
ShumateMapProjection projection,
const char *uri_format);
+ShumateNetworkTileSource *shumate_network_tile_source_new_vector_full (const char *id,
+ const char *name,
+ const char *license,
+ const char *license_uri,
+ guint min_zoom,
+ guint max_zoom,
+ guint tile_size,
+ ShumateMapProjection projection,
+ const char *uri_format,
+ ShumateVectorStyle *style);
+
const char *shumate_network_tile_source_get_uri_format (ShumateNetworkTileSource *tile_source);
void shumate_network_tile_source_set_uri_format (ShumateNetworkTileSource *tile_source,
const char *uri_format);
@@ -96,6 +108,8 @@ void shumate_network_tile_source_set_max_conns (ShumateNetworkTileSource *tile_s
void shumate_network_tile_source_set_user_agent (ShumateNetworkTileSource *tile_source,
const char *user_agent);
+ShumateVectorStyle *shumate_network_tile_source_get_style (ShumateNetworkTileSource *self);
+
G_END_DECLS
#endif /* _SHUMATE_NETWORK_TILE_SOURCE_H_ */
diff --git a/shumate/shumate-vector-style.c b/shumate/shumate-vector-style.c
new file mode 100644
index 0000000..841cde9
--- /dev/null
+++ b/shumate/shumate-vector-style.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2021 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 <cairo/cairo.h>
+
+#include "shumate-vector-style.h"
+
+struct _ShumateVectorStyle
+{
+ GObject parent_instance;
+
+ char *style_json;
+};
+
+G_DEFINE_TYPE (ShumateVectorStyle, shumate_vector_style, G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_STYLE_JSON,
+ N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
+
+/**
+ * shumate_vector_style_create:
+ * @style_json: a JSON string
+ * @error: return location for a [class@GLib.Error], or %NULL
+ *
+ * Creates a vector style from a JSON definition.
+ *
+ * Returns: (transfer full): a new [class@VectorStyle] object, or %NULL if the
+ * style could not be parsed
+ */
+ShumateVectorStyle *
+shumate_vector_style_create (const char *style_json, GError **error)
+{
+ g_return_val_if_fail (style_json != NULL, NULL);
+
+ return g_object_new (SHUMATE_TYPE_VECTOR_STYLE,
+ "style-json", style_json,
+ NULL);
+}
+
+
+static void
+shumate_vector_style_finalize (GObject *object)
+{
+ ShumateVectorStyle *self = (ShumateVectorStyle *)object;
+
+ g_clear_pointer (&self->style_json, g_free);
+
+ G_OBJECT_CLASS (shumate_vector_style_parent_class)->finalize (object);
+}
+
+static void
+shumate_vector_style_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ShumateVectorStyle *self = SHUMATE_VECTOR_STYLE (object);
+
+ switch (prop_id)
+ {
+ case PROP_STYLE_JSON:
+ g_value_set_string (value, self->style_json);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+shumate_vector_style_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ShumateVectorStyle *self = SHUMATE_VECTOR_STYLE (object);
+
+ switch (prop_id)
+ {
+ case PROP_STYLE_JSON:
+ /* Property is construct only, so it should only be set once */
+ g_assert (self->style_json == NULL);
+ self->style_json = g_strdup (g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+shumate_vector_style_class_init (ShumateVectorStyleClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = shumate_vector_style_finalize;
+ object_class->get_property = shumate_vector_style_get_property;
+ object_class->set_property = shumate_vector_style_set_property;
+
+ properties[PROP_STYLE_JSON] =
+ g_param_spec_string ("style-json",
+ "Style JSON",
+ "Style JSON",
+ NULL,
+ 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 void
+shumate_vector_style_init (ShumateVectorStyle *self)
+{
+}
+
+
+/**
+ * shumate_vector_style_get_style_json:
+ * @self: a [class@VectorStyle]
+ *
+ * Gets the JSON string from which this vector style was loaded.
+ *
+ * Returns: (nullable): the style JSON, or %NULL if none is set
+ */
+const char *
+shumate_vector_style_get_style_json (ShumateVectorStyle *self)
+{
+ g_return_val_if_fail (SHUMATE_IS_VECTOR_STYLE (self), NULL);
+
+ return self->style_json;
+}
+
+
+static GdkTexture *
+texture_new_for_surface (cairo_surface_t *surface)
+{
+ g_autoptr(GBytes) bytes = NULL;
+ GdkTexture *texture;
+
+ g_return_val_if_fail (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE, NULL);
+ g_return_val_if_fail (cairo_image_surface_get_width (surface) > 0, NULL);
+ g_return_val_if_fail (cairo_image_surface_get_height (surface) > 0, NULL);
+
+ bytes = g_bytes_new_with_free_func (cairo_image_surface_get_data (surface),
+ cairo_image_surface_get_height (surface)
+ * cairo_image_surface_get_stride (surface),
+ (GDestroyNotify) cairo_surface_destroy,
+ cairo_surface_reference (surface));
+
+ texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface),
+ cairo_image_surface_get_height (surface),
+ GDK_MEMORY_B8G8R8A8_PREMULTIPLIED,
+ bytes,
+ cairo_image_surface_get_stride (surface));
+
+ return texture;
+}
+
+
+/**
+ * shumate_vector_style_render:
+ * @self: a [class@VectorStyle]
+ *
+ * Renders a tile to a texture using this style.
+ *
+ * Returns: (transfer full): a [class@Gdk.Texture] containing the rendered tile
+ */
+GdkTexture *
+shumate_vector_style_render (ShumateVectorStyle *self, int size)
+{
+ GdkTexture *texture;
+ cairo_t *cr;
+ cairo_surface_t *surface;
+
+ g_return_val_if_fail (SHUMATE_IS_VECTOR_STYLE (self), NULL);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, size, size);
+ cr = cairo_create (surface);
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ texture = texture_new_for_surface (surface);
+
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+
+ return texture;
+}
+
diff --git a/shumate/shumate-vector-style.h b/shumate/shumate-vector-style.h
new file mode 100644
index 0000000..ac0d66f
--- /dev/null
+++ b/shumate/shumate-vector-style.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 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 <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define SHUMATE_TYPE_VECTOR_STYLE (shumate_vector_style_get_type())
+
+G_DECLARE_FINAL_TYPE (ShumateVectorStyle, shumate_vector_style, SHUMATE, VECTOR_STYLE, GObject)
+
+ShumateVectorStyle *shumate_vector_style_create (const char *style_json, GError **error);
+
+GdkTexture *shumate_vector_style_render (ShumateVectorStyle *self, int size);
+
+G_END_DECLS
+
diff --git a/shumate/shumate.h b/shumate/shumate.h
index 0486d1a..2809970 100644
--- a/shumate/shumate.h
+++ b/shumate/shumate.h
@@ -48,6 +48,8 @@
#include "shumate/shumate-memory-cache.h"
#include "shumate/shumate-file-cache.h"
+#include "shumate/shumate-vector-style.h"
+
#undef __SHUMATE_SHUMATE_H_INSIDE__
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]