diff options
author | kabeer khan <kabeer.khan@samsung.com> | 2015-02-11 17:30:49 +0100 |
---|---|---|
committer | Cedric BAIL <cedric@osg.samsung.com> | 2015-02-11 17:30:54 +0100 |
commit | 46b9b23144ba6a95d619b1aa21ec326ea92303b6 (patch) | |
tree | 1fb951df8d0f01d8477352f42438c003326be1fe | |
parent | 566eefd7d0e4ac70dca3f12b6ce99ae12bec7102 (diff) | |
download | efl-46b9b23144ba6a95d619b1aa21ec326ea92303b6.tar.gz |
evas: add image orient set/get API in software backend for now.
Summary:
Added API's to rotate(0, 90, 180, 270), flip(horizontal, vertical, transpose, transverse)
evas image object. Also added example to demonstrate this.
Signed-off-by: kabeer khan <kabeer.khan@samsung.com>
Reviewers: raster, stephenmhouston, cedric
Subscribers: stephenmhouston, cedric
Differential Revision: https://phab.enlightenment.org/D1950
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
-rw-r--r-- | src/examples/evas/.gitignore | 1 | ||||
-rw-r--r-- | src/examples/evas/Makefile.am | 6 | ||||
-rw-r--r-- | src/examples/evas/Makefile.examples | 1 | ||||
-rw-r--r-- | src/examples/evas/evas-images4.c | 180 | ||||
-rw-r--r-- | src/lib/evas/Evas_Common.h | 18 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_image.eo | 28 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_object_image.c | 64 | ||||
-rw-r--r-- | src/lib/evas/include/evas_common_private.h | 1 | ||||
-rw-r--r-- | src/lib/evas/include/evas_private.h | 2 | ||||
-rw-r--r-- | src/modules/evas/engines/software_generic/evas_engine.c | 341 |
10 files changed, 641 insertions, 1 deletions
diff --git a/src/examples/evas/.gitignore b/src/examples/evas/.gitignore index 7c29ff584b..579d96b971 100644 --- a/src/examples/evas/.gitignore +++ b/src/examples/evas/.gitignore @@ -5,6 +5,7 @@ /evas_images /evas_images2 /evas_images3 +/evas_images4 /evas_init_shutdown /evas_object_manipulation /evas_object_manipulation-eo diff --git a/src/examples/evas/Makefile.am b/src/examples/evas/Makefile.am index fd8e552e00..b5846f3e24 100644 --- a/src/examples/evas/Makefile.am +++ b/src/examples/evas/Makefile.am @@ -139,6 +139,11 @@ evas_images3_SOURCES = evas-images3.c evas_images3_LDADD = $(ECORE_EVAS_COMMON_LDADD) evas_images3_CPPFLAGS = $(ECORE_EVAS_COMMON_CPPFLAGS) +EXTRA_PROGRAMS += evas_images4 +evas_images4_SOURCES = evas-images4.c +evas_images4_LDADD = $(ECORE_EVAS_COMMON_LDADD) +evas_images4_CPPFLAGS = $(ECORE_EVAS_COMMON_CPPFLAGS) + EXTRA_PROGRAMS += evas_text evas_text_SOURCES = evas-text.c evas_text_LDADD = $(ECORE_EVAS_COMMON_LDADD) @@ -300,6 +305,7 @@ evas-hints.c \ evas-images.c \ evas-images2.c \ evas-images3.c \ +evas-images4.c \ evas-init-shutdown.c \ evas-map-utils.c \ evas-map-aa.c \ diff --git a/src/examples/evas/Makefile.examples b/src/examples/evas/Makefile.examples index be10cd57cd..313be1b3b0 100644 --- a/src/examples/evas/Makefile.examples +++ b/src/examples/evas/Makefile.examples @@ -14,6 +14,7 @@ EXAMPLES= evas-aspect-hints \ evas-images \ evas-images2 \ evas-images3 \ + evas-images4 \ evas-init-shutdown \ evas-map-utils \ evas-object-manipulation \ diff --git a/src/examples/evas/evas-images4.c b/src/examples/evas/evas-images4.c new file mode 100644 index 0000000000..391664ef94 --- /dev/null +++ b/src/examples/evas/evas-images4.c @@ -0,0 +1,180 @@ +/** + * Simple Evas example illustrating some image objects functions + * + * You'll need at least one engine built for it (excluding the buffer + * one) and the png image loader/saver also built. See stdout/stderr + * for output. + * + * @verbatim + * gcc -o evas-images4 evas-images4.c `pkg-config --libs --cflags evas ecore ecore-evas` + * @endverbatim + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#else +#define PACKAGE_EXAMPLES_DIR "." +#endif + +#include <Ecore.h> +#include <Ecore_Evas.h> +#include <stdio.h> +#include <errno.h> + +#define WIDTH (320) +#define HEIGHT (240) + +static const char *img_path = PACKAGE_EXAMPLES_DIR "/im1.png"; +static const char *commands = \ + "commands are:\n" + "\tp - print image fill property\n" + "\t0 - rotate by 0\n" + "\t1 - rotate by 90\n" + "\t2 - rotate by 180\n" + "\t3 - rotate by 270\n" + "\t4 - flip horizontal\n" + "\t5 - flip vertical\n" + "\t6 - flip transpose\n" + "\t7 - flip transverse\n" + "\ts - save noise image to disk (/tmp dir)\n" + "\th - print help\n"; + +const char *file_path = "/tmp/evas-images4-example.png"; +const char *quality_str = "quality=100"; + +struct test_data +{ + Ecore_Evas *ee; + Evas *evas; + Evas_Object *bg, *img; +}; + +static struct test_data d = {0}; + +static void +_on_destroy(Ecore_Evas *ee EINA_UNUSED) +{ + ecore_main_loop_quit(); +} + +/* here just to keep our example's window size and background image's + * size in synchrony */ +static void +_canvas_resize_cb(Ecore_Evas *ee) +{ + int w, h; + + ecore_evas_geometry_get(ee, NULL, NULL, &w, &h); + evas_object_resize(d.bg, w, h); +} + +static void +_on_keydown(void *data EINA_UNUSED, + Evas *evas EINA_UNUSED, + Evas_Object *o EINA_UNUSED, + void *einfo) +{ + Evas_Event_Key_Down *ev = einfo; + + if (strcmp(ev->key, "h") == 0) /* print help */ + { + fprintf(stdout, commands); + return; + } + + if (strcmp(ev->key, "s") == 0) /* save noise image to disk */ + { + if (!evas_object_image_save(d.img, file_path, NULL, quality_str)) + fprintf(stderr, "Cannot save image to '%s' (flags '%s')\n", + file_path, quality_str); + else + fprintf(stdout, "Image saved to '%s' (flags '%s'), check it out with " + "an image viewer\n", file_path, quality_str); + + return; + } + + if (strcmp(ev->key, "p") == 0) /* print image size*/ + { + Evas_Coord w, h; + + evas_object_image_size_get(d.img, &w, &h); + fprintf(stdout, "Image has size set to: w=%d, h=%d\n", w, h); + return; + } + + int key_val = ev->key[0] - '0'; + if (key_val >= 0 && key_val <= 7) + { + evas_object_image_orient_set(d.img, key_val); + fprintf(stdout, "Set %i and got %i\n", key_val, + evas_object_image_orient_get(d.img)); + + return; + } +} + +int +main(void) +{ + int err; + + if (!ecore_evas_init()) + return EXIT_FAILURE; + + /* this will give you a window with an Evas canvas under the first + * engine available */ + d.ee = ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL); + if (!d.ee) + goto error; + + ecore_evas_callback_destroy_set(d.ee, _on_destroy); + ecore_evas_callback_resize_set(d.ee, _canvas_resize_cb); + ecore_evas_show(d.ee); + + /* the canvas pointer, de facto */ + d.evas = ecore_evas_get(d.ee); + + d.bg = evas_object_rectangle_add(d.evas); + evas_object_color_set(d.bg, 255, 255, 255, 255); /* white bg */ + evas_object_move(d.bg, 0, 0); /* at canvas' origin */ + evas_object_resize(d.bg, WIDTH, HEIGHT); /* covers full canvas */ + evas_object_show(d.bg); + + d.img = evas_object_image_add(d.evas); + evas_object_image_file_set(d.img, img_path, NULL); + err = evas_object_image_load_error_get(d.img); + if (err != EVAS_LOAD_ERROR_NONE) + { + fprintf(stderr, "could not load image '%s'. error string is \"%s\"\n", + img_path, evas_load_error_str(err)); + } + else + { + fprintf(stdout, + "loaded image '%s' with succes! error string is \"%s\"\n", + img_path, evas_load_error_str(err)); + + evas_object_move(d.img, WIDTH / 2, HEIGHT / 2); + evas_object_image_fill_set(d.img, 0, 0, WIDTH / 2, HEIGHT / 2); + evas_object_resize(d.img, WIDTH / 2, HEIGHT / 2); + evas_object_show(d.img); + + evas_object_focus_set(d.bg, EINA_TRUE); + evas_object_event_callback_add( + d.bg, EVAS_CALLBACK_KEY_DOWN, _on_keydown, NULL); + } + + fprintf(stdout, commands); + ecore_main_loop_begin(); + + ecore_evas_free(d.ee); + ecore_evas_shutdown(); + return 0; + +error: + fprintf(stderr, "you got to have at least one evas engine built and linked" + " up to ecore-evas for this example to run properly.\n"); + ecore_evas_shutdown(); + return -1; +} diff --git a/src/lib/evas/Evas_Common.h b/src/lib/evas/Evas_Common.h index e1ab7d6c42..27d8dfa199 100644 --- a/src/lib/evas/Evas_Common.h +++ b/src/lib/evas/Evas_Common.h @@ -631,6 +631,24 @@ typedef enum _Evas_Image_Content_Hint EVAS_IMAGE_CONTENT_HINT_STATIC = 2 /**< The contents won't change over time */ } Evas_Image_Content_Hint; /**< How an image's data is to be treated by Evas, for optimization */ +/** + * Possible orientation options for evas_object_image_orient_set(). + * @brief Types of orientation available + * @since 1.14 + */ +typedef enum _Evas_Image_Orient +{ + EVAS_IMAGE_ORIENT_NONE = 0, /**< no orientation change */ + EVAS_IMAGE_ORIENT_0 = 0, /**< no orientation change */ + EVAS_IMAGE_ORIENT_90 = 1, /**< orient 90 degrees clockwise*/ + EVAS_IMAGE_ORIENT_180 = 2, /**< orient 180 degrees clockwise */ + EVAS_IMAGE_ORIENT_270 = 3, /**< rotate 90 degrees counter-clockwise (i.e. 270 degrees clockwise)*/ + EVAS_IMAGE_FLIP_HORIZONTAL = 4, /**< flip image horizontally */ + EVAS_IMAGE_FLIP_VERTICAL = 5, /**< flip image vertically */ + EVAS_IMAGE_FLIP_TRANSPOSE = 6, /**< flip image along the y = (width - x) line (bottom-left to top-right) */ + EVAS_IMAGE_FLIP_TRANSVERSE = 7 /**< flip image along the y = x line (top-left to bottom-right) */ +} Evas_Image_Orient; + typedef enum _Evas_Device_Class { EVAS_DEVICE_CLASS_NONE, /**< Not a device @since 1.8 */ diff --git a/src/lib/evas/canvas/evas_image.eo b/src/lib/evas/canvas/evas_image.eo index 23e563de6c..df97e32525 100644 --- a/src/lib/evas/canvas/evas_image.eo +++ b/src/lib/evas/canvas/evas_image.eo @@ -925,6 +925,34 @@ class Evas.Image (Evas.Object, Efl.File, Efl.Image) int b; /*@ Bottom padding in pixels */ } } + orient { + set { + /*@ + Set the image orientation. + + This function allows to rotate or flip the image. + + @see evas_object_image_orient_get() + @see @ref Evas_Image_Orient + + @since 1.14*/ + } + get { + /*@ + Get the image orientation. + + @return The image orientation @ref Evas_Image_Orient + + @see evas_object_image_orient_set() + @see @ref Evas_Image_Orient + + @since 1.14*/ + } + values { + Evas_Image_Orient orient; /*@ The image orientation @ref Evas_Image_Orient + Default is #EVAS_IMAGE_ORIENT_NONE. */ + } + } } methods { preload_begin { diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c index 9ec344a15d..cf4309778c 100644 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -92,7 +92,8 @@ struct _Evas_Object_Image_State int frame; int spread; - Evas_Colorspace cspace; + Evas_Colorspace cspace; + Evas_Image_Orient orient; Eina_Bool smooth_scale : 1; Eina_Bool has_alpha :1; @@ -237,6 +238,7 @@ static const Evas_Object_Image_State default_state = { 0, //frame EVAS_TEXTURE_REPEAT, EVAS_COLORSPACE_ARGB8888, + EVAS_IMAGE_ORIENT_NONE, // flags EINA_TRUE, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE @@ -661,6 +663,61 @@ _evas_image_source_get(Eo *eo_obj EINA_UNUSED, Evas_Image_Data *o) return o->cur->source; } +EOLIAN static void +_evas_image_orient_set(Eo *eo_obj, Evas_Image_Data *o, Evas_Image_Orient orient) +{ + Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); + int iw, ih; + + if (o->cur->orient == orient) return; + + if ((o->preloading) && (o->engine_data)) + { + o->preloading = EINA_FALSE; + ENFN->image_data_preload_cancel(ENDT, o->engine_data, eo_obj); + } + + if(o->engine_data) + { + int stride = 0; + + o->engine_data = ENFN->image_orient_set(ENDT, o->engine_data, orient); + if(o->engine_data) + { + EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) + state_write->orient = orient; + EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); + + 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; + } + ENFN->image_size_get(ENDT, o->engine_data, &iw, &ih); + EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) + { + state_write->image.w = iw; + state_write->image.h = ih; + } + EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); + } + o->changed = EINA_TRUE; + evas_object_change(eo_obj, obj); +} + +EOLIAN static Evas_Image_Orient +_evas_image_orient_get(Eo *eo_obj EINA_UNUSED, Evas_Image_Data *o) +{ + return o->cur->orient; +} + EAPI Eina_Bool evas_object_image_source_unset(Evas_Object *eo_obj) { @@ -3588,6 +3645,11 @@ evas_object_image_render_pre(Evas_Object *eo_obj, evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj); if (!o->pixels->pixel_updates) goto done; } + if (o->cur->orient != o->prev->orient) + { + evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj); + if (!o->pixels->pixel_updates) goto done; + } } if (((obj->cur->geometry.x != obj->prev->geometry.x) || diff --git a/src/lib/evas/include/evas_common_private.h b/src/lib/evas/include/evas_common_private.h index 56dc039c53..0160af565b 100644 --- a/src/lib/evas/include/evas_common_private.h +++ b/src/lib/evas/include/evas_common_private.h @@ -596,6 +596,7 @@ struct _Image_Entry Evas_Image_Load_Opts load_opts; Evas_Colorspace space; const Evas_Colorspace *cspaces; // owned by the loader, live as long as the loader + Evas_Image_Orient orient; unsigned int w; unsigned int h; diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 3cd94aa6f8..c07cfa31df 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1217,6 +1217,8 @@ struct _Evas_Func void (*image_data_preload_cancel) (void *data, void *image, const Eo *target); void *(*image_alpha_set) (void *data, void *image, int has_alpha); int (*image_alpha_get) (void *data, void *image); + void *(*image_orient_set) (void *data, void *image, Evas_Image_Orient orient); + Evas_Image_Orient (*image_orient_get) (void *data, void *image); void *(*image_border_set) (void *data, void *image, int l, int r, int t, int b); void (*image_border_get) (void *data, void *image, int *l, int *r, int *t, int *b); Eina_Bool (*image_draw) (void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async); diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index a3b15b4dcc..58cbb23a60 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -57,6 +57,9 @@ #define OSMESA_MAX_WIDTH 0x24 /* new in 4.0 */ #define OSMESA_MAX_HEIGHT 0x25 /* new in 4.0 */ +/* Required for orient */ +#define TILE 32 + typedef void (*OSMESAproc)(); typedef struct osmesa_context *OSMesaContext; @@ -1291,6 +1294,342 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data) return im; } +static void * +_image_flip_horizontal(void *data, Image_Entry *im) +{ + unsigned int *p1, *p2, tmp; + DATA32 *image_data; + int x, y, iw, ih; + Image_Entry *im2; + + iw = im->w; + ih = im->h; + image_data = evas_cache_image_pixels(im); + for (y = 0; y < ih; y++) + { + p1 = image_data + (y * iw); + p2 = image_data + ((y + 1) * iw) - 1; + for (x = 0; x < (iw >> 1); x++) + { + tmp = *p1; + *p1 = *p2; + *p2 = tmp; + p1++; + p2--; + } + } + im2 = eng_image_new_from_data(data, iw, ih, image_data, + eng_image_alpha_get(data, im), + eng_image_colorspace_get(data, im)); + return im2; +} + +static void * +_image_flip_vertical(void *data, Image_Entry *im) +{ + unsigned int *p1, *p2, tmp; + DATA32 *image_data; + int x, y, iw, ih; + Image_Entry *im2; + + iw = im->w; + ih = im->h; + image_data = evas_cache_image_pixels(im); + for (y = 0; y < (ih >> 1); y++) + { + p1 = image_data + (y * iw); + p2 = image_data + ((ih - 1 - y) * iw); + for (x = 0; x < iw; x++) + { + tmp = *p1; + *p1 = *p2; + *p2 = tmp; + p1++; + p2++; + } + } + im2 = eng_image_new_from_data(data, iw, ih, image_data, + eng_image_alpha_get(data, im), + eng_image_colorspace_get(data, im)); + return im2; +} + +static void * +_image_rotate_180(void *data, Image_Entry *im) +{ + unsigned int *p1, *p2, tmp; + DATA32 *image_data; + int x, hw, iw, ih; + Image_Entry *im2; + + iw = im->w; + ih = im->h; + image_data = evas_cache_image_pixels(im); + if(!image_data) return im; + hw = iw * ih; + x = (hw / 2); + p1 = image_data; + p2 = image_data + hw - 1; + for (; --x > 0; ) + { + tmp = *p1; + *p1 = *p2; + *p2 = tmp; + p1++; + p2--; + } + im2 = eng_image_new_from_data(data, iw, ih, image_data, + eng_image_alpha_get(data, im), + eng_image_colorspace_get(data, im)); + return im2; +} + +# define GETDAT(neww, newh) \ + DATA32 *image_data, *image_data2; \ + int iw, ih, w, h; \ + Image_Entry *im2; \ + iw = im->w; \ + ih = im->h; \ + image_data = evas_cache_image_pixels(im); \ + if (!image_data) return im; \ + image_data2 = malloc(iw * ih * sizeof(int)); \ + if (!image_data2) { \ + return im; \ + } \ + memcpy(image_data2, image_data, iw * ih * sizeof(int)); \ + im = eng_image_new_from_data(data, iw, ih, image_data, \ + eng_image_alpha_get(data, im), \ + eng_image_colorspace_get(data, im)); \ + w = neww; h = newh; \ + image_data = evas_cache_image_pixels(im); \ + +# define PUTDAT \ + im2 = eng_image_new_from_data(data, w, h, image_data, \ + eng_image_alpha_get(data, im), \ + eng_image_colorspace_get(data, im)); \ + im2 = eng_image_size_set(data, im2, w, h); \ + free(image_data2); \ + return im2; \ + +static void * +_image_rotate_90(void *data, Image_Entry *im) +{ + GETDAT(ih, iw); + int x, y, xx, yy, xx2, yy2; + unsigned int *src, *dst; + + for (y = 0; y < ih; y += TILE) + { + yy2 = y + TILE; + if (yy2 > ih) yy2 = ih; + for (x = 0; x < iw; x += TILE) + { + xx2 = x + TILE; + if (xx2 > iw) xx2 = iw; + for (yy = y; yy < yy2; yy++) + { + src = image_data2 + (yy * iw) + x; + dst = image_data + (x * w) + (w - yy - 1); + for (xx = x; xx < xx2; xx++) + { + *dst = *src; + src++; + dst += w; + } + } + } + } + PUTDAT; +} + +static void * +_image_rotate_270(void *data, Image_Entry *im) +{ + GETDAT(ih, iw); + int x, y, xx, yy, xx2, yy2; + unsigned int *src, *dst; + + for (y = 0; y < ih; y += TILE) + { + yy2 = y + TILE; + if (yy2 > ih) yy2 = ih; + for (x = 0; x < iw; x += TILE) + { + xx2 = x + TILE; + if (xx2 > iw) xx2 = iw; + for (yy = y; yy < yy2; yy++) + { + src = image_data2 + (yy * iw) + x; + dst = image_data + ((h - x - 1) * w) + yy; + for (xx = x; xx < xx2; xx++) + { + *dst = *src; + src++; + dst -= w; + } + } + } + } + PUTDAT; +} + +static void * +_image_flip_transverse(void *data, Image_Entry *im) +{ + GETDAT(ih, iw); + int x, y; + unsigned int *src, *dst; + + src = image_data2; + for (y = 0; y < ih; y++) + { + dst = image_data + y; + for (x = 0; x < iw; x++) + { + *dst = *src; + src++; + dst += w; + } + } + PUTDAT; +} + +static void * +_image_flip_transpose(void *data, Image_Entry *im) +{ + GETDAT(ih, iw); + int x, y; + unsigned int *src, *dst; + + src = image_data2 + (iw * ih) - 1; + for (y = 0; y < ih; y++) + { + dst = image_data + y; + for (x = 0; x < iw; x++) + { + *dst = *src; + src--; + dst += w; + } + } + PUTDAT; +} + +#undef GETDAT +#undef PUTDAT + +static void * +eng_image_orient_set(void *data, void *image, Evas_Image_Orient orient) +{ + Image_Entry *im; + + if (!image) return NULL; + im = image; + if (im->orient == orient) return im; + + if ((im->orient >= EVAS_IMAGE_ORIENT_0) && + (im->orient <= EVAS_IMAGE_ORIENT_270) && + (orient >= EVAS_IMAGE_ORIENT_0) && + (orient <= EVAS_IMAGE_ORIENT_270)) + { + // we are rotating from one anglee to another, so figure out delta + // and apply that delta + Evas_Image_Orient rot_delta = (4 + orient - im->orient) % 4; + switch (rot_delta) + { + case EVAS_IMAGE_ORIENT_0: + ERR("You shouldn't get this message, wrong orient value"); + break; + case EVAS_IMAGE_ORIENT_90: + im = _image_rotate_90(data, im); + im->orient = orient; + break; + case EVAS_IMAGE_ORIENT_180: + im = _image_rotate_180(data, im); + im->orient = orient; + break; + case EVAS_IMAGE_ORIENT_270: + im = _image_rotate_270(data, im); + im->orient = orient; + break; + default: + ERR("Wrong orient value"); + break; + } + } + else if (((im->orient == EVAS_IMAGE_ORIENT_NONE) && + (orient == EVAS_IMAGE_FLIP_HORIZONTAL)) || + ((im->orient == EVAS_IMAGE_FLIP_HORIZONTAL) && + (orient == EVAS_IMAGE_ORIENT_NONE))) + { + // flip horizontally to get the new orientation + im = _image_flip_horizontal(data, im); + im->orient = orient; + } + else if (((im->orient == EVAS_IMAGE_ORIENT_NONE) && + (orient == EVAS_IMAGE_FLIP_VERTICAL)) || + ((im->orient == EVAS_IMAGE_FLIP_VERTICAL) && + (orient == EVAS_IMAGE_ORIENT_NONE))) + { + // flip vertically to get the new orientation + im = _image_flip_vertical(data, im); + im->orient = orient; + } + else + { + // generic solution - undo the previous orientation and then apply the + // new one after that + int i; + + for (i = 0; i < 2; i++) + { + switch (im->orient) + { + case EVAS_IMAGE_ORIENT_0: + break; + case EVAS_IMAGE_ORIENT_90: + if(i == 1) im = _image_rotate_90(data, im); + else im = _image_rotate_270(data, im); + break; + case EVAS_IMAGE_ORIENT_180: + im = _image_rotate_180(data, im); + break; + case EVAS_IMAGE_ORIENT_270: + if(i == 1) im = _image_rotate_270(data, im); + else im = _image_rotate_90(data, im); + break; + case EVAS_IMAGE_FLIP_HORIZONTAL: + im = _image_flip_horizontal(data, im); + break; + case EVAS_IMAGE_FLIP_VERTICAL: + im = _image_flip_vertical(data, im); + break; + case EVAS_IMAGE_FLIP_TRANSPOSE: + im = _image_flip_transpose(data, im); + break; + case EVAS_IMAGE_FLIP_TRANSVERSE: + im = _image_flip_transverse(data, im); + break; + default: + ERR("Wrong orient value"); + break; + } + im->orient = orient; + } + } + return im; +} + +static Evas_Image_Orient +eng_image_orient_get(void *data EINA_UNUSED, void *image) +{ + Image_Entry *im; + + if (!image) return EVAS_IMAGE_ORIENT_NONE; + im = image; + return im->orient; +} + static void eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const Eo *target) { @@ -3158,6 +3497,8 @@ static Evas_Func func = eng_image_data_preload_cancel, eng_image_alpha_set, eng_image_alpha_get, + eng_image_orient_set, + eng_image_orient_get, eng_image_border_set, eng_image_border_get, eng_image_draw, |