From 234484a78b0cd965e5706d00543caac2a49ea38a Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Thu, 2 Jul 2015 15:33:31 +0900 Subject: Evas.Image: Rewrite Eo API data_set() - Merge data_set() and data_copy_set() by passing a copy flag to the function call. (I have just copy/pasted the implementation code to avoid mistakes) - Add image properties to the data_set() function: width, height, cspace, stride (optional) NOTE: I did not add the alpha flag. --- src/lib/evas/Evas_Legacy.h | 43 ++++++- src/lib/evas/canvas/evas_image.eo | 49 ++------ src/lib/evas/canvas/evas_object_image.c | 212 ++++++++++++++++++-------------- 3 files changed, 171 insertions(+), 133 deletions(-) diff --git a/src/lib/evas/Evas_Legacy.h b/src/lib/evas/Evas_Legacy.h index 2f6fa5563c..79bc007b44 100644 --- a/src/lib/evas/Evas_Legacy.h +++ b/src/lib/evas/Evas_Legacy.h @@ -2892,7 +2892,6 @@ image) to start drawing from. EAPI void evas_object_image_fill_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h); /** - * * Sets the size of the given image object. * * This function will scale down or crop the image so that it is @@ -2907,7 +2906,6 @@ EAPI void evas_object_image_fill_get(const Evas_Object *obj, Evas_Coord *x, Evas EAPI void evas_object_image_size_set(Evas_Object *obj, int w, int h); /** - * * Retrieves the size of the given image object. * * See @ref evas_object_image_size_set() for more details. @@ -2917,6 +2915,47 @@ EAPI void evas_object_image_size_set(Evas_Object *obj, int w, int h); */ EAPI void evas_object_image_size_get(const Evas_Object *obj, int *w, int *h); +// to be deprecated with better eo api +/** + * Replaces the raw image data of the given image object. + * + * This function lets the application replace an image object's + * internal pixel buffer with an user-allocated one. For best results, + * you should generally first call evas_object_image_size_set() with + * the width and height for the new buffer. + * + * This call is best suited for when you will be using image data with + * different dimensions than the existing image data, if any. If you + * only need to modify the existing image in some fashion, then using + * evas_object_image_data_get() is probably what you are after. + * + * Note that the caller is responsible for freeing the buffer when + * finished with it, as user-set image data will not be automatically + * freed when the image object is deleted. + * + * See @ref evas_object_image_data_get() for more details. + * + * @param[in] data The raw data to replace. + */ +EAPI void evas_object_image_data_copy_set(Evas_Object *obj, void *data); + +// to be depracted with better eo api +/** + * Sets the raw image data of the given image object. + * + * Note that the raw data must be of the same size (see + * evas_object_image_size_set(), which has to be called @b before this + * one) and colorspace (see evas_object_image_colorspace_set()) of the + * image. If data is @c NULL, the current image data will be + * freed. Naturally, if one does not set an image object's data + * manually, it will still have one, allocated by Evas. + * + * @see evas_object_image_data_get() + * + * @param[in] data The raw data, or @c NULL. + */ +EAPI void evas_object_image_data_set(Evas_Object *obj, void *data); + /* * Converts the raw image data of the given image object to the * specified colorspace. diff --git a/src/lib/evas/canvas/evas_image.eo b/src/lib/evas/canvas/evas_image.eo index 53c9076bcf..cdd06595ac 100644 --- a/src/lib/evas/canvas/evas_image.eo +++ b/src/lib/evas/canvas/evas_image.eo @@ -578,31 +578,6 @@ class Evas.Image (Evas.Object, Efl.File, Efl.Image, Efl.Gfx.Fill, Efl.Gfx.View, data: void *; /*@ The data pointer to be passed to @a func. */ } } - @property data_copy { - set { - /*@ - Replaces the raw image data of the given image object. - - This function lets the application replace an image object's - internal pixel buffer with an user-allocated one. For best results, - you should generally first call evas_object_image_size_set() with - the width and height for the new buffer. - - This call is best suited for when you will be using image data with - different dimensions than the existing image data, if any. If you - only need to modify the existing image in some fashion, then using - evas_object_image_data_get() is probably what you are after. - - Note that the caller is responsible for freeing the buffer when - finished with it, as user-set image data will not be automatically - freed when the image object is deleted. - - See @ref evas_object_image_data_get() for more details. */ - } - values { - data: void *; /*@ The raw data to replace. */ - } - } @property animated_frame { set { /*@ @@ -827,20 +802,20 @@ class Evas.Image (Evas.Object, Efl.File, Efl.Image, Efl.Gfx.Fill, Efl.Gfx.View, } } data_set { - /*@ - Sets the raw image data of the given image object. - - Note that the raw data must be of the same size (see - evas_object_image_size_set(), which has to be called @b before this - one) and colorspace (see evas_object_image_colorspace_set()) of the - image. If data is @c NULL, the current image data will be - freed. Naturally, if one does not set an image object's data - manually, it will still have one, allocated by Evas. - - @see evas_object_image_data_get() */ + [[Sets the raw image data of the given image object. + If data is NULL, the current image data will be freed and + Evas will allocate an empty surface. + ]] + legacy: null; /* legacy has a different signature */ params { - @in data: void *; /*@ The raw data, or @c NULL. */ + @in data: void *; [[The raw data, or NULL.]] + @in width: int; [[Image width in pixels.]] + @in height: int; [[Image height in pixels.]] + @in cspace: Evas.Colorspace; [[Colorspace of the pixel data.]] + @in copy: bool; [[If true, Evas will copy the data, + otherwise the client must keep the pointer alive.]] + @in stride: int; [[Image stride in bytes (optional).]] } } data_get @const { diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c index aee6260152..fae62fe2fe 100644 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -1247,47 +1247,124 @@ evas_object_image_data_convert(Evas_Object *eo_obj, Evas_Colorspace to_cspace) } EOLIAN static void -_evas_image_data_set(Eo *eo_obj, Evas_Image_Data *o, void *data) +_evas_image_data_set(Eo *eo_obj, Evas_Image_Data *o, + void *data, int width, int height, Evas_Colorspace cspace, + Eina_Bool copy, int stride) { Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); void *p_data; Eina_Bool resize_call = EINA_FALSE; - evas_object_async_block(obj); evas_render_rendering_wait(obj->layer->evas); _evas_object_image_cleanup(eo_obj, obj, o); p_data = o->engine_data; - if (data) + + eo_do(eo_obj, + efl_gfx_view_size_set(width, height); + evas_obj_image_colorspace_set(cspace); + ); + if (data && ((width <= 0) || (height <= 0) || + (width != o->cur->image.w) || (height != o->cur->image.h))) { - if (o->engine_data) + ERR("The image dimensions are invalid: %dx%d", width, height); + return; + } + + if (!copy || !data) + { + if (data) { - o->engine_data = ENFN->image_data_put(ENDT, o->engine_data, data); + if (o->engine_data) + { + o->engine_data = ENFN->image_data_put(ENDT, o->engine_data, data); + } + else + { + o->engine_data = ENFN->image_new_from_data(ENDT, + o->cur->image.w, + o->cur->image.h, + data, + o->cur->has_alpha, + o->cur->cspace); + } + if (o->engine_data) + { + if (ENFN->image_scale_hint_set) + ENFN->image_scale_hint_set(ENDT, o->engine_data, o->scale_hint); + + if (ENFN->image_content_hint_set) + ENFN->image_content_hint_set(ENDT, o->engine_data, o->content_hint); + + if (!stride) + { + if (ENFN->image_stride_get) + ENFN->image_stride_get(ENDT, o->engine_data, &stride); + else + stride = o->cur->image.w * 4; + } + + if (o->cur->image.stride != stride) + { + EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) + state_write->image.stride = stride; + EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); + } + } + o->written = EINA_TRUE; } else { - o->engine_data = ENFN->image_new_from_data(ENDT, - o->cur->image.w, - o->cur->image.h, - data, - o->cur->has_alpha, - o->cur->cspace); + if (o->engine_data) + ENFN->image_free(ENDT, o->engine_data); + o->load_error = EVAS_LOAD_ERROR_NONE; + if ((o->cur->image.w != 0) || (o->cur->image.h != 0)) + resize_call = EINA_TRUE; + + EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) + { + state_write->image.w = 0; + state_write->image.h = 0; + state_write->image.stride = 0; + } + EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); + + o->engine_data = NULL; + } + /* FIXME - in engine call above + if (o->engine_data) + o->engine_data = ENFN->image_alpha_set(ENDT, o->engine_data, o->cur->has_alpha); + */ + if (o->pixels_checked_out > 0) o->pixels_checked_out--; + if (p_data != o->engine_data) + { + EVAS_OBJECT_WRITE_IMAGE_FREE_FILE_AND_KEY(o); + o->pixels_checked_out = 0; } + if (resize_call) evas_object_inform_call_image_resize(eo_obj); + } + else // copy && data + { + if (o->engine_data) + ENFN->image_free(ENDT, o->engine_data); + o->engine_data = ENFN->image_new_from_copied_data + (ENDT, o->cur->image.w, o->cur->image.h, data, + o->cur->has_alpha, o->cur->cspace); if (o->engine_data) { - int stride = 0; - + o->engine_data = ENFN->image_alpha_set(ENDT, o->engine_data, o->cur->has_alpha); if (ENFN->image_scale_hint_set) ENFN->image_scale_hint_set(ENDT, o->engine_data, o->scale_hint); - if (ENFN->image_content_hint_set) ENFN->image_content_hint_set(ENDT, o->engine_data, o->content_hint); - - if (ENFN->image_stride_get) - ENFN->image_stride_get(ENDT, o->engine_data, &stride); - else - stride = o->cur->image.w * 4; + if (!stride) + { + if (ENFN->image_stride_get) + ENFN->image_stride_get(ENDT, o->engine_data, &stride); + else + stride = o->cur->image.w * 4; + } if (o->cur->image.stride != stride) { @@ -1295,38 +1372,29 @@ _evas_image_data_set(Eo *eo_obj, Evas_Image_Data *o, void *data) state_write->image.stride = stride; EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); } - } - o->written = EINA_TRUE; - } - else - { - if (o->engine_data) - ENFN->image_free(ENDT, o->engine_data); - o->load_error = EVAS_LOAD_ERROR_NONE; - if ((o->cur->image.w != 0) || (o->cur->image.h != 0)) - resize_call = EINA_TRUE; - - EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) - { - state_write->image.w = 0; - state_write->image.h = 0; - state_write->image.stride = 0; + o->written = EINA_TRUE; } - EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); - - o->engine_data = NULL; - } -/* FIXME - in engine call above - if (o->engine_data) - o->engine_data = ENFN->image_alpha_set(ENDT, o->engine_data, o->cur->has_alpha); -*/ - if (o->pixels_checked_out > 0) o->pixels_checked_out--; - if (p_data != o->engine_data) - { - EVAS_OBJECT_WRITE_IMAGE_FREE_FILE_AND_KEY(o); o->pixels_checked_out = 0; + EVAS_OBJECT_WRITE_IMAGE_FREE_FILE_AND_KEY(o); } - if (resize_call) evas_object_inform_call_image_resize(eo_obj); +} + +EAPI void +evas_object_image_data_set(Evas_Object *eo_obj, void *data) +{ + Evas_Image_Data *o = eo_data_scope_get(eo_obj, MY_CLASS); + + _evas_image_data_set(eo_obj, o, data, o->cur->image.w, o->cur->image.h, + o->cur->cspace, EINA_FALSE, 0); +} + +EAPI void +evas_object_image_data_copy_set(Evas_Object *eo_obj, void *data) +{ + Evas_Image_Data *o = eo_data_scope_get(eo_obj, MY_CLASS); + + _evas_image_data_set(eo_obj, o, data, o->cur->image.w, o->cur->image.h, + o->cur->cspace, EINA_TRUE, 0); } EOLIAN static void* @@ -1437,51 +1505,6 @@ _evas_image_preload_cancel(Eo *eo_obj, Evas_Image_Data *_pd EINA_UNUSED) _image_preload_internal(eo_obj, _pd, EINA_TRUE); } -EOLIAN static void -_evas_image_data_copy_set(Eo *eo_obj, Evas_Image_Data *o, void *data) -{ - Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); - - if (!data) return; - evas_object_async_block(obj); - _evas_object_image_cleanup(eo_obj, obj, o); - if ((o->cur->image.w <= 0) || - (o->cur->image.h <= 0)) return; - if (o->engine_data) - ENFN->image_free(ENDT, o->engine_data); - o->engine_data = ENFN->image_new_from_copied_data(ENDT, - o->cur->image.w, - o->cur->image.h, - data, - o->cur->has_alpha, - o->cur->cspace); - if (o->engine_data) - { - int stride = 0; - - o->engine_data = - ENFN->image_alpha_set(ENDT, o->engine_data, o->cur->has_alpha); - if (ENFN->image_scale_hint_set) - ENFN->image_scale_hint_set(ENDT, o->engine_data, o->scale_hint); - if (ENFN->image_content_hint_set) - ENFN->image_content_hint_set(ENDT, o->engine_data, o->content_hint); - if (ENFN->image_stride_get) - ENFN->image_stride_get(ENDT, o->engine_data, &stride); - else - stride = o->cur->image.w * 4; - - if (o->cur->image.stride != stride) - { - EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) - state_write->image.stride = stride; - EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); - } - o->written = EINA_TRUE; - } - o->pixels_checked_out = 0; - EVAS_OBJECT_WRITE_IMAGE_FREE_FILE_AND_KEY(o); -} - EOLIAN static void _evas_image_data_update_add(Eo *eo_obj, Evas_Image_Data *o, int x, int y, int w, int h) { @@ -1994,9 +2017,10 @@ EOLIAN static void _evas_image_colorspace_set(Eo *eo_obj, Evas_Image_Data *o, Evas_Colorspace cspace) { Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); - evas_object_async_block(obj); + evas_object_async_block(obj); _evas_object_image_cleanup(eo_obj, obj, o); + if (o->cur->cspace == cspace) return; EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) state_write->cspace = cspace; -- cgit v1.2.1