[clutter/wip/actor-content: 32/33] image: Add loading at scale methods
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/wip/actor-content: 32/33] image: Add loading at scale methods
- Date: Wed, 18 May 2011 11:13:06 +0000 (UTC)
commit 39896e9a39aafd3da438d67e33425b57f7109f33
Author: Emmanuele Bassi <ebassi linux intel com>
Date: Tue Apr 19 14:13:18 2011 +0100
image: Add loading at scale methods
Allow loading image data from a GFile using a specific size, with or
without preserving the aspect ratio.
clutter/clutter-image.c | 152 ++++++++++++++++++++++++++++++---
clutter/clutter-image.h | 73 ++++++++++------
tests/conform/test-conform-main.c | 1 +
tests/conform/test-image.c | 37 ++++++++
tests/interactive/test-border-image.c | 9 ++-
5 files changed, 228 insertions(+), 44 deletions(-)
---
diff --git a/clutter/clutter-image.c b/clutter/clutter-image.c
index fd97797..124067b 100644
--- a/clutter/clutter-image.c
+++ b/clutter/clutter-image.c
@@ -428,16 +428,28 @@ clutter_image_load_from_data (ClutterImage *image,
return TRUE;
}
-
/**
- * clutter_image_load:
+ * clutter_image_load_at_scale:
* @image: a #ClutterImage
* @gfile: a #GFile
+ * @width: the width of the image, or -1 to use the size of the image
+ * data; if @flags contains %CLUTTER_IMAGE_LOAD_PRESERVE_ASPECT and
+ * the @width is -1 then the width of the image will be set depending
+ * on the value specified in @height
+ * @height: the height of the image, or -1 to use the size of the image
+ * data; if @flags contains %CLUTTER_IMAGE_LOAD_PRESERVE_ASPETC and
+ * the @height is -1 then the height of the image will be set depending
+ * on the value specified in @width
+ * @flags: flags to modify the image loading operations
* @cancellable: (allow-none): a #GCancellable, or %NULL
* @error: return location for a #GError, or %NULL
*
* Synchronously loads image data available to the location pointed
- * by @gfile.
+ * by @gfile, scaling it to match @width and @height (with potential
+ * optimizations depending on the image format).
+ *
+ * This function should be used to load potentially large images when
+ * the final, on-screen size is known.
*
* This function will block the execution until the image data has
* been loaded, or an error was encountered.
@@ -452,10 +464,13 @@ clutter_image_load_from_data (ClutterImage *image,
* Since: 1.8
*/
gboolean
-clutter_image_load (ClutterImage *image,
- GFile *gfile,
- GCancellable *cancellable,
- GError **error)
+clutter_image_load_at_scale (ClutterImage *image,
+ GFile *gfile,
+ gint width,
+ gint height,
+ ClutterImageLoadFlags flags,
+ GCancellable *cancellable,
+ GError **error)
{
ClutterImageLoader *loader;
ClutterImagePrivate *priv;
@@ -482,8 +497,8 @@ clutter_image_load (ClutterImage *image,
res = _clutter_image_loader_load_stream (loader,
G_INPUT_STREAM (stream),
- -1, -1,
- CLUTTER_IMAGE_LOAD_NONE,
+ width, height,
+ flags,
cancellable,
error);
if (!res)
@@ -548,11 +563,50 @@ clutter_image_load (ClutterImage *image,
return TRUE;
}
+/**
+ * clutter_image_load:
+ * @image: a #ClutterImage
+ * @gfile: a #GFile
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Synchronously loads image data available to the location pointed
+ * by @gfile.
+ *
+ * This function will block the execution until the image data has
+ * been loaded, or an error was encountered.
+ *
+ * It is possible to cancel the loading by using the @cancellable
+ * instance.
+ *
+ * In case of error, the #GError structure will be filled accordingly.
+ *
+ * Return value: %TRUE if the loading was successful, and %FALSE otherwise
+ *
+ * Since: 1.8
+ */
+gboolean
+clutter_image_load (ClutterImage *image,
+ GFile *gfile,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return clutter_image_load_at_scale (image, gfile,
+ -1, -1,
+ CLUTTER_IMAGE_LOAD_NONE,
+ cancellable,
+ error);
+}
+
typedef struct {
ClutterImageLoader *loader;
ClutterImage *image;
+ gint width;
+ gint height;
+ ClutterImageLoadFlags flags;
GAsyncReadyCallback callback;
gpointer user_data;
+ gpointer tag;
GInputStream *stream;
GError *error;
GCancellable *cancellable;
@@ -603,7 +657,7 @@ async_load_complete (GObject *gobject,
res = g_simple_async_result_new (G_OBJECT (closure->image),
closure->callback,
closure->user_data,
- clutter_image_load_async);
+ closure->tag);
g_simple_async_result_set_op_res_gpointer (res,
closure,
@@ -656,14 +710,81 @@ 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->width,
+ closure->height,
+ closure->flags,
closure->cancellable,
async_load_complete,
closure);
}
/**
+ * clutter_image_load_at_scale_async:
+ * @image: a #ClutterImage
+ * @gfile: a #GFile
+ * @width: the width of the image, or -1 to use the size of the image
+ * data; if @flags contains %CLUTTER_IMAGE_LOAD_PRESERVE_ASPECT and
+ * the @width is -1 then the width of the image will be set depending
+ * on the value specified in @height
+ * @height: the height of the image, or -1 to use the size of the image
+ * data; if @flags contains %CLUTTER_IMAGE_LOAD_PRESERVE_ASPETC and
+ * the @height is -1 then the height of the image will be set depending
+ * on the value specified in @width
+ * @flags: flags to modify the image loading operations
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @callback: (scope async): a callback function
+ * @user_data: closure to pass to @callback
+ *
+ * Asynchronously loads image data from the resource pointed by @gfile
+ * into @image.
+ *
+ * When the image data has been loaded the @callback function will be
+ * called; it is the responsability of the developer to call
+ * clutter_image_load_finish() inside @callback.
+ *
+ * Since: 1.8
+ */
+void
+clutter_image_load_at_scale_async (ClutterImage *image,
+ GFile *gfile,
+ gint width,
+ gint height,
+ ClutterImageLoadFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ AsyncReadClosure *closure;
+ ClutterImageLoader *loader;
+
+ g_return_if_fail (CLUTTER_IS_IMAGE (image));
+ g_return_if_fail (G_IS_FILE (gfile));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (callback != NULL);
+
+ loader = _clutter_image_loader_new ();
+ if (loader == NULL)
+ return;
+
+ closure = g_new0 (AsyncReadClosure, 1);
+ closure->loader = loader;
+ closure->image = g_object_ref (image);
+ closure->width = width;
+ closure->height = height;
+ closure->flags = flags;
+ closure->tag = clutter_image_load_at_scale_async;
+ closure->cancellable = (cancellable != NULL)
+ ? g_object_ref (cancellable)
+ : NULL;
+ closure->callback = callback;
+ closure->user_data = user_data;
+
+ g_file_read_async (gfile, G_PRIORITY_DEFAULT, cancellable,
+ async_read_complete,
+ closure);
+}
+
+/**
* clutter_image_load_async:
* @image: a #ClutterImage
* @gfile: a #GFile
@@ -702,6 +823,10 @@ clutter_image_load_async (ClutterImage *image,
closure = g_new0 (AsyncReadClosure, 1);
closure->loader = loader;
closure->image = g_object_ref (image);
+ closure->width = -1;
+ closure->height = -1;
+ closure->flags = CLUTTER_IMAGE_LOAD_NONE;
+ closure->tag = clutter_image_load_async;
closure->cancellable = (cancellable != NULL)
? g_object_ref (cancellable)
: NULL;
@@ -746,7 +871,8 @@ clutter_image_load_finish (ClutterImage *image,
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == clutter_image_load_async);
+ g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == clutter_image_load_async ||
+ g_simple_async_result_get_source_tag (simple) == clutter_image_load_at_scale_async);
closure = g_simple_async_result_get_op_res_gpointer (simple);
if (closure->error != NULL)
diff --git a/clutter/clutter-image.h b/clutter/clutter-image.h
index 48dd16a..ac504ae 100644
--- a/clutter/clutter-image.h
+++ b/clutter/clutter-image.h
@@ -124,34 +124,51 @@ struct _ClutterImageClass
GQuark clutter_image_error_quark (void);
GType clutter_image_get_type (void) G_GNUC_CONST;
-ClutterImage * clutter_image_new (void);
-
-gboolean clutter_image_load_from_data (ClutterImage *image,
- const guchar *data,
- CoglPixelFormat format,
- gint width,
- gint height,
- gint rowstride,
- GError **error);
-
-gboolean clutter_image_load (ClutterImage *image,
- GFile *gfile,
- GCancellable *cancellable,
- GError **error);
-void clutter_image_load_async (ClutterImage *image,
- GFile *gfile,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean clutter_image_load_finish (ClutterImage *image,
- GAsyncResult *res,
- GError **error);
-
-void clutter_image_get_size (ClutterImage *image,
- gint *width,
- gint *height);
-
-CoglHandle clutter_image_get_cogl_texture (ClutterImage *image);
+ClutterImage * clutter_image_new (void);
+
+gboolean clutter_image_load_from_data (ClutterImage *image,
+ const guchar *data,
+ CoglPixelFormat format,
+ gint width,
+ gint height,
+ gint rowstride,
+ GError **error);
+
+gboolean clutter_image_load (ClutterImage *image,
+ GFile *gfile,
+ GCancellable *cancellable,
+ GError **error);
+gboolean clutter_image_load_at_scale (ClutterImage *image,
+ GFile *gfile,
+ gint width,
+ gint height,
+ ClutterImageLoadFlags flags,
+ GCancellable *cancellable,
+ GError **error);
+
+void clutter_image_load_async (ClutterImage *image,
+ GFile *gfile,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+void clutter_image_load_at_scale_async (ClutterImage *image,
+ GFile *gfile,
+ gint width,
+ gint height,
+ ClutterImageLoadFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean clutter_image_load_finish (ClutterImage *image,
+ GAsyncResult *res,
+ GError **error);
+
+void clutter_image_get_size (ClutterImage *image,
+ gint *width,
+ gint *height);
+
+CoglHandle clutter_image_get_cogl_texture (ClutterImage *image);
G_END_DECLS
diff --git a/tests/conform/test-conform-main.c b/tests/conform/test-conform-main.c
index a6f44d6..79fb1a3 100644
--- a/tests/conform/test-conform-main.c
+++ b/tests/conform/test-conform-main.c
@@ -211,6 +211,7 @@ main (int argc, char **argv)
TEST_CONFORM_SIMPLE ("/behaviours", test_behaviours);
TEST_CONFORM_SIMPLE ("/image", image_sync_loading);
+ TEST_CONFORM_SIMPLE ("/image", image_sync_loading_at_scale);
TEST_CONFORM_SIMPLE ("/image", image_async_loading);
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_object);
diff --git a/tests/conform/test-image.c b/tests/conform/test-image.c
index 2a24ec8..8e905af 100644
--- a/tests/conform/test-image.c
+++ b/tests/conform/test-image.c
@@ -35,6 +35,43 @@ image_sync_loading (void)
g_object_unref (image);
}
+void
+image_sync_loading_at_scale (void)
+{
+ ClutterImage *image = clutter_image_new ();
+ GError *error;
+ GFile *gfile;
+ gint width, height;
+ gboolean res;
+
+ g_assert (CLUTTER_IS_IMAGE (image));
+
+ gfile = g_file_new_for_path (TESTS_DATADIR "/redhand.png");
+
+ width = height = 0;
+ error = NULL;
+
+ res = clutter_image_load_at_scale (image, gfile,
+ 64, 64, CLUTTER_IMAGE_LOAD_NONE,
+ NULL,
+ &error);
+
+ if (g_test_verbose() && error != NULL)
+ g_print ("Unexpected error: %s\n", error->message);
+
+ g_assert (error == NULL);
+ g_assert (res);
+
+ clutter_image_get_size (image, &width, &height);
+ g_assert_cmpint (width, ==, 64);
+ g_assert_cmpint (height, ==, 64);
+
+ g_assert (clutter_image_get_cogl_texture (image) != COGL_INVALID_HANDLE);
+
+ g_object_unref (gfile);
+ g_object_unref (image);
+}
+
static void
async_load_done_cb (GObject *gobject,
GAsyncResult *result,
diff --git a/tests/interactive/test-border-image.c b/tests/interactive/test-border-image.c
index 3eec8ab..3ec323d 100644
--- a/tests/interactive/test-border-image.c
+++ b/tests/interactive/test-border-image.c
@@ -72,9 +72,12 @@ test_border_image_main (int argc,
image = CLUTTER_CONTENT (clutter_image_new ());
gfile = g_file_new_for_path (TESTS_DATADIR "/redhand.png");
- clutter_image_load_async (CLUTTER_IMAGE (image), gfile, NULL,
- load_async_done,
- NULL);
+ clutter_image_load_at_scale_async (CLUTTER_IMAGE (image), gfile,
+ RECT_SIZE, RECT_SIZE,
+ CLUTTER_IMAGE_LOAD_NONE,
+ NULL,
+ load_async_done,
+ NULL);
g_object_unref (gfile);
n_cols = (STAGE_WIDTH - (2 * PADDING)) / (RECT_SIZE + (2 * SPACING));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]