[libchamplain] Renderers: Set surface on tiles



commit 7a14435544606f0e5a919dc69be9273ccf63792f
Author: Jonas Danielsson <jonas threetimestwo org>
Date:   Thu Nov 12 11:56:25 2015 +0100

    Renderers: Set surface on tiles
    
    https://bugzilla.gnome.org/show_bug.cgi?id=757350

 champlain/champlain-error-tile-renderer.c |    7 ++-
 champlain/champlain-image-renderer.c      |   68 ++++++++++++++++++++---------
 champlain/champlain-memphis-renderer.c    |    1 +
 3 files changed, 53 insertions(+), 23 deletions(-)
---
diff --git a/champlain/champlain-error-tile-renderer.c b/champlain/champlain-error-tile-renderer.c
index 1bbcbc0..10fbc9b 100644
--- a/champlain/champlain-error-tile-renderer.c
+++ b/champlain/champlain-error-tile-renderer.c
@@ -190,11 +190,14 @@ static gboolean
 redraw_tile (ClutterCanvas *canvas,
     cairo_t *cr,
     gint w,
-    gint h)
+    gint h,
+    ChamplainTile *tile)
 {
   cairo_pattern_t *pat;
   gint size = w;
   
+  champlain_exportable_set_surface (CHAMPLAIN_EXPORTABLE (tile), cairo_get_target (cr));
+
   /* draw a linear gray to white pattern */
   pat = cairo_pattern_create_linear (size / 2.0, 0.0, size, size / 2.0);
   cairo_pattern_add_color_stop_rgb (pat, 0, 0.686, 0.686, 0.686);
@@ -245,7 +248,7 @@ render (ChamplainRenderer *renderer, ChamplainTile *tile)
     {
       priv->error_canvas = clutter_canvas_new ();
       clutter_canvas_set_size (CLUTTER_CANVAS (priv->error_canvas), size, size);
-      g_signal_connect (priv->error_canvas, "draw", G_CALLBACK (redraw_tile), NULL);
+      g_signal_connect (priv->error_canvas, "draw", G_CALLBACK (redraw_tile), tile);
       clutter_content_invalidate (priv->error_canvas);
     }
 
diff --git a/champlain/champlain-image-renderer.c b/champlain/champlain-image-renderer.c
index e5484a1..2dea139 100644
--- a/champlain/champlain-image-renderer.c
+++ b/champlain/champlain-image-renderer.c
@@ -130,16 +130,40 @@ set_data (ChamplainRenderer *renderer, const gchar *data, guint size)
 }
 
 
-static void 
+static gboolean
+image_tile_draw_cb (ClutterCanvas   *canvas,
+    cairo_t *cr,
+    gint width,
+    gint height,
+    ChamplainTile *tile)
+{
+  cairo_surface_t *surface;
+
+  surface = champlain_exportable_get_surface (CHAMPLAIN_EXPORTABLE (tile));
+
+  /* Clear the drawing area */
+  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+  cairo_paint (cr);
+  cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+  cairo_set_source_surface (cr, surface, 0, 0);
+  cairo_paint(cr);
+
+  return FALSE;
+}
+
+static void
 image_rendered_cb (GInputStream *stream, GAsyncResult *res, RendererData *data)
 {
   ChamplainTile *tile = data->tile;
   gboolean error = TRUE;
-  GError *gerror = NULL;
   ClutterActor *actor = NULL;
   GdkPixbuf *pixbuf;
   ClutterContent *content;
   gfloat width, height;
+  cairo_surface_t *image_surface = NULL;
+  cairo_format_t format;
+  cairo_t *cr;
   
   pixbuf = gdk_pixbuf_new_from_stream_finish (res, NULL);
   if (!pixbuf)
@@ -148,29 +172,28 @@ image_rendered_cb (GInputStream *stream, GAsyncResult *res, RendererData *data)
       goto finish;
     }
   
-  /* Load the image into clutter */
-  content = clutter_image_new ();
-  if (!clutter_image_set_data (CLUTTER_IMAGE (content),
-          gdk_pixbuf_get_pixels (pixbuf),
-          gdk_pixbuf_get_has_alpha (pixbuf)
-            ? COGL_PIXEL_FORMAT_RGBA_8888
-            : COGL_PIXEL_FORMAT_RGB_888,
-          gdk_pixbuf_get_width (pixbuf),
-          gdk_pixbuf_get_height (pixbuf),
-          gdk_pixbuf_get_rowstride (pixbuf),
-          &gerror))
+  width = gdk_pixbuf_get_width (pixbuf);
+  height = gdk_pixbuf_get_height (pixbuf);
+  format = (gdk_pixbuf_get_has_alpha (pixbuf) ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24);
+  image_surface = cairo_image_surface_create (format, width, height);
+  if (cairo_surface_status (image_surface) != CAIRO_STATUS_SUCCESS)
     {
-      if (gerror)
-        {
-          g_warning ("Unable to transfer to clutter: %s", gerror->message);
-          g_error_free (gerror);
-        }
-
-      g_object_unref (content);
+      g_warning ("Bad surface");
       goto finish;
     }
+  cr = cairo_create (image_surface);
+  gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+  cairo_paint (cr);
+  champlain_exportable_set_surface (CHAMPLAIN_EXPORTABLE (tile), image_surface);
+  cairo_destroy (cr);
+
+  /* Load the image into clutter */
+  width = height = champlain_tile_get_size (tile);
+  content = clutter_canvas_new ();
+  clutter_canvas_set_size (CLUTTER_CANVAS (content), width, height);
+  g_signal_connect (content, "draw", G_CALLBACK (image_tile_draw_cb), tile);
+  clutter_content_invalidate (content);
 
-  clutter_content_get_preferred_size (content, &width, &height);
   actor = clutter_actor_new ();
   clutter_actor_set_size (actor, width, height);
   clutter_actor_set_content (actor, content);
@@ -190,6 +213,9 @@ finish:
   if (pixbuf)
     g_object_unref (pixbuf);
 
+  if (image_surface)
+    cairo_surface_destroy (image_surface);
+
   g_object_unref (data->renderer);
   g_object_unref (tile);
   g_object_unref (stream);
diff --git a/champlain/champlain-memphis-renderer.c b/champlain/champlain-memphis-renderer.c
index e4aed1e..1d1987f 100644
--- a/champlain/champlain-memphis-renderer.c
+++ b/champlain/champlain-memphis-renderer.c
@@ -334,6 +334,7 @@ tile_loaded_cb (gpointer worker_data)
      and we close the surface anyway */
   argb_to_rgba (cairo_image_surface_get_data (cst),
       cairo_image_surface_get_stride (cst) * cairo_image_surface_get_height (cst));
+  champlain_exportable_set_surface (CHAMPLAIN_EXPORTABLE (tile), cst);
 
   pixbuf = gdk_pixbuf_new_from_data (cairo_image_surface_get_data (cst),
         GDK_COLORSPACE_RGB, TRUE, 8, size, size,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]