[clutter/wip/actor-content] image-loader: Add size to async loading



commit 8d911ed98281473ff10efabe3733d757c0affe36
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Mon Apr 18 16:15:20 2011 +0100

    image-loader: Add size to async loading
    
    Allow specifying the loading size using the async API.

 clutter/clutter-image-loader.c                     |   18 ++++--
 clutter/clutter-image-loader.h                     |    6 ++
 clutter/clutter-image.c                            |    2 +
 .../image-loaders/clutter-image-loader-pixbuf.c    |   74 ++++++++++++++++++--
 4 files changed, 90 insertions(+), 10 deletions(-)
---
diff --git a/clutter/clutter-image-loader.c b/clutter/clutter-image-loader.c
index 9a667e3..b318475 100644
--- a/clutter/clutter-image-loader.c
+++ b/clutter/clutter-image-loader.c
@@ -219,6 +219,9 @@ _clutter_image_loader_load_stream (ClutterImageLoader     *loader,
  * clutter_image_loader_load_stream_async:
  * @loader: a #ClutterImageLoader
  * @stream: a #GInputStream
+ * @width: the width of the image, or -1
+ * @height: the height of the image, or -1
+ * @flags: flags to pass to the image loader
  * @cancellable: (allow-none): a #GCancellable or %NULL
  * @callback: (scope async): a callback
  * @user_data: closure for @callback
@@ -230,11 +233,14 @@ _clutter_image_loader_load_stream (ClutterImageLoader     *loader,
  * Since: 1.8
  */
 void
-_clutter_image_loader_load_stream_async (ClutterImageLoader  *loader,
-                                         GInputStream        *stream,
-                                         GCancellable        *cancellable,
-                                         GAsyncReadyCallback  callback,
-                                         gpointer             user_data)
+_clutter_image_loader_load_stream_async (ClutterImageLoader    *loader,
+                                         GInputStream          *stream,
+                                         gint                   width,
+                                         gint                   height,
+                                         ClutterImageLoadFlags  flags,
+                                         GCancellable          *cancellable,
+                                         GAsyncReadyCallback    callback,
+                                         gpointer               user_data)
 {
   g_return_if_fail (CLUTTER_IS_IMAGE_LOADER (loader));
   g_return_if_fail (G_IS_INPUT_STREAM (stream));
@@ -242,6 +248,8 @@ _clutter_image_loader_load_stream_async (ClutterImageLoader  *loader,
   g_return_if_fail (callback != NULL);
 
   CLUTTER_IMAGE_LOADER_GET_CLASS (loader)->load_stream_async (loader, stream,
+                                                              width, height,
+                                                              flags,
                                                               cancellable,
                                                               callback,
                                                               user_data);
diff --git a/clutter/clutter-image-loader.h b/clutter/clutter-image-loader.h
index acfc4d6..ece4db2 100644
--- a/clutter/clutter-image-loader.h
+++ b/clutter/clutter-image-loader.h
@@ -110,6 +110,9 @@ struct _ClutterImageLoaderClass
 
   void       (* load_stream_async)  (ClutterImageLoader     *loader,
                                      GInputStream           *stream,
+                                     gint                    width,
+                                     gint                    height,
+                                     ClutterImageLoadFlags   flags,
                                      GCancellable           *cancellable,
                                      GAsyncReadyCallback     callback,
                                      gpointer                user_data);
@@ -161,6 +164,9 @@ gboolean                _clutter_image_loader_load_stream               (Clutter
 
 void                    _clutter_image_loader_load_stream_async         (ClutterImageLoader     *loader,
                                                                          GInputStream           *stream,
+                                                                         gint                    width,
+                                                                         gint                    height,
+                                                                         ClutterImageLoadFlags   flags,
                                                                          GCancellable           *cancellable,
                                                                          GAsyncReadyCallback     callback,
                                                                          gpointer                user_data);
diff --git a/clutter/clutter-image.c b/clutter/clutter-image.c
index ad2fb68..568d6f1 100644
--- a/clutter/clutter-image.c
+++ b/clutter/clutter-image.c
@@ -666,6 +666,8 @@ async_read_complete (GObject      *gobject,
                 G_OBJECT_TYPE_NAME (closure->loader));
   _clutter_image_loader_load_stream_async (closure->loader,
                                            closure->stream,
+                                           -1, -1,
+                                           CLUTTER_IMAGE_LOAD_NONE,
                                            closure->cancellable,
                                            async_load_complete,
                                            closure);
diff --git a/clutter/image-loaders/clutter-image-loader-pixbuf.c b/clutter/image-loaders/clutter-image-loader-pixbuf.c
index e5e8e81..543aee6 100644
--- a/clutter/image-loaders/clutter-image-loader-pixbuf.c
+++ b/clutter/image-loaders/clutter-image-loader-pixbuf.c
@@ -158,6 +158,9 @@ typedef struct {
   GByteArray *content;
   gsize pos;
   GError *error;
+  gint width;
+  gint height;
+  guint preserve_aspect_ratio : 1;
 } AsyncLoadClosure;
 
 static void
@@ -193,6 +196,55 @@ async_load_closure_free (gpointer data)
 }
 
 static void
+on_loader_size_prepared (GdkPixbufLoader  *loader,
+                         gint              width,
+                         gint              height,
+                         AsyncLoadClosure *closure)
+{
+  if (closure->preserve_aspect_ratio)
+    {
+      if (closure->width > 0 || closure->height > 0)
+        {
+          if (closure->width < 0)
+            {
+              width = width * (double) closure->height / (double) height;
+              height = closure->height;
+            }
+          else if (closure->height < 0)
+            {
+              height = height * (double) closure->width / (double) width;
+              width = closure->width;
+            }
+          else if (((double) height * closure->width) > ((double) width * closure->height))
+            {
+              width = 0.5
+                    + (double) width * (double) closure->height / height;
+              height = closure->height;
+            }
+          else
+            {
+              height = 0.5
+                     + (double) height * (double) closure->width / width;
+              width = closure->width;
+            }
+        }
+    }
+  else
+    {
+      if (closure->width > 0)
+        width = closure->width;
+
+      if (closure->height > 0)
+        height = closure->height;
+    }
+
+  width = MAX (width, 1);
+  height = MAX (height, 1);
+
+  gdk_pixbuf_loader_set_size (loader, width, height);
+}
+
+static void
 load_stream_data_read_callback (GObject      *gobject,
                                 GAsyncResult *result,
                                 gpointer      user_data)
@@ -257,17 +309,24 @@ load_stream_data_read_callback (GObject      *gobject,
 }
 
 static void
-clutter_image_loader_pixbuf_load_stream_async (ClutterImageLoader *loader,
-                                               GInputStream       *stream,
-                                               GCancellable       *cancellable,
-                                               GAsyncReadyCallback callback,
-                                               gpointer            user_data)
+clutter_image_loader_pixbuf_load_stream_async (ClutterImageLoader    *loader,
+                                               GInputStream          *stream,
+                                               gint                   width,
+                                               gint                   height,
+                                               ClutterImageLoadFlags  flags,
+                                               GCancellable          *cancellable,
+                                               GAsyncReadyCallback    callback,
+                                               gpointer               user_data)
 {
   AsyncLoadClosure *closure;
 
   closure = g_new0 (AsyncLoadClosure, 1);
   closure->loader = g_object_ref (loader);
   closure->stream = g_object_ref (stream);
+  closure->width = width;
+  closure->height = height;
+  closure->preserve_aspect_ratio =
+    (flags & CLUTTER_IMAGE_LOAD_PRESERVE_ASPECT) != 0;
   closure->cancellable = cancellable != NULL
                        ? g_object_ref (cancellable)
                        : NULL;
@@ -278,6 +337,11 @@ clutter_image_loader_pixbuf_load_stream_async (ClutterImageLoader *loader,
   closure->pos = 0;
 
   g_byte_array_set_size (closure->content, closure->pos + GET_DATA_BLOCK_SIZE);
+
+  g_signal_connect (closure->pixbuf_loader, "size-prepared",
+                    G_CALLBACK (on_loader_size_prepared),
+                    closure);
+
   g_input_stream_read_async (stream, closure->content->data + closure->pos,
                              GET_DATA_BLOCK_SIZE, 0,
                              closure->cancellable,



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