summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Danielsson <jonas@threetimestwo.org>2015-11-12 11:57:37 +0100
committerJiří Techet <techet@gmail.com>2015-11-16 21:03:23 +0100
commitb6012f6a275e64b477319d926f80c4a5cb33add4 (patch)
tree5ad3b8d4534f6534d5b4892d85bb3ed6091ef906
parent7a14435544606f0e5a919dc69be9273ccf63792f (diff)
downloadlibchamplain-b6012f6a275e64b477319d926f80c4a5cb33add4.tar.gz
ChamplainView: Add champlain_view_to_surface
This function will export the current map view to a cairo_surface_t surface. https://bugzilla.gnome.org/show_bug.cgi?id=757350
-rw-r--r--champlain/champlain-view.c103
-rw-r--r--champlain/champlain-view.h2
2 files changed, 105 insertions, 0 deletions
diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c
index 2aa7436..537cda0 100644
--- a/champlain/champlain-view.c
+++ b/champlain/champlain-view.c
@@ -275,6 +275,9 @@ static void get_tile_bounds (ChamplainView *view,
guint *min_y,
guint *max_x,
guint *max_y);
+static gboolean tile_in_tile_map (ChamplainView *view,
+ gint tile_x,
+ gint tile_y);
static void
update_coords (ChamplainView *view,
@@ -1743,6 +1746,106 @@ champlain_view_zoom_out (ChamplainView *view)
}
+
+static void
+layers_to_surface (ChamplainView *view,
+ cairo_t *cr)
+{
+ ClutterActorIter iter;
+ ClutterActor *child;
+
+ clutter_actor_iter_init (&iter, view->priv->user_layers);
+ while (clutter_actor_iter_next (&iter, &child))
+ {
+ ChamplainLayer *layer = CHAMPLAIN_LAYER (child);
+ cairo_surface_t *surface;
+
+ if (!CHAMPLAIN_IS_EXPORTABLE (layer))
+ continue;
+
+ surface = champlain_exportable_get_surface (CHAMPLAIN_EXPORTABLE (layer));
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint(cr);
+ }
+}
+
+/**
+ * champlain_view_to_surface:
+ * @view: a #ChamplainView
+ * @include_layers: Set to %TRUE if you want to include layers
+ *
+ * Will generate a #cairo_surface_t that represents the current view
+ * of the map. Without any markers or layers. If the current #ChamplainRenderer
+ * used does not support this, this function will return %NULL.
+ *
+ * If @include_layers is set to %TRUE all layers that implement
+ * #ChamplainExportable will be included in the surface.
+ *
+ * The #ChamplainView also need to be in #CHAMPLAIN_STATE_DONE state.
+ *
+ * Returns: (transfer full): a #cairo_surface_t or %NULL on failure. Free with
+ * cairo_surface_destroy() when done.
+ */
+cairo_surface_t *
+champlain_view_to_surface (ChamplainView *view,
+ gboolean include_layers)
+{
+ DEBUG_LOG ()
+
+ g_return_val_if_fail (CHAMPLAIN_IS_VIEW (view), NULL);
+
+ ChamplainViewPrivate *priv = view->priv;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ ClutterActorIter iter;
+ ClutterActor *child;
+ gdouble width, height;
+
+ if (priv->state != CHAMPLAIN_STATE_DONE)
+ return NULL;
+
+ width = clutter_actor_get_width (CLUTTER_ACTOR (view));
+ height = clutter_actor_get_height (CLUTTER_ACTOR (view));
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ cr = cairo_create (surface);
+
+ clutter_actor_iter_init (&iter, priv->map_layer);
+ while (clutter_actor_iter_next (&iter, &child))
+ {
+ ChamplainTile *tile = CHAMPLAIN_TILE (child);
+ guint tile_x = champlain_tile_get_x (tile);
+ guint tile_y = champlain_tile_get_y (tile);
+ guint tile_size = champlain_tile_get_size (tile);
+
+ if (tile_in_tile_map (view, tile_x, tile_y))
+ {
+ cairo_surface_t *tile_surface;
+ double x, y;
+
+ tile_surface = champlain_exportable_get_surface (CHAMPLAIN_EXPORTABLE (tile));
+ if (!tile_surface)
+ {
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+ return NULL;
+ }
+ x = ((double) tile_x * tile_size) - priv->viewport_x;
+ y = ((double) tile_y * tile_size) - priv->viewport_y;
+ cairo_set_source_surface (cr,
+ tile_surface,
+ x, y);
+ cairo_paint(cr);
+ }
+ }
+
+ if (include_layers)
+ layers_to_surface (view, cr);
+
+ cairo_destroy (cr);
+ return surface;
+}
+
+
/**
* champlain_view_set_zoom_level:
* @view: a #ChamplainView
diff --git a/champlain/champlain-view.h b/champlain/champlain-view.h
index 7f92f3b..43eca16 100644
--- a/champlain/champlain-view.h
+++ b/champlain/champlain-view.h
@@ -133,6 +133,8 @@ void champlain_view_add_layer (ChamplainView *view,
ChamplainLayer *layer);
void champlain_view_remove_layer (ChamplainView *view,
ChamplainLayer *layer);
+cairo_surface_t * champlain_view_to_surface (ChamplainView *view,
+ gboolean include_layers);
guint champlain_view_get_zoom_level (ChamplainView *view);
guint champlain_view_get_min_zoom_level (ChamplainView *view);