[gnome-shell] StTextureCache: add api to load image to cairo surface



commit f7ab90b93b88b7e4ad08e56614cd0aaf25160697
Author: Ray Strode <rstrode redhat com>
Date:   Fri Dec 10 17:15:39 2010 -0500

    StTextureCache: add api to load image to cairo surface
    
    Loading a pixbuf in a way that cairo can use it is a
    pretty involved process that involves a lot of code, and pixel
    fiddling.
    
    This commit adds the mechanism to StTextureCache so we can reuse
    the existing pixbuf handling code there, and also get caching.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=636976

 src/st/st-texture-cache.c |   98 +++++++++++++++++++++++++++++++++++++++++++++
 src/st/st-texture-cache.h |    3 +
 2 files changed, 101 insertions(+), 0 deletions(-)
---
diff --git a/src/st/st-texture-cache.c b/src/st/st-texture-cache.c
index c7906ab..52ce02e 100644
--- a/src/st/st-texture-cache.c
+++ b/src/st/st-texture-cache.c
@@ -30,6 +30,7 @@
 
 #define CACHE_PREFIX_GICON "gicon:"
 #define CACHE_PREFIX_URI "uri:"
+#define CACHE_PREFIX_URI_FOR_CAIRO "uri-for-cairo:"
 #define CACHE_PREFIX_THUMBNAIL_URI "thumbnail-uri:"
 #define CACHE_PREFIX_RAW_CHECKSUM "raw-checksum:"
 #define CACHE_PREFIX_COMPRESSED_CHECKSUM "compressed-checksum:"
@@ -798,6 +799,27 @@ pixbuf_to_cogl_handle (GdkPixbuf *pixbuf)
                                      gdk_pixbuf_get_pixels (pixbuf));
 }
 
+static cairo_surface_t *
+pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
+{
+  cairo_surface_t *dummy_surface;
+  cairo_pattern_t *pattern;
+  cairo_surface_t *surface;
+  cairo_t *cr;
+
+  dummy_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+
+  cr = cairo_create (dummy_surface);
+  gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+  pattern = cairo_get_source (cr);
+  cairo_pattern_get_surface (pattern, &surface);
+  cairo_surface_reference (surface);
+  cairo_destroy (cr);
+  cairo_surface_destroy (dummy_surface);
+
+  return surface;
+}
+
 static GdkPixbuf *
 load_pixbuf_fallback(AsyncTextureLoadData *data)
 {
@@ -1504,6 +1526,45 @@ out:
   return texdata;
 }
 
+static cairo_surface_t *
+st_texture_cache_load_uri_sync_to_cairo_surface (StTextureCache        *cache,
+                                                 StTextureCachePolicy   policy,
+                                                 const gchar           *uri,
+                                                 int                    available_width,
+                                                 int                    available_height,
+                                                 GError               **error)
+{
+  cairo_surface_t *surface;
+  GdkPixbuf *pixbuf;
+  char *key;
+
+  key = g_strconcat (CACHE_PREFIX_URI_FOR_CAIRO, uri, NULL);
+
+  surface = g_hash_table_lookup (cache->priv->keyed_cache, key);
+
+  if (surface == NULL)
+    {
+      pixbuf = impl_load_pixbuf_file (uri, available_width, available_height, error);
+      if (!pixbuf)
+        goto out;
+
+      surface = pixbuf_to_cairo_surface (pixbuf);
+      g_object_unref (pixbuf);
+
+      if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
+        {
+          cairo_surface_reference (surface);
+          g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), surface);
+        }
+    }
+  else
+    cairo_surface_reference (surface);
+
+out:
+  g_free (key);
+  return surface;
+}
+
 /**
  * st_texture_cache_load_uri_sync:
  *
@@ -1583,6 +1644,43 @@ st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
 }
 
 /**
+ * st_texture_cache_load_file_to_cairo_surface:
+ * @cache: A #StTextureCache
+ * @file_path: Path to a file in supported image format
+ *
+ * This function synchronously loads the given file path
+ * into a cairo surface.  On error, a warning is emitted
+ * and %NULL is returned.
+ *
+ * Returns: (transfer full): a new #cairo_surface_t *
+ */
+cairo_surface_t *
+st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache,
+                                             const gchar    *file_path)
+{
+  cairo_surface_t *surface;
+  GFile *file;
+  char *uri;
+  GError *error = NULL;
+
+  file = g_file_new_for_path (file_path);
+  uri = g_file_get_uri (file);
+
+  surface = st_texture_cache_load_uri_sync_to_cairo_surface (cache, ST_TEXTURE_CACHE_POLICY_FOREVER,
+                                                             uri, -1, -1, &error);
+  g_object_unref (file);
+  g_free (uri);
+
+  if (surface == NULL)
+    {
+      g_warning ("Failed to load %s: %s", file_path, error->message);
+      g_clear_error (&error);
+      return NULL;
+    }
+  return surface;
+}
+
+/**
  * st_texture_cache_load_file_simple:
  * @cache: A #StTextureCache
  * @file_path: Filesystem path
diff --git a/src/st/st-texture-cache.h b/src/st/st-texture-cache.h
index 4f1a482..5f1e701 100644
--- a/src/st/st-texture-cache.h
+++ b/src/st/st-texture-cache.h
@@ -119,6 +119,9 @@ ClutterActor *st_texture_cache_load_uri_sync (StTextureCache       *cache,
 CoglHandle    st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
                                                           const gchar    *file_path);
 
+cairo_surface_t *st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache,
+                                                              const gchar    *file_path);
+
 ClutterActor *st_texture_cache_load_file_simple (StTextureCache *cache,
                                                  const gchar    *file_path);
 



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