2 # include "config.h" /* so that EAPI in Evas.h is correctly defined */
13 #include "evas_common.h"
14 #include "evas_private.h"
15 #include "../engines/common/evas_convert_color.h"
16 #include "../engines/common/evas_convert_colorspace.h"
17 #include "../engines/common/evas_convert_yuv.h"
19 #define VERBOSE_PROXY_ERROR 1
21 /* private magic number for image objects */
22 static const char o_type[] = "image";
24 /* private struct for rectangle object internal data */
25 typedef struct _Evas_Object_Image Evas_Object_Image;
27 struct _Evas_Object_Image
33 Evas_Coord_Rectangle fill;
48 Evas_Colorspace cspace;
50 unsigned char smooth_scale : 1;
51 unsigned char has_alpha :1;
52 unsigned char opaque :1;
53 unsigned char opaque_valid :1;
56 int pixels_checked_out;
58 Eina_List *pixel_updates;
61 unsigned char scale_down_by;
67 Eina_Bool orientation : 1;
71 Evas_Object_Image_Pixels_Get_Cb get_pixels;
72 void *get_pixels_data;
75 Evas_Video_Surface video;
80 Evas_Image_Scale_Hint scale_hint;
81 Evas_Image_Content_Hint content_hint;
85 unsigned char changed : 1;
86 unsigned char dirty_pixels : 1;
87 unsigned char filled : 1;
88 unsigned char proxyrendering : 1;
89 unsigned char preloading : 1;
90 unsigned char video_rendering : 1;
91 unsigned char video_surface : 1;
92 unsigned char video_visible : 1;
93 unsigned char created : 1;
96 /* private methods for image objects */
97 static void evas_object_image_unload(Evas_Object *obj, Eina_Bool dirty);
98 static void evas_object_image_load(Evas_Object *obj);
99 static Evas_Coord evas_object_image_figure_x_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret);
100 static Evas_Coord evas_object_image_figure_y_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret);
102 static void evas_object_image_init(Evas_Object *obj);
103 static void *evas_object_image_new(void);
104 static void evas_object_image_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y);
105 static void evas_object_image_free(Evas_Object *obj);
106 static void evas_object_image_render_pre(Evas_Object *obj);
107 static void evas_object_image_render_post(Evas_Object *obj);
109 static unsigned int evas_object_image_id_get(Evas_Object *obj);
110 static unsigned int evas_object_image_visual_id_get(Evas_Object *obj);
111 static void *evas_object_image_engine_data_get(Evas_Object *obj);
113 static int evas_object_image_is_opaque(Evas_Object *obj);
114 static int evas_object_image_was_opaque(Evas_Object *obj);
115 static int evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
116 static int evas_object_image_has_opaque_rect(Evas_Object *obj);
117 static int evas_object_image_get_opaque_rect(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
118 static int evas_object_image_can_map(Evas_Object *obj);
120 static void *evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_Colorspace to_cspace);
121 static void evas_object_image_filled_resize_listener(void *data, Evas *e, Evas_Object *obj, void *einfo);
123 static void _proxy_unset(Evas_Object *proxy);
124 static void _proxy_set(Evas_Object *proxy, Evas_Object *src);
125 static void _proxy_error(Evas_Object *proxy, void *context, void *output, void *surface, int x, int y);
127 static void _cleanup_tmpf(Evas_Object *obj);
129 static const Evas_Object_Func object_func =
131 /* methods (compulsory) */
132 evas_object_image_free,
133 evas_object_image_render,
134 evas_object_image_render_pre,
135 evas_object_image_render_post,
136 evas_object_image_id_get,
137 evas_object_image_visual_id_get,
138 evas_object_image_engine_data_get,
139 /* these are optional. NULL = nothing */
144 evas_object_image_is_opaque,
145 evas_object_image_was_opaque,
146 evas_object_image_is_inside,
150 evas_object_image_has_opaque_rect,
151 evas_object_image_get_opaque_rect,
152 evas_object_image_can_map
155 EVAS_MEMPOOL(_mp_obj);
158 _evas_object_image_cleanup(Evas_Object *obj, Evas_Object_Image *o)
160 if ((o->preloading) && (o->engine_data))
163 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
167 if (o->tmpf) _cleanup_tmpf(obj);
168 if (o->cur.source) _proxy_unset(obj);
172 evas_object_image_add(Evas *e)
175 Evas_Object_Image *o;
177 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
180 EINA_SAFETY_ON_NULL_RETURN_VAL(e->engine.func, NULL);
181 obj = evas_object_new(e);
182 evas_object_image_init(obj);
183 evas_object_inject(obj, e);
184 o = (Evas_Object_Image *)(obj->object_data);
185 o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output,
191 evas_object_image_filled_add(Evas *e)
194 obj = evas_object_image_add(e);
195 evas_object_image_filled_set(obj, 1);
200 _cleanup_tmpf(Evas_Object *obj)
202 #ifdef HAVE_SYS_MMAN_H
203 Evas_Object_Image *o;
205 o = (Evas_Object_Image *)(obj->object_data);
206 if (!o->tmpf) return;
211 if (o->tmpf_fd >= 0) close(o->tmpf_fd);
212 eina_stringshare_del(o->tmpf);
221 _create_tmpf(Evas_Object *obj, void *data, int size, char *format __UNUSED__)
223 #ifdef HAVE_SYS_MMAN_H
224 Evas_Object_Image *o;
229 o = (Evas_Object_Image *)(obj->object_data);
231 snprintf(buf, sizeof(buf), "/dev/shm/.evas-tmpf-%i-%p-%i-XXXXXX",
232 (int)getpid(), data, (int)size);
237 const char *tmpdir = getenv("TMPDIR");
241 tmpdir = getenv("TMP");
244 tmpdir = getenv("TEMP");
245 if (!tmpdir) tmpdir = "/tmp";
248 snprintf(buf, sizeof(buf), "%s/.evas-tmpf-%i-%p-%i-XXXXXX",
249 tmpdir, (int)getpid(), data, (int)size);
253 if (ftruncate(fd, size) < 0)
263 eina_mmap_safety_enabled_set(EINA_TRUE);
265 dst = mmap(NULL, size,
266 PROT_READ | PROT_WRITE,
269 if (dst == MAP_FAILED)
276 snprintf(buf, sizeof(buf), "/proc/%li/fd/%i", (long)getpid(), fd);
278 o->tmpf = eina_stringshare_add(buf);
279 memcpy(dst, data, size);
290 evas_object_image_memfile_set(Evas_Object *obj, void *data, int size, char *format, char *key)
292 Evas_Object_Image *o;
294 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
297 o = (Evas_Object_Image *)(obj->object_data);
298 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
302 evas_object_image_file_set(obj, NULL, NULL);
303 // invalidate the cache effectively
304 evas_object_image_alpha_set(obj, !o->cur.has_alpha);
305 evas_object_image_alpha_set(obj, !o->cur.has_alpha);
307 if ((size < 1) || (!data)) return;
309 _create_tmpf(obj, data, size, format);
310 evas_object_image_file_set(obj, o->tmpf, key);
313 ERR("unable to load '%s' from memory", o->tmpf);
320 evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key)
322 Evas_Object_Image *o;
323 Evas_Image_Load_Opts lo;
325 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
328 o = (Evas_Object_Image *)(obj->object_data);
329 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
332 if ((o->tmpf) && (file != o->tmpf)) _cleanup_tmpf(obj);
333 if ((o->cur.file) && (file) && (!strcmp(o->cur.file, file)))
335 if ((!o->cur.key) && (!key))
337 if ((o->cur.key) && (key) && (!strcmp(o->cur.key, key)))
341 * WTF? why cancel a null image preload? this is just silly (tm)
343 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
347 if (o->cur.source) _proxy_unset(obj);
348 if (o->cur.file) eina_stringshare_del(o->cur.file);
349 if (o->cur.key) eina_stringshare_del(o->cur.key);
350 if (file) o->cur.file = eina_stringshare_add(file);
351 else o->cur.file = NULL;
352 if (key) o->cur.key = eina_stringshare_add(key);
353 else o->cur.key = NULL;
361 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
365 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
368 o->load_error = EVAS_LOAD_ERROR_NONE;
369 lo.scale_down_by = o->load_opts.scale_down_by;
370 lo.dpi = o->load_opts.dpi;
371 lo.w = o->load_opts.w;
372 lo.h = o->load_opts.h;
373 lo.region.x = o->load_opts.region.x;
374 lo.region.y = o->load_opts.region.y;
375 lo.region.w = o->load_opts.region.w;
376 lo.region.h = o->load_opts.region.h;
377 lo.orientation = o->load_opts.orientation;
378 o->engine_data = obj->layer->evas->engine.func->image_load(obj->layer->evas->engine.data.output,
388 obj->layer->evas->engine.func->image_size_get(obj->layer->evas->engine.data.output,
389 o->engine_data, &w, &h);
390 if (obj->layer->evas->engine.func->image_stride_get)
391 obj->layer->evas->engine.func->image_stride_get(obj->layer->evas->engine.data.output,
392 o->engine_data, &stride);
395 o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get(obj->layer->evas->engine.data.output,
397 o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output,
401 o->cur.image.stride = stride;
405 if (o->load_error == EVAS_LOAD_ERROR_NONE)
406 o->load_error = EVAS_LOAD_ERROR_GENERIC;
407 o->cur.has_alpha = 1;
408 o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
411 o->cur.image.stride = 0;
414 evas_object_change(obj);
418 evas_object_image_file_get(const Evas_Object *obj, const char **file, const char **key)
420 Evas_Object_Image *o;
422 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
423 if (file) *file = NULL;
424 if (key) *key = NULL;
427 o = (Evas_Object_Image *)(obj->object_data);
428 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
429 if (file) *file = NULL;
430 if (key) *key = NULL;
433 if (file) *file = o->cur.file;
434 if (key) *key = o->cur.key;
438 evas_object_image_source_set(Evas_Object *obj, Evas_Object *src)
440 Evas_Object_Image *o;
442 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
445 o = obj->object_data;
446 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
450 if (src == obj) return EINA_FALSE;
451 if (o->cur.source == src) return EINA_TRUE;
453 _evas_object_image_cleanup(obj, o);
454 /* Kill the image if any */
455 if (o->cur.file || o->cur.key)
456 evas_object_image_file_set(obj, NULL, NULL);
460 _proxy_set(obj, src);
468 evas_object_image_source_get(const Evas_Object *obj)
470 Evas_Object_Image *o;
472 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
475 o = obj->object_data;
476 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
480 return o->cur.source;
484 evas_object_image_source_unset(Evas_Object *obj)
486 return evas_object_image_source_set(obj, NULL);
490 evas_object_image_border_set(Evas_Object *obj, int l, int r, int t, int b)
492 Evas_Object_Image *o;
494 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
497 o = (Evas_Object_Image *)(obj->object_data);
498 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
505 if ((o->cur.border.l == l) &&
506 (o->cur.border.r == r) &&
507 (o->cur.border.t == t) &&
508 (o->cur.border.b == b)) return;
513 o->cur.opaque_valid = 0;
515 evas_object_change(obj);
519 evas_object_image_border_get(const Evas_Object *obj, int *l, int *r, int *t, int *b)
521 Evas_Object_Image *o;
523 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
530 o = (Evas_Object_Image *)(obj->object_data);
531 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
538 if (l) *l = o->cur.border.l;
539 if (r) *r = o->cur.border.r;
540 if (t) *t = o->cur.border.t;
541 if (b) *b = o->cur.border.b;
545 evas_object_image_border_center_fill_set(Evas_Object *obj, Evas_Border_Fill_Mode fill)
547 Evas_Object_Image *o;
549 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
552 o = (Evas_Object_Image *)(obj->object_data);
553 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
556 if (fill == o->cur.border.fill) return;
557 o->cur.border.fill = fill;
559 evas_object_change(obj);
562 EAPI Evas_Border_Fill_Mode
563 evas_object_image_border_center_fill_get(const Evas_Object *obj)
565 Evas_Object_Image *o;
567 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
570 o = (Evas_Object_Image *)(obj->object_data);
571 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
574 return o->cur.border.fill;
578 evas_object_image_filled_set(Evas_Object *obj, Eina_Bool setting)
580 Evas_Object_Image *o;
582 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
585 o = (Evas_Object_Image *)(obj->object_data);
586 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
591 if (o->filled == setting) return;
595 evas_object_event_callback_del(obj, EVAS_CALLBACK_RESIZE, evas_object_image_filled_resize_listener);
600 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
601 evas_object_image_fill_set(obj, 0, 0, w, h);
603 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, evas_object_image_filled_resize_listener, NULL);
608 evas_object_image_filled_get(const Evas_Object *obj)
610 Evas_Object_Image *o;
612 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
615 o = (Evas_Object_Image *)(obj->object_data);
616 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
624 evas_object_image_border_scale_set(Evas_Object *obj, double scale)
626 Evas_Object_Image *o;
628 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
631 o = (Evas_Object_Image *)(obj->object_data);
632 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
635 if (scale == o->cur.border.scale) return;
636 o->cur.border.scale = scale;
638 evas_object_change(obj);
642 evas_object_image_border_scale_get(const Evas_Object *obj)
644 Evas_Object_Image *o;
646 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
649 o = (Evas_Object_Image *)(obj->object_data);
650 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
653 return o->cur.border.scale;
657 evas_object_image_fill_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
659 Evas_Object_Image *o;
666 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
669 o = (Evas_Object_Image *)(obj->object_data);
670 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
674 if ((o->cur.fill.x == x) &&
675 (o->cur.fill.y == y) &&
676 (o->cur.fill.w == w) &&
677 (o->cur.fill.h == h)) return;
682 o->cur.opaque_valid = 0;
684 evas_object_change(obj);
688 evas_object_image_fill_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
690 Evas_Object_Image *o;
692 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
699 o = (Evas_Object_Image *)(obj->object_data);
700 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
707 if (x) *x = o->cur.fill.x;
708 if (y) *y = o->cur.fill.y;
709 if (w) *w = o->cur.fill.w;
710 if (h) *h = o->cur.fill.h;
715 evas_object_image_fill_spread_set(Evas_Object *obj, Evas_Fill_Spread spread)
717 Evas_Object_Image *o;
719 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
722 o = (Evas_Object_Image *)(obj->object_data);
723 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
726 if (spread == (Evas_Fill_Spread)o->cur.spread) return;
727 o->cur.spread = spread;
729 evas_object_change(obj);
732 EAPI Evas_Fill_Spread
733 evas_object_image_fill_spread_get(const Evas_Object *obj)
735 Evas_Object_Image *o;
737 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
738 return EVAS_TEXTURE_REPEAT;
740 o = (Evas_Object_Image *)(obj->object_data);
741 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
742 return EVAS_TEXTURE_REPEAT;
744 return (Evas_Fill_Spread)o->cur.spread;
748 evas_object_image_size_set(Evas_Object *obj, int w, int h)
750 Evas_Object_Image *o;
753 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
756 o = (Evas_Object_Image *)(obj->object_data);
757 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
760 _evas_object_image_cleanup(obj, o);
763 if (w > 32768) return;
764 if (h > 32768) return;
765 if ((w == o->cur.image.w) &&
766 (h == o->cur.image.h)) return;
770 o->engine_data = obj->layer->evas->engine.func->image_size_set(obj->layer->evas->engine.data.output,
774 o->engine_data = obj->layer->evas->engine.func->image_new_from_copied_data
775 (obj->layer->evas->engine.data.output, w, h, NULL, o->cur.has_alpha,
780 if (obj->layer->evas->engine.func->image_scale_hint_set)
781 obj->layer->evas->engine.func->image_scale_hint_set
782 (obj->layer->evas->engine.data.output,
783 o->engine_data, o->scale_hint);
784 if (obj->layer->evas->engine.func->image_content_hint_set)
785 obj->layer->evas->engine.func->image_content_hint_set
786 (obj->layer->evas->engine.data.output,
787 o->engine_data, o->content_hint);
788 if (obj->layer->evas->engine.func->image_stride_get)
789 obj->layer->evas->engine.func->image_stride_get
790 (obj->layer->evas->engine.data.output,
791 o->engine_data, &stride);
797 o->cur.image.stride = stride;
799 /* FIXME - in engine call above
801 o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
805 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
807 evas_object_change(obj);
811 evas_object_image_size_get(const Evas_Object *obj, int *w, int *h)
813 Evas_Object_Image *o;
815 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
820 o = (Evas_Object_Image *)(obj->object_data);
821 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
826 if (w) *w = o->cur.image.w;
827 if (h) *h = o->cur.image.h;
831 evas_object_image_stride_get(const Evas_Object *obj)
833 Evas_Object_Image *o;
835 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
838 o = (Evas_Object_Image *)(obj->object_data);
839 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
842 return o->cur.image.stride;
846 evas_object_image_load_error_get(const Evas_Object *obj)
848 Evas_Object_Image *o;
850 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
853 o = (Evas_Object_Image *)(obj->object_data);
854 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
857 return o->load_error;
861 evas_object_image_data_convert(Evas_Object *obj, Evas_Colorspace to_cspace)
863 Evas_Object_Image *o;
867 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
870 o = (Evas_Object_Image *)(obj->object_data);
871 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
874 if ((o->preloading) && (o->engine_data))
877 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
881 if (!o->engine_data) return NULL;
882 if (o->video_surface)
883 o->video.update_pixels(o->video.data, obj, &o->video);
884 if (o->cur.cspace == to_cspace) return NULL;
887 obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
888 o->engine_data, 0, &data,
890 result = evas_object_image_data_convert_internal(o, data, to_cspace);
894 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
895 o->engine_data, data);
901 evas_object_image_data_set(Evas_Object *obj, void *data)
903 Evas_Object_Image *o;
906 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
909 o = (Evas_Object_Image *)(obj->object_data);
910 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
913 _evas_object_image_cleanup(obj, o);
914 p_data = o->engine_data;
920 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
927 obj->layer->evas->engine.func->image_new_from_data(obj->layer->evas->engine.data.output,
938 if (obj->layer->evas->engine.func->image_scale_hint_set)
939 obj->layer->evas->engine.func->image_scale_hint_set
940 (obj->layer->evas->engine.data.output,
941 o->engine_data, o->scale_hint);
942 if (obj->layer->evas->engine.func->image_content_hint_set)
943 obj->layer->evas->engine.func->image_content_hint_set
944 (obj->layer->evas->engine.data.output,
945 o->engine_data, o->content_hint);
946 if (obj->layer->evas->engine.func->image_stride_get)
947 obj->layer->evas->engine.func->image_stride_get
948 (obj->layer->evas->engine.data.output,
949 o->engine_data, &stride);
951 stride = o->cur.image.w * 4;
952 o->cur.image.stride = stride;
958 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
960 o->load_error = EVAS_LOAD_ERROR_NONE;
963 o->cur.image.stride = 0;
964 o->engine_data = NULL;
966 /* FIXME - in engine call above
968 o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
972 if (o->pixels_checked_out > 0) o->pixels_checked_out--;
973 if (p_data != o->engine_data)
975 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
976 o->pixels_checked_out = 0;
979 evas_object_change(obj);
983 evas_object_image_data_get(const Evas_Object *obj, Eina_Bool for_writing)
985 Evas_Object_Image *o;
988 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
991 o = (Evas_Object_Image *)(obj->object_data);
992 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
995 if (!o->engine_data) return NULL;
998 if (obj->layer->evas->engine.func->image_scale_hint_set)
999 obj->layer->evas->engine.func->image_scale_hint_set
1000 (obj->layer->evas->engine.data.output,
1001 o->engine_data, o->scale_hint);
1002 if (obj->layer->evas->engine.func->image_content_hint_set)
1003 obj->layer->evas->engine.func->image_content_hint_set
1004 (obj->layer->evas->engine.data.output,
1005 o->engine_data, o->content_hint);
1007 obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1012 /* if we fail to get engine_data, we have to return NULL */
1013 if (!o->engine_data) return NULL;
1019 if (obj->layer->evas->engine.func->image_stride_get)
1020 obj->layer->evas->engine.func->image_stride_get
1021 (obj->layer->evas->engine.data.output,
1022 o->engine_data, &stride);
1024 stride = o->cur.image.w * 4;
1025 o->cur.image.stride = stride;
1027 o->pixels_checked_out++;
1030 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
1037 evas_object_image_preload(Evas_Object *obj, Eina_Bool cancel)
1039 Evas_Object_Image *o;
1041 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1044 o = (Evas_Object_Image *)(obj->object_data);
1045 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1048 if (!o->engine_data)
1051 evas_object_inform_call_image_preloaded(obj);
1054 // FIXME: if already busy preloading, then dont request again until
1061 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
1071 obj->layer->evas->engine.func->image_data_preload_request(obj->layer->evas->engine.data.output,
1079 evas_object_image_data_copy_set(Evas_Object *obj, void *data)
1081 Evas_Object_Image *o;
1084 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1087 o = (Evas_Object_Image *)(obj->object_data);
1088 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1091 _evas_object_image_cleanup(obj, o);
1092 if ((o->cur.image.w <= 0) ||
1093 (o->cur.image.h <= 0)) return;
1095 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
1098 obj->layer->evas->engine.func->image_new_from_copied_data(obj->layer->evas->engine.data.output,
1109 obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1112 if (obj->layer->evas->engine.func->image_scale_hint_set)
1113 obj->layer->evas->engine.func->image_scale_hint_set
1114 (obj->layer->evas->engine.data.output,
1115 o->engine_data, o->scale_hint);
1116 if (obj->layer->evas->engine.func->image_content_hint_set)
1117 obj->layer->evas->engine.func->image_content_hint_set
1118 (obj->layer->evas->engine.data.output,
1119 o->engine_data, o->content_hint);
1120 if (obj->layer->evas->engine.func->image_stride_get)
1121 obj->layer->evas->engine.func->image_stride_get
1122 (obj->layer->evas->engine.data.output,
1123 o->engine_data, &stride);
1125 stride = o->cur.image.w * 4;
1126 o->cur.image.stride = stride;
1128 o->pixels_checked_out = 0;
1129 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
1133 evas_object_image_data_update_add(Evas_Object *obj, int x, int y, int w, int h)
1135 Evas_Object_Image *o;
1138 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1141 o = (Evas_Object_Image *)(obj->object_data);
1142 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1145 RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, o->cur.image.w, o->cur.image.h);
1146 if ((w <= 0) || (h <= 0)) return;
1147 NEW_RECT(r, x, y, w, h);
1148 if (r) o->pixel_updates = eina_list_append(o->pixel_updates, r);
1150 evas_object_change(obj);
1154 evas_object_image_alpha_set(Evas_Object *obj, Eina_Bool has_alpha)
1156 Evas_Object_Image *o;
1158 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1161 o = (Evas_Object_Image *)(obj->object_data);
1162 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1165 if ((o->preloading) && (o->engine_data))
1168 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
1172 if (((has_alpha) && (o->cur.has_alpha)) ||
1173 ((!has_alpha) && (!o->cur.has_alpha)))
1175 o->cur.has_alpha = has_alpha;
1181 obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1184 if (obj->layer->evas->engine.func->image_scale_hint_set)
1185 obj->layer->evas->engine.func->image_scale_hint_set
1186 (obj->layer->evas->engine.data.output,
1187 o->engine_data, o->scale_hint);
1188 if (obj->layer->evas->engine.func->image_content_hint_set)
1189 obj->layer->evas->engine.func->image_content_hint_set
1190 (obj->layer->evas->engine.data.output,
1191 o->engine_data, o->content_hint);
1192 if (obj->layer->evas->engine.func->image_stride_get)
1193 obj->layer->evas->engine.func->image_stride_get
1194 (obj->layer->evas->engine.data.output,
1195 o->engine_data, &stride);
1197 stride = o->cur.image.w * 4;
1198 o->cur.image.stride = stride;
1200 evas_object_image_data_update_add(obj, 0, 0, o->cur.image.w, o->cur.image.h);
1201 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
1206 evas_object_image_alpha_get(const Evas_Object *obj)
1208 Evas_Object_Image *o;
1210 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1213 o = (Evas_Object_Image *)(obj->object_data);
1214 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1217 return o->cur.has_alpha;
1221 evas_object_image_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth_scale)
1223 Evas_Object_Image *o;
1225 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1228 o = (Evas_Object_Image *)(obj->object_data);
1229 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1232 if (((smooth_scale) && (o->cur.smooth_scale)) ||
1233 ((!smooth_scale) && (!o->cur.smooth_scale)))
1235 o->cur.smooth_scale = smooth_scale;
1237 evas_object_change(obj);
1241 evas_object_image_smooth_scale_get(const Evas_Object *obj)
1243 Evas_Object_Image *o;
1245 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1248 o = (Evas_Object_Image *)(obj->object_data);
1249 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1252 return o->cur.smooth_scale;
1256 evas_object_image_reload(Evas_Object *obj)
1258 Evas_Object_Image *o;
1260 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1263 o = (Evas_Object_Image *)(obj->object_data);
1264 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1267 if ((o->preloading) && (o->engine_data))
1270 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
1274 if ((!o->cur.file) ||
1275 (o->pixels_checked_out > 0)) return;
1277 o->engine_data = obj->layer->evas->engine.func->image_dirty_region(obj->layer->evas->engine.data.output, o->engine_data, 0, 0, o->cur.image.w, o->cur.image.h);
1278 evas_object_image_unload(obj, 1);
1279 evas_object_inform_call_image_unloaded(obj);
1280 evas_object_image_load(obj);
1281 o->prev.file = NULL;
1284 evas_object_change(obj);
1288 evas_object_image_save(const Evas_Object *obj, const char *file, const char *key, const char *flags)
1290 Evas_Object_Image *o;
1291 DATA32 *data = NULL;
1292 int quality = 80, compress = 9, ok = 0;
1295 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1298 o = (Evas_Object_Image *)(obj->object_data);
1299 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1303 if (!o->engine_data) return 0;
1304 o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1314 tflags = alloca(strlen(flags) + 1);
1315 strcpy(tflags, flags);
1319 pp = strchr(p, ' ');
1321 sscanf(p, "quality=%i", &quality);
1322 sscanf(p, "compress=%i", &compress);
1327 im = (RGBA_Image*) evas_cache_image_data(evas_common_image_cache_get(),
1332 EVAS_COLORSPACE_ARGB8888);
1335 if (o->cur.cspace == EVAS_COLORSPACE_ARGB8888)
1336 im->image.data = data;
1338 im->image.data = evas_object_image_data_convert_internal(o,
1340 EVAS_COLORSPACE_ARGB8888);
1343 ok = evas_common_save_image_to_file(im, file, key, quality, compress);
1345 if (o->cur.cspace != EVAS_COLORSPACE_ARGB8888)
1346 free(im->image.data);
1349 evas_cache_image_drop(&im->cache_entry);
1351 o->engine_data = obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
1358 evas_object_image_pixels_import(Evas_Object *obj, Evas_Pixel_Import_Source *pixels)
1360 Evas_Object_Image *o;
1362 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1365 o = (Evas_Object_Image *)(obj->object_data);
1366 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1369 _evas_object_image_cleanup(obj, o);
1370 if ((pixels->w != o->cur.image.w) || (pixels->h != o->cur.image.h)) return 0;
1371 switch (pixels->format)
1374 case EVAS_PIXEL_FORMAT_ARGB32:
1378 DATA32 *image_pixels = NULL;
1381 obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1386 /* FIXME: need to actualyl support this */
1387 /* memcpy(image_pixels, pixels->rows, o->cur.image.w * o->cur.image.h * 4);*/
1390 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
1395 obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1399 evas_object_change(obj);
1404 #ifdef BUILD_CONVERT_YUV
1405 case EVAS_PIXEL_FORMAT_YUV420P_601:
1409 DATA32 *image_pixels = NULL;
1412 obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1418 evas_common_convert_yuv_420p_601_rgba((DATA8 **) pixels->rows,
1419 (DATA8 *) image_pixels,
1424 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
1429 obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1433 evas_object_change(obj);
1446 evas_object_image_pixels_get_callback_set(Evas_Object *obj, Evas_Object_Image_Pixels_Get_Cb func, void *data)
1448 Evas_Object_Image *o;
1450 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1453 o = (Evas_Object_Image *)(obj->object_data);
1454 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1457 o->func.get_pixels = func;
1458 o->func.get_pixels_data = data;
1462 evas_object_image_pixels_dirty_set(Evas_Object *obj, Eina_Bool dirty)
1464 Evas_Object_Image *o;
1466 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1469 o = (Evas_Object_Image *)(obj->object_data);
1470 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1473 if (dirty) o->dirty_pixels = 1;
1474 else o->dirty_pixels = 0;
1476 evas_object_change(obj);
1480 evas_object_image_pixels_dirty_get(const Evas_Object *obj)
1482 Evas_Object_Image *o;
1484 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1487 o = (Evas_Object_Image *)(obj->object_data);
1488 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1491 if (o->dirty_pixels) return 1;
1496 evas_object_image_load_dpi_set(Evas_Object *obj, double dpi)
1498 Evas_Object_Image *o;
1500 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1503 o = (Evas_Object_Image *)(obj->object_data);
1504 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1507 if (dpi == o->load_opts.dpi) return;
1508 o->load_opts.dpi = dpi;
1511 evas_object_image_unload(obj, 0);
1512 evas_object_inform_call_image_unloaded(obj);
1513 evas_object_image_load(obj);
1515 evas_object_change(obj);
1520 evas_object_image_load_dpi_get(const Evas_Object *obj)
1522 Evas_Object_Image *o;
1524 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1527 o = (Evas_Object_Image *)(obj->object_data);
1528 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1531 return o->load_opts.dpi;
1535 evas_object_image_load_size_set(Evas_Object *obj, int w, int h)
1537 Evas_Object_Image *o;
1539 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1542 o = (Evas_Object_Image *)(obj->object_data);
1543 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1546 if ((o->load_opts.w == w) && (o->load_opts.h == h)) return;
1551 evas_object_image_unload(obj, 0);
1552 evas_object_inform_call_image_unloaded(obj);
1553 evas_object_image_load(obj);
1555 evas_object_change(obj);
1560 evas_object_image_load_size_get(const Evas_Object *obj, int *w, int *h)
1562 Evas_Object_Image *o;
1564 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1567 o = (Evas_Object_Image *)(obj->object_data);
1568 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1571 if (w) *w = o->load_opts.w;
1572 if (h) *h = o->load_opts.h;
1576 evas_object_image_load_scale_down_set(Evas_Object *obj, int scale_down)
1578 Evas_Object_Image *o;
1580 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1583 o = (Evas_Object_Image *)(obj->object_data);
1584 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1587 if (o->load_opts.scale_down_by == scale_down) return;
1588 o->load_opts.scale_down_by = scale_down;
1591 evas_object_image_unload(obj, 0);
1592 evas_object_inform_call_image_unloaded(obj);
1593 evas_object_image_load(obj);
1595 evas_object_change(obj);
1600 evas_object_image_load_scale_down_get(const Evas_Object *obj)
1602 Evas_Object_Image *o;
1604 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1607 o = (Evas_Object_Image *)(obj->object_data);
1608 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1611 return o->load_opts.scale_down_by;
1615 evas_object_image_load_region_set(Evas_Object *obj, int x, int y, int w, int h)
1617 Evas_Object_Image *o;
1619 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1622 o = (Evas_Object_Image *)(obj->object_data);
1623 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1626 if ((o->load_opts.region.x == x) && (o->load_opts.region.y == y) &&
1627 (o->load_opts.region.w == w) && (o->load_opts.region.h == h)) return;
1628 o->load_opts.region.x = x;
1629 o->load_opts.region.y = y;
1630 o->load_opts.region.w = w;
1631 o->load_opts.region.h = h;
1634 evas_object_image_unload(obj, 0);
1635 evas_object_inform_call_image_unloaded(obj);
1636 evas_object_image_load(obj);
1638 evas_object_change(obj);
1643 evas_object_image_load_region_get(const Evas_Object *obj, int *x, int *y, int *w, int *h)
1645 Evas_Object_Image *o;
1647 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1650 o = (Evas_Object_Image *)(obj->object_data);
1651 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1654 if (x) *x = o->load_opts.region.x;
1655 if (y) *y = o->load_opts.region.y;
1656 if (w) *w = o->load_opts.region.w;
1657 if (h) *h = o->load_opts.region.h;
1661 evas_object_image_load_orientation_set(Evas_Object *obj, Eina_Bool enable)
1663 Evas_Object_Image *o;
1665 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1668 o = (Evas_Object_Image *)(obj->object_data);
1669 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1672 o->load_opts.orientation = !!enable;
1676 evas_object_image_load_orientation_get(const Evas_Object *obj)
1678 Evas_Object_Image *o;
1680 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1683 o = (Evas_Object_Image *)(obj->object_data);
1684 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1687 return o->load_opts.orientation;
1691 evas_object_image_colorspace_set(Evas_Object *obj, Evas_Colorspace cspace)
1693 Evas_Object_Image *o;
1695 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1698 o = (Evas_Object_Image *)(obj->object_data);
1699 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1703 _evas_object_image_cleanup(obj, o);
1705 o->cur.cspace = cspace;
1707 obj->layer->evas->engine.func->image_colorspace_set(obj->layer->evas->engine.data.output,
1712 EAPI Evas_Colorspace
1713 evas_object_image_colorspace_get(const Evas_Object *obj)
1715 Evas_Object_Image *o;
1717 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1718 return EVAS_COLORSPACE_ARGB8888;
1720 o = (Evas_Object_Image *)(obj->object_data);
1721 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1722 return EVAS_COLORSPACE_ARGB8888;
1724 return o->cur.cspace;
1728 evas_object_image_video_surface_set(Evas_Object *obj, Evas_Video_Surface *surf)
1730 Evas_Object_Image *o;
1732 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1735 o = (Evas_Object_Image *)(obj->object_data);
1736 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1739 _evas_object_image_cleanup(obj, o);
1740 if (o->video_surface)
1742 o->video_surface = 0;
1743 obj->layer->evas->video_objects = eina_list_remove(obj->layer->evas->video_objects, obj);
1748 if (surf->version != EVAS_VIDEO_SURFACE_VERSION) return ;
1750 if (!surf->update_pixels ||
1757 o->created = EINA_TRUE;
1758 o->video_surface = 1;
1761 obj->layer->evas->video_objects = eina_list_append(obj->layer->evas->video_objects, obj);
1765 o->video_surface = 0;
1766 o->video.update_pixels = NULL;
1767 o->video.move = NULL;
1768 o->video.resize = NULL;
1769 o->video.hide = NULL;
1770 o->video.show = NULL;
1771 o->video.data = NULL;
1775 EAPI const Evas_Video_Surface *
1776 evas_object_image_video_surface_get(const Evas_Object *obj)
1778 Evas_Object_Image *o;
1780 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1783 o = (Evas_Object_Image *)(obj->object_data);
1784 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1787 if (!o->video_surface) return NULL;
1792 evas_object_image_native_surface_set(Evas_Object *obj, Evas_Native_Surface *surf)
1794 Evas_Object_Image *o;
1796 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1799 o = (Evas_Object_Image *)(obj->object_data);
1800 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1803 _evas_object_image_cleanup(obj, o);
1804 if (!obj->layer->evas->engine.func->image_native_set) return;
1806 ((surf->version < 2) ||
1807 (surf->version > EVAS_NATIVE_SURFACE_VERSION))) return;
1809 obj->layer->evas->engine.func->image_native_set(obj->layer->evas->engine.data.output,
1814 EAPI Evas_Native_Surface *
1815 evas_object_image_native_surface_get(const Evas_Object *obj)
1817 Evas_Object_Image *o;
1819 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1822 o = (Evas_Object_Image *)(obj->object_data);
1823 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1826 if (!obj->layer->evas->engine.func->image_native_get) return NULL;
1827 return obj->layer->evas->engine.func->image_native_get(obj->layer->evas->engine.data.output,
1832 evas_object_image_scale_hint_set(Evas_Object *obj, Evas_Image_Scale_Hint hint)
1834 Evas_Object_Image *o;
1836 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1839 o = (Evas_Object_Image *)(obj->object_data);
1840 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1843 if (o->scale_hint == hint) return;
1844 o->scale_hint = hint;
1849 if (obj->layer->evas->engine.func->image_scale_hint_set)
1850 obj->layer->evas->engine.func->image_scale_hint_set
1851 (obj->layer->evas->engine.data.output,
1852 o->engine_data, o->scale_hint);
1853 if (obj->layer->evas->engine.func->image_stride_get)
1854 obj->layer->evas->engine.func->image_stride_get
1855 (obj->layer->evas->engine.data.output,
1856 o->engine_data, &stride);
1858 stride = o->cur.image.w * 4;
1859 o->cur.image.stride = stride;
1863 EAPI Evas_Image_Scale_Hint
1864 evas_object_image_scale_hint_get(const Evas_Object *obj)
1866 Evas_Object_Image *o;
1868 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1869 return EVAS_IMAGE_SCALE_HINT_NONE;
1871 o = (Evas_Object_Image *)(obj->object_data);
1872 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1873 return EVAS_IMAGE_SCALE_HINT_NONE;
1875 return o->scale_hint;
1879 evas_object_image_content_hint_set(Evas_Object *obj, Evas_Image_Content_Hint hint)
1881 Evas_Object_Image *o;
1883 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1886 o = (Evas_Object_Image *)(obj->object_data);
1887 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1890 if (o->content_hint == hint) return;
1891 o->content_hint = hint;
1896 if (obj->layer->evas->engine.func->image_content_hint_set)
1897 obj->layer->evas->engine.func->image_content_hint_set
1898 (obj->layer->evas->engine.data.output,
1899 o->engine_data, o->content_hint);
1900 if (obj->layer->evas->engine.func->image_stride_get)
1901 obj->layer->evas->engine.func->image_stride_get
1902 (obj->layer->evas->engine.data.output,
1903 o->engine_data, &stride);
1905 stride = o->cur.image.w * 4;
1906 o->cur.image.stride = stride;
1911 evas_object_image_alpha_mask_set(Evas_Object *obj, Eina_Bool ismask)
1913 Evas_Object_Image *o;
1915 if (!ismask) return;
1917 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1920 o = (Evas_Object_Image *)(obj->object_data);
1921 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1925 /* Convert to A8 if not already */
1931 #define FRAME_MAX 1024
1932 EAPI Evas_Image_Content_Hint
1933 evas_object_image_content_hint_get(const Evas_Object *obj)
1935 Evas_Object_Image *o;
1937 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1938 return EVAS_IMAGE_CONTENT_HINT_NONE;
1940 o = (Evas_Object_Image *)(obj->object_data);
1941 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1942 return EVAS_IMAGE_CONTENT_HINT_NONE;
1944 return o->content_hint;
1948 evas_object_image_region_support_get(const Evas_Object *obj)
1950 Evas_Object_Image *o;
1952 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1955 o = (Evas_Object_Image *) (obj->object_data);
1956 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1960 return obj->layer->evas->engine.func->image_can_region_get(
1961 obj->layer->evas->engine.data.output,
1965 /* animated feature */
1967 evas_object_image_animated_get(const Evas_Object *obj)
1969 Evas_Object_Image *o;
1971 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1974 o = (Evas_Object_Image *)(obj->object_data);
1975 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1979 if (obj->layer->evas->engine.func->image_animated_get)
1980 return obj->layer->evas->engine.func->image_animated_get(obj->layer->evas->engine.data.output, o->engine_data);
1985 evas_object_image_animated_frame_count_get(const Evas_Object *obj)
1987 Evas_Object_Image *o;
1989 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1992 o = (Evas_Object_Image *)(obj->object_data);
1993 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1997 if (!evas_object_image_animated_get(obj)) return -1;
1998 if (obj->layer->evas->engine.func->image_animated_frame_count_get)
1999 return obj->layer->evas->engine.func->image_animated_frame_count_get(obj->layer->evas->engine.data.output, o->engine_data);
2003 EAPI Evas_Image_Animated_Loop_Hint
2004 evas_object_image_animated_loop_type_get(const Evas_Object *obj)
2006 Evas_Object_Image *o;
2008 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2009 return EVAS_IMAGE_ANIMATED_HINT_NONE;
2011 o = (Evas_Object_Image *)(obj->object_data);
2012 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2013 return EVAS_IMAGE_ANIMATED_HINT_NONE;
2016 if (!evas_object_image_animated_get(obj)) return EVAS_IMAGE_ANIMATED_HINT_NONE;
2018 if (obj->layer->evas->engine.func->image_animated_loop_type_get)
2019 return obj->layer->evas->engine.func->image_animated_loop_type_get(obj->layer->evas->engine.data.output, o->engine_data);
2020 return EVAS_IMAGE_ANIMATED_HINT_NONE;
2024 evas_object_image_animated_loop_count_get(const Evas_Object *obj)
2026 Evas_Object_Image *o;
2028 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2031 o = (Evas_Object_Image *)(obj->object_data);
2032 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2036 if (!evas_object_image_animated_get(obj)) return -1;
2038 if (obj->layer->evas->engine.func->image_animated_loop_count_get)
2039 return obj->layer->evas->engine.func->image_animated_loop_count_get(obj->layer->evas->engine.data.output, o->engine_data);
2044 evas_object_image_animated_frame_duration_get(const Evas_Object *obj, int start_frame, int frame_num)
2046 Evas_Object_Image *o;
2047 int frame_count = 0;
2049 if (start_frame < 1) return -1;
2050 if (frame_num < 0) return -1;
2052 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2055 o = (Evas_Object_Image *)(obj->object_data);
2056 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2060 if (!evas_object_image_animated_get(obj)) return -1;
2062 if (!obj->layer->evas->engine.func->image_animated_frame_count_get) return -1;
2064 frame_count = obj->layer->evas->engine.func->image_animated_frame_count_get(obj->layer->evas->engine.data.output, o->engine_data);
2066 if ((start_frame + frame_num) > frame_count) return -1;
2067 if (obj->layer->evas->engine.func->image_animated_frame_duration_get)
2068 return obj->layer->evas->engine.func->image_animated_frame_duration_get(obj->layer->evas->engine.data.output, o->engine_data, start_frame, frame_num);
2073 evas_object_image_animated_frame_set(Evas_Object *obj, int frame_index)
2075 Evas_Object_Image *o;
2076 int frame_count = 0;
2078 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2081 o = (Evas_Object_Image *)(obj->object_data);
2082 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2086 if (!o->cur.file) return;
2087 if (o->cur.frame == frame_index) return;
2089 if (!evas_object_image_animated_get(obj)) return;
2091 frame_count = evas_object_image_animated_frame_count_get(obj);
2093 /* limit the size of frame to FRAME_MAX */
2094 if ((frame_count > FRAME_MAX) || (frame_count < 0) || (frame_index > frame_count))
2097 if (!obj->layer->evas->engine.func->image_animated_frame_set) return;
2098 if (!obj->layer->evas->engine.func->image_animated_frame_set(obj->layer->evas->engine.data.output, o->engine_data, frame_index))
2101 o->prev.frame = o->cur.frame;
2102 o->cur.frame = frame_index;
2105 evas_object_change(obj);
2110 evas_image_cache_flush(Evas *e)
2112 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2116 e->engine.func->image_cache_flush(e->engine.data.output);
2120 evas_image_cache_reload(Evas *e)
2124 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2128 evas_image_cache_flush(e);
2129 EINA_INLIST_FOREACH(e->layers, layer)
2133 EINA_INLIST_FOREACH(layer->objects, obj)
2135 Evas_Object_Image *o;
2137 o = (Evas_Object_Image *)(obj->object_data);
2138 if (o->magic == MAGIC_OBJ_IMAGE)
2140 evas_object_image_unload(obj, 1);
2141 evas_object_inform_call_image_unloaded(obj);
2145 evas_image_cache_flush(e);
2146 EINA_INLIST_FOREACH(e->layers, layer)
2150 EINA_INLIST_FOREACH(layer->objects, obj)
2152 Evas_Object_Image *o;
2154 o = (Evas_Object_Image *)(obj->object_data);
2155 if (o->magic == MAGIC_OBJ_IMAGE)
2157 evas_object_image_load(obj);
2159 evas_object_change(obj);
2163 evas_image_cache_flush(e);
2167 evas_image_cache_set(Evas *e, int size)
2169 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2173 if (size < 0) size = 0;
2174 e->engine.func->image_cache_set(e->engine.data.output, size);
2178 evas_image_cache_get(const Evas *e)
2180 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2184 return e->engine.func->image_cache_get(e->engine.data.output);
2188 evas_image_max_size_get(const Evas *e, int *maxw, int *maxh)
2191 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2195 if (maxw) *maxw = 0xffff;
2196 if (maxh) *maxh = 0xffff;
2197 if (!e->engine.func->image_max_size_get) return EINA_FALSE;
2198 e->engine.func->image_max_size_get(e->engine.data.output, &w, &h);
2199 if (maxw) *maxw = w;
2200 if (maxh) *maxh = h;
2204 /* all nice and private */
2206 _proxy_unset(Evas_Object *proxy)
2208 Evas_Object_Image *o;
2210 o = proxy->object_data;
2211 if (!o->cur.source) return;
2213 o->cur.source->proxy.proxies = eina_list_remove(o->cur.source->proxy.proxies, proxy);
2215 o->cur.source = NULL;
2218 evas_map_free(o->cur.defmap);
2219 o->cur.defmap = NULL;
2225 _proxy_set(Evas_Object *proxy, Evas_Object *src)
2227 Evas_Object_Image *o;
2229 o = proxy->object_data;
2231 evas_object_image_file_set(proxy, NULL, NULL);
2233 o->cur.source = src;
2234 o->load_error = EVAS_LOAD_ERROR_NONE;
2236 src->proxy.proxies = eina_list_append(src->proxy.proxies, proxy);
2237 src->proxy.redraw = EINA_TRUE;
2240 /* Some moron just set a proxy on a proxy.
2241 * Give them some pixels. A random color
2244 _proxy_error(Evas_Object *proxy, void *context, void *output, void *surface,
2248 int r = rand() % 255;
2249 int g = rand() % 255;
2250 int b = rand() % 255;
2252 /* XXX: Eina log error or something I'm sure
2253 * If it bugs you, just fix it. Don't tell me */
2254 if (VERBOSE_PROXY_ERROR) printf("Err: Argh! Recursive proxies.\n");
2256 func = proxy->layer->evas->engine.func;
2257 func->context_color_set(output, context, r, g, b, 255);
2258 func->context_multiplier_unset(output, context);
2259 func->context_render_op_set(output, context, proxy->cur.render_op);
2260 func->rectangle_draw(output, context, surface, proxy->cur.geometry.x + x,
2261 proxy->cur.geometry.y + y,
2262 proxy->cur.geometry.w,
2263 proxy->cur.geometry.h);
2269 _proxy_subrender_recurse(Evas_Object *obj, Evas_Object *clip, void *output, void *surface, void *ctx, int x, int y)
2272 Evas *e = obj->layer->evas;
2274 if (obj->clip.clipees) return;
2275 if (!obj->cur.visible) return;
2276 if ((!clip) || (clip != obj->cur.clipper))
2278 if (!obj->cur.cache.clip.visible) return;
2279 if ((obj->cur.cache.clip.a == 0) &&
2280 (obj->cur.render_op == EVAS_RENDER_BLEND)) return;
2282 if ((obj->func->is_visible) && (!obj->func->is_visible(obj))) return;
2284 if (!obj->pre_render_done)
2285 obj->func->render_pre(obj);
2286 ctx = e->engine.func->context_new(output);
2287 if (obj->smart.smart)
2289 EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
2291 _proxy_subrender_recurse(obj2, clip, output, surface, ctx, x, y);
2296 obj->func->render(obj, output, ctx, surface, x, y);
2298 e->engine.func->context_free(output, ctx);
2303 * Render the source object when a proxy is set.
2305 * Used to force a draw if necessary, else just makes sures it's available.
2308 _proxy_subrender(Evas *e, Evas_Object *source)
2311 /* Evas_Object *obj2, *clip;*/
2314 if (!source) return;
2316 w = source->cur.geometry.w;
2317 h = source->cur.geometry.h;
2319 source->proxy.redraw = EINA_FALSE;
2321 /* We need to redraw surface then */
2322 if ((source->proxy.surface) &&
2323 ((source->proxy.w != w) || (source->proxy.h != h)))
2325 e->engine.func->image_map_surface_free(e->engine.data.output,
2326 source->proxy.surface);
2327 source->proxy.surface = NULL;
2330 /* FIXME: Hardcoded alpha 'on' */
2331 /* FIXME (cont): Should see if the object has alpha */
2332 if (!source->proxy.surface)
2334 source->proxy.surface = e->engine.func->image_map_surface_new
2335 (e->engine.data.output, w, h, 1);
2336 source->proxy.w = w;
2337 source->proxy.h = h;
2340 ctx = e->engine.func->context_new(e->engine.data.output);
2341 e->engine.func->context_color_set(e->engine.data.output, ctx, 0, 0, 0, 0);
2342 e->engine.func->context_render_op_set(e->engine.data.output, ctx, EVAS_RENDER_COPY);
2343 e->engine.func->rectangle_draw(e->engine.data.output, ctx,
2344 source->proxy.surface, 0, 0, w, h);
2345 e->engine.func->context_free(e->engine.data.output, ctx);
2347 ctx = e->engine.func->context_new(e->engine.data.output);
2348 evas_render_mapped(e, source, ctx, source->proxy.surface,
2349 -source->cur.geometry.x,
2350 -source->cur.geometry.y,
2351 1, 0, 0, e->output.w, e->output.h);
2352 e->engine.func->context_free(e->engine.data.output, ctx);
2353 source->proxy.surface = e->engine.func->image_dirty_region
2354 (e->engine.data.output, source->proxy.surface, 0, 0, w, h);
2356 ctx = e->engine.func->context_new(e->engine.data.output);
2357 if (source->smart.smart)
2359 clip = evas_object_smart_clipped_clipper_get(source);
2360 EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(source), obj2)
2362 _proxy_subrender_recurse(obj2, clip, e->engine.data.output,
2363 source->proxy.surface,
2365 -source->cur.geometry.x,
2366 -source->cur.geometry.y);
2371 if (!source->pre_render_done)
2372 source->func->render_pre(source);
2373 source->func->render(source, e->engine.data.output, ctx,
2374 source->proxy.surface,
2375 -source->cur.geometry.x,
2376 -source->cur.geometry.y);
2379 e->engine.func->context_free(e->engine.data.output, ctx);
2380 source->proxy.surface = e->engine.func->image_dirty_region
2381 (e->engine.data.output, source->proxy.surface, 0, 0, w, h);
2385 #if 0 // filtering disabled
2388 * Note that this is similar to proxy_subrender_recurse. It should be
2389 * possible to merge I guess
2392 image_filter_draw_under_recurse(Evas *e, Evas_Object *obj, Evas_Object *stop,
2393 void *output, void *ctx, void *surface,
2398 if (obj->clip.clipees) return;
2399 /* FIXME: Doing bounding box test */
2400 if (!evas_object_is_in_output_rect(obj, stop->cur.geometry.x,
2401 stop->cur.geometry.y,
2402 stop->cur.geometry.w,
2403 stop->cur.geometry.h))
2406 if (!evas_object_is_visible(obj)) return;
2407 obj->pre_render_done = 1;
2408 ctx = e->engine.func->context_new(output);
2410 if (obj->smart.smart)
2412 EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
2414 if (obj2 == stop) return;
2415 image_filter_draw_under_recurse(e, obj2, stop, output, surface,
2420 obj->func->render(obj, output, ctx, surface, x ,y);
2421 e->engine.func->context_free(output, ctx);
2425 * Draw all visible objects intersecting an object which are _beneath_ it.
2428 image_filter_draw_under(Evas *e, Evas_Object *stop, void *output, void *ctx, void *surface, int dx, int dy)
2433 x = stop->cur.geometry.x - dx;
2434 y = stop->cur.geometry.y - dy;
2436 EINA_INLIST_FOREACH(e->layers, lay)
2439 EINA_INLIST_FOREACH(lay->objects, obj)
2441 if (obj->delete_me) continue;
2442 if (obj == stop) return;
2443 /* FIXME: Do bounding box check */
2444 image_filter_draw_under_recurse(e, obj, stop, output, ctx,
2448 e->engine.func->image_dirty_region(output, surface, 0, 0, 300, 300);
2449 e->engine.func->output_flush(output);
2453 * Update the filtered object.
2455 * Creates a new context, and renders stuff (filtered) onto that.
2458 image_filter_update(Evas *e, Evas_Object *obj, void *src, int imagew, int imageh, int *outw, int *outh)
2462 Evas_Filter_Info *info;
2468 if (info->mode == EVAS_FILTER_MODE_BELOW)
2470 w = obj->cur.geometry.w;
2471 h = obj->cur.geometry.h;
2472 evas_filter_get_size(info, w, h, &imagew, &imageh, EINA_TRUE);
2477 evas_filter_get_size(info, imagew, imageh, &w, &h, EINA_FALSE);
2478 alpha = e->engine.func->image_alpha_get(e->engine.data.output, src);
2481 /* Certain filters may make alpha images anyway */
2482 if (alpha == EINA_FALSE) alpha = evas_filter_always_alpha(info);
2484 surface = e->engine.func->image_map_surface_new(e->engine.data.output, w, h,
2487 if (info->mode == EVAS_FILTER_MODE_BELOW)
2492 disw = obj->cur.geometry.w;
2493 dish = obj->cur.geometry.h;
2494 dx = (imagew - w) >> 1;
2495 dy = (imageh - h) >> 1;
2496 subsurface = e->engine.func->image_map_surface_new
2497 (e->engine.data.output, imagew, imageh, 1);
2498 ctx = e->engine.func->context_new(e->engine.data.output);
2499 e->engine.func->context_color_set(e->engine.data.output, ctx, 0, 255, 0, 255);
2500 e->engine.func->context_render_op_set(e->engine.data.output, ctx, EVAS_RENDER_COPY);
2501 e->engine.func->rectangle_draw(e->engine.data.output, ctx,
2502 subsurface, 0, 0, imagew, imageh);
2504 image_filter_draw_under(e, obj, e->engine.data.output, ctx,
2505 subsurface, dx, dy);
2507 e->engine.func->context_free(e->engine.data.output, ctx);
2509 ctx = e->engine.func->context_new(e->engine.data.output);
2511 e->engine.func->image_draw_filtered(e->engine.data.output,
2512 ctx, surface, subsurface, info);
2514 e->engine.func->context_free(e->engine.data.output, ctx);
2516 e->engine.func->image_map_surface_free(e->engine.data.output,
2521 ctx = e->engine.func->context_new(e->engine.data.output);
2522 e->engine.func->image_draw_filtered(e->engine.data.output,
2523 ctx, surface, src, info);
2524 e->engine.func->context_free(e->engine.data.output, ctx);
2527 e->engine.func->image_dirty_region(e->engine.data.output, surface,
2529 if (outw) *outw = w;
2530 if (outh) *outh = h;
2531 return e->engine.func->image_filtered_save(src, surface,
2538 evas_object_image_unload(Evas_Object *obj, Eina_Bool dirty)
2540 Evas_Object_Image *o;
2542 o = (Evas_Object_Image *)(obj->object_data);
2544 if ((!o->cur.file) ||
2545 (o->pixels_checked_out > 0)) return;
2549 o->engine_data = obj->layer->evas->engine.func->image_dirty_region
2550 (obj->layer->evas->engine.data.output,
2553 o->cur.image.w, o->cur.image.h);
2560 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
2564 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
2567 o->engine_data = NULL;
2568 o->load_error = EVAS_LOAD_ERROR_NONE;
2569 o->cur.has_alpha = 1;
2570 o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
2573 o->cur.image.stride = 0;
2577 evas_object_image_load(Evas_Object *obj)
2579 Evas_Object_Image *o;
2580 Evas_Image_Load_Opts lo;
2582 o = (Evas_Object_Image *)(obj->object_data);
2583 if (o->engine_data) return;
2585 lo.scale_down_by = o->load_opts.scale_down_by;
2586 lo.dpi = o->load_opts.dpi;
2587 lo.w = o->load_opts.w;
2588 lo.h = o->load_opts.h;
2589 lo.region.x = o->load_opts.region.x;
2590 lo.region.y = o->load_opts.region.y;
2591 lo.region.w = o->load_opts.region.w;
2592 lo.region.h = o->load_opts.region.h;
2593 lo.orientation = o->load_opts.orientation;
2594 o->engine_data = obj->layer->evas->engine.func->image_load
2595 (obj->layer->evas->engine.data.output,
2605 obj->layer->evas->engine.func->image_size_get
2606 (obj->layer->evas->engine.data.output,
2607 o->engine_data, &w, &h);
2608 if (obj->layer->evas->engine.func->image_stride_get)
2609 obj->layer->evas->engine.func->image_stride_get
2610 (obj->layer->evas->engine.data.output,
2611 o->engine_data, &stride);
2614 o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get
2615 (obj->layer->evas->engine.data.output,
2617 o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get
2618 (obj->layer->evas->engine.data.output,
2622 o->cur.image.stride = stride;
2626 o->load_error = EVAS_LOAD_ERROR_GENERIC;
2631 evas_object_image_figure_x_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret)
2635 w = ((size * obj->layer->evas->output.w) /
2636 (Evas_Coord)obj->layer->evas->viewport.w);
2637 if (size <= 0) size = 1;
2640 while (start - size > 0) start -= size;
2644 while (start < 0) start += size;
2646 start = ((start * obj->layer->evas->output.w) /
2647 (Evas_Coord)obj->layer->evas->viewport.w);
2653 evas_object_image_figure_y_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret)
2657 h = ((size * obj->layer->evas->output.h) /
2658 (Evas_Coord)obj->layer->evas->viewport.h);
2659 if (size <= 0) size = 1;
2662 while (start - size > 0) start -= size;
2666 while (start < 0) start += size;
2668 start = ((start * obj->layer->evas->output.h) /
2669 (Evas_Coord)obj->layer->evas->viewport.h);
2675 evas_object_image_init(Evas_Object *obj)
2677 /* alloc image ob, setup methods and default values */
2678 obj->object_data = evas_object_image_new();
2679 /* set up default settings for this kind of object */
2680 obj->cur.color.r = 255;
2681 obj->cur.color.g = 255;
2682 obj->cur.color.b = 255;
2683 obj->cur.color.a = 255;
2684 obj->cur.geometry.x = 0;
2685 obj->cur.geometry.y = 0;
2686 obj->cur.geometry.w = 0;
2687 obj->cur.geometry.h = 0;
2689 obj->cur.anti_alias = 0;
2690 obj->cur.render_op = EVAS_RENDER_BLEND;
2691 /* set up object-specific settings */
2692 obj->prev = obj->cur;
2693 /* set up methods (compulsory) */
2694 obj->func = &object_func;
2699 evas_object_image_new(void)
2701 Evas_Object_Image *o;
2703 /* alloc obj private data */
2704 EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_image", Evas_Object_Image, 16, NULL);
2705 o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Image);
2706 if (!o) return NULL;
2707 EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Image);
2708 o->magic = MAGIC_OBJ_IMAGE;
2711 o->cur.smooth_scale = 1;
2712 o->cur.border.fill = 1;
2713 o->cur.border.scale = 1.0;
2714 o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
2715 o->cur.spread = EVAS_TEXTURE_REPEAT;
2716 o->cur.opaque_valid = 0;
2717 o->cur.source = NULL;
2724 evas_object_image_free(Evas_Object *obj)
2726 Evas_Object_Image *o;
2729 /* frees private object data. very simple here */
2730 o = (Evas_Object_Image *)(obj->object_data);
2731 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2736 if (o->cur.file) eina_stringshare_del(o->cur.file);
2737 if (o->cur.key) eina_stringshare_del(o->cur.key);
2738 if (o->cur.source) _proxy_unset(obj);
2744 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
2748 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
2751 if (o->video_surface)
2753 o->video_surface = 0;
2754 obj->layer->evas->video_objects = eina_list_remove(obj->layer->evas->video_objects, obj);
2756 o->engine_data = NULL;
2758 EINA_LIST_FREE(o->pixel_updates, r)
2759 eina_rectangle_free(r);
2760 EVAS_MEMPOOL_FREE(_mp_obj, o);
2764 evas_object_image_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
2766 Evas_Object_Image *o;
2767 int imagew, imageh, uvw, uvh;
2770 /* render object to surface with context, and offset by x,y */
2771 o = (Evas_Object_Image *)(obj->object_data);
2773 if ((o->cur.fill.w < 1) || (o->cur.fill.h < 1))
2774 return; /* no error message, already printed in pre_render */
2777 if (o->proxyrendering)
2779 _proxy_error(obj, context, output, surface, x, y);
2783 /* We are displaying the overlay */
2784 if (o->video_visible)
2786 /* Create a transparent rectangle */
2787 obj->layer->evas->engine.func->context_color_set(output,
2790 obj->layer->evas->engine.func->context_multiplier_unset(output,
2792 obj->layer->evas->engine.func->context_render_op_set(output, context,
2794 obj->layer->evas->engine.func->rectangle_draw(output,
2797 obj->cur.geometry.x + x,
2798 obj->cur.geometry.y + y,
2799 obj->cur.geometry.w,
2800 obj->cur.geometry.h);
2805 obj->layer->evas->engine.func->context_color_set(output,
2807 255, 255, 255, 255);
2809 if ((obj->cur.cache.clip.r == 255) &&
2810 (obj->cur.cache.clip.g == 255) &&
2811 (obj->cur.cache.clip.b == 255) &&
2812 (obj->cur.cache.clip.a == 255))
2814 obj->layer->evas->engine.func->context_multiplier_unset(output,
2818 obj->layer->evas->engine.func->context_multiplier_set(output,
2820 obj->cur.cache.clip.r,
2821 obj->cur.cache.clip.g,
2822 obj->cur.cache.clip.b,
2823 obj->cur.cache.clip.a);
2825 obj->layer->evas->engine.func->context_render_op_set(output, context,
2826 obj->cur.render_op);
2830 pixels = o->engine_data;
2831 imagew = o->cur.image.w;
2832 imageh = o->cur.image.h;
2836 else if (o->cur.source->proxy.surface && !o->cur.source->proxy.redraw)
2838 pixels = o->cur.source->proxy.surface;
2839 imagew = o->cur.source->proxy.w;
2840 imageh = o->cur.source->proxy.h;
2844 else if (o->cur.source->type == o_type &&
2845 ((Evas_Object_Image *)o->cur.source->object_data)->engine_data)
2847 Evas_Object_Image *oi;
2848 oi = o->cur.source->object_data;
2849 pixels = oi->engine_data;
2850 imagew = oi->cur.image.w;
2851 imageh = oi->cur.image.h;
2852 uvw = o->cur.source->cur.geometry.w;
2853 uvh = o->cur.source->cur.geometry.h;
2857 o->proxyrendering = 1;
2858 _proxy_subrender(obj->layer->evas, o->cur.source);
2859 pixels = o->cur.source->proxy.surface;
2860 imagew = o->cur.source->proxy.w;
2861 imageh = o->cur.source->proxy.h;
2864 o->proxyrendering = 0;
2867 #if 0 // filtering disabled
2868 /* Now check/update filter */
2869 if (obj->filter && obj->filter->filter)
2871 Filtered_Image *fi = NULL;
2872 //printf("%p has filter: %s\n", obj,obj->filter->dirty?"dirty":"clean");
2873 if (obj->filter->dirty)
2875 if (obj->filter->mode != EVAS_FILTER_MODE_BELOW)
2880 if (obj->filter->key) free(obj->filter->key);
2881 obj->filter->key = NULL;
2882 obj->filter->len = 0;
2883 key = evas_filter_key_get(obj->filter, &len);
2886 obj->filter->key = key;
2887 obj->filter->len = len;
2888 fi = obj->layer->evas->engine.func->image_filtered_get
2889 (o->engine_data, key, len);
2890 if (obj->filter->cached && fi != obj->filter->cached)
2892 obj->layer->evas->engine.func->image_filtered_free
2893 (o->engine_data, obj->filter->cached);
2894 obj->filter->cached = NULL;
2898 else if (obj->filter->cached)
2900 obj->layer->evas->engine.func->image_filtered_free
2901 (o->engine_data, obj->filter->cached);
2904 fi = image_filter_update(obj->layer->evas, obj, pixels,
2905 imagew, imageh, &imagew, &imageh);
2907 obj->filter->dirty = 0;
2908 obj->filter->cached = fi;
2912 fi = obj->filter->cached;
2920 Evas_Coord idw, idh, idx, idy;
2924 if (o->dirty_pixels)
2926 if (o->func.get_pixels)
2928 // Set img object for direct rendering optimization
2929 // Check for image w/h against image geometry w/h
2930 // Check for image color r,g,b,a = {255,255,255,255}
2931 // Check and make sure that there are no maps.
2932 if ( (obj->cur.geometry.w == o->cur.image.w) &&
2933 (obj->cur.geometry.h == o->cur.image.h) &&
2934 (obj->cur.color.r == 255) &&
2935 (obj->cur.color.g == 255) &&
2936 (obj->cur.color.b == 255) &&
2937 (obj->cur.color.a == 255) &&
2940 if (obj->layer->evas->engine.func->gl_img_obj_set)
2942 obj->layer->evas->engine.func->gl_img_obj_set(output, obj, o->cur.has_alpha);
2947 o->func.get_pixels(o->func.get_pixels_data, obj);
2948 if (o->engine_data != pixels)
2949 pixels = o->engine_data;
2950 o->engine_data = obj->layer->evas->engine.func->image_dirty_region
2951 (obj->layer->evas->engine.data.output, o->engine_data,
2952 0, 0, o->cur.image.w, o->cur.image.h);
2954 o->dirty_pixels = 0;
2956 if ((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap))
2958 evas_object_map_update(obj, x, y, imagew, imageh, uvw, uvh);
2960 obj->layer->evas->engine.func->image_map_draw
2961 (output, context, surface, pixels, obj->spans,
2962 o->cur.smooth_scale | obj->cur.map->smooth, 0);
2966 obj->layer->evas->engine.func->image_scale_hint_set(output,
2969 /* This is technically a bug here: If the value is recreated
2970 * (which is returned)it may be a new object, however exactly 0
2971 * of all the evas engines do this. */
2972 obj->layer->evas->engine.func->image_border_set(output, pixels,
2973 o->cur.border.l, o->cur.border.r,
2974 o->cur.border.t, o->cur.border.b);
2975 idx = evas_object_image_figure_x_fill(obj, o->cur.fill.x, o->cur.fill.w, &idw);
2976 idy = evas_object_image_figure_y_fill(obj, o->cur.fill.y, o->cur.fill.h, &idh);
2977 if (idw < 1) idw = 1;
2978 if (idh < 1) idh = 1;
2979 if (idx > 0) idx -= idw;
2980 if (idy > 0) idy -= idh;
2981 while ((int)idx < obj->cur.geometry.w)
2988 if ((o->cur.fill.w == obj->cur.geometry.w) &&
2989 (o->cur.fill.x == 0))
2992 iw = obj->cur.geometry.w;
2995 iw = ((int)(idx + idw)) - ix;
2996 while ((int)idy < obj->cur.geometry.h)
3001 if ((o->cur.fill.h == obj->cur.geometry.h) &&
3002 (o->cur.fill.y == 0))
3004 ih = obj->cur.geometry.h;
3008 ih = ((int)(idy + idh)) - iy;
3009 if ((o->cur.border.l == 0) &&
3010 (o->cur.border.r == 0) &&
3011 (o->cur.border.t == 0) &&
3012 (o->cur.border.b == 0) &&
3013 (o->cur.border.fill != 0))
3014 obj->layer->evas->engine.func->image_draw(output,
3021 obj->cur.geometry.x + ix + x,
3022 obj->cur.geometry.y + iy + y,
3024 o->cur.smooth_scale);
3027 int inx, iny, inw, inh, outx, outy, outw, outh;
3028 int bl, br, bt, bb, bsl, bsr, bst, bsb;
3029 int imw, imh, ox, oy;
3031 ox = obj->cur.geometry.x + ix + x;
3032 oy = obj->cur.geometry.y + iy + y;
3035 bl = o->cur.border.l;
3036 br = o->cur.border.r;
3037 bt = o->cur.border.t;
3038 bb = o->cur.border.b;
3044 if ((bl + br) > imw)
3054 if ((bt + bb) > imh)
3059 if (o->cur.border.scale != 1.0)
3061 bsl = ((double)bl * o->cur.border.scale);
3062 bsr = ((double)br * o->cur.border.scale);
3063 bst = ((double)bt * o->cur.border.scale);
3064 bsb = ((double)bb * o->cur.border.scale);
3068 bsl = bl; bsr = br; bst = bt; bsb = bb;
3074 outx = ox; outy = oy;
3075 outw = bsl; outh = bst;
3076 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3080 inw = imw - bl - br; inh = bt;
3081 outx = ox + bsl; outy = oy;
3082 outw = iw - bsl - bsr; outh = bst;
3083 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3086 inx = imw - br; iny = 0;
3088 outx = ox + iw - bsr; outy = oy;
3089 outw = bsr; outh = bst;
3090 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3094 inw = bl; inh = imh - bt - bb;
3095 outx = ox; outy = oy + bst;
3096 outw = bsl; outh = ih - bst - bsb;
3097 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3100 if (o->cur.border.fill > EVAS_BORDER_FILL_NONE)
3103 inw = imw - bl - br; inh = imh - bt - bb;
3104 outx = ox + bsl; outy = oy + bst;
3105 outw = iw - bsl - bsr; outh = ih - bst - bsb;
3106 if ((o->cur.border.fill == EVAS_BORDER_FILL_SOLID) &&
3107 (obj->cur.cache.clip.a == 255) &&
3108 (obj->cur.render_op == EVAS_RENDER_BLEND))
3110 obj->layer->evas->engine.func->context_render_op_set(output, context,
3112 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3113 obj->layer->evas->engine.func->context_render_op_set(output, context,
3114 obj->cur.render_op);
3117 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3121 inx = imw - br; iny = bt;
3122 inw = br; inh = imh - bt - bb;
3123 outx = ox + iw - bsr; outy = oy + bst;
3124 outw = bsr; outh = ih - bst - bsb;
3125 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3128 inx = 0; iny = imh - bb;
3130 outx = ox; outy = oy + ih - bsb;
3131 outw = bsl; outh = bsb;
3132 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3135 inx = bl; iny = imh - bb;
3136 inw = imw - bl - br; inh = bb;
3137 outx = ox + bsl; outy = oy + ih - bsb;
3138 outw = iw - bsl - bsr; outh = bsb;
3139 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3142 inx = imw - br; iny = imh - bb;
3144 outx = ox + iw - bsr; outy = oy + ih - bsb;
3145 outw = bsr; outh = bsb;
3146 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3149 if (dobreak_h) break;
3153 if (dobreak_w) break;
3160 if (obj->layer->evas->engine.func->gl_img_obj_set)
3162 obj->layer->evas->engine.func->gl_img_obj_set(output, NULL, 0);
3170 evas_object_image_render_pre(Evas_Object *obj)
3172 Evas_Object_Image *o;
3173 int is_v = 0, was_v = 0;
3176 /* dont pre-render the obj twice! */
3177 if (obj->pre_render_done) return;
3178 obj->pre_render_done = 1;
3179 /* pre-render phase. this does anything an object needs to do just before */
3180 /* rendering. this could mean loading the image data, retrieving it from */
3181 /* elsewhere, decoding video etc. */
3182 /* then when this is done the object needs to figure if it changed and */
3183 /* if so what and where and add the appropriate redraw rectangles */
3184 o = (Evas_Object_Image *)(obj->object_data);
3185 e = obj->layer->evas;
3187 if ((o->cur.fill.w < 1) || (o->cur.fill.h < 1))
3189 ERR("%p has invalid fill size: %dx%d. Ignored",
3190 obj, o->cur.fill.w, o->cur.fill.h);
3194 /* if someone is clipping this obj - go calculate the clipper */
3195 if (obj->cur.clipper)
3197 if (obj->cur.cache.clip.dirty)
3198 evas_object_clip_recalc(obj->cur.clipper);
3199 obj->cur.clipper->func->render_pre(obj->cur.clipper);
3201 /* Proxy: Do it early */
3202 if (o->cur.source &&
3203 (o->cur.source->proxy.redraw || o->cur.source->changed))
3205 /* XXX: Do I need to sort out the map here? */
3206 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3210 /* now figure what changed and add draw rects */
3211 /* if it just became visible or invisible */
3212 is_v = evas_object_is_visible(obj);
3213 was_v = evas_object_was_visible(obj);
3216 evas_object_render_pre_visible_change(&e->clip_changes, obj, is_v, was_v);
3217 if (!o->pixel_updates) goto done;
3219 if (obj->changed_map)
3221 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3224 /* it's not visible - we accounted for it appearing or not so just abort */
3225 if (!is_v) goto done;
3226 /* clipper changed this is in addition to anything else for obj */
3227 evas_object_render_pre_clipper_change(&e->clip_changes, obj);
3228 /* if we restacked (layer or just within a layer) and don't clip anyone */
3231 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3232 if (!o->pixel_updates) goto done;
3234 /* if it changed color */
3235 if ((obj->cur.color.r != obj->prev.color.r) ||
3236 (obj->cur.color.g != obj->prev.color.g) ||
3237 (obj->cur.color.b != obj->prev.color.b) ||
3238 (obj->cur.color.a != obj->prev.color.a))
3240 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3241 if (!o->pixel_updates) goto done;
3243 /* if it changed render op */
3244 if (obj->cur.render_op != obj->prev.render_op)
3246 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3247 if (!o->pixel_updates) goto done;
3249 /* if it changed anti_alias */
3250 if (obj->cur.anti_alias != obj->prev.anti_alias)
3252 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3253 if (!o->pixel_updates) goto done;
3257 if (((o->cur.file) && (!o->prev.file)) ||
3258 ((!o->cur.file) && (o->prev.file)) ||
3259 ((o->cur.key) && (!o->prev.key)) ||
3260 ((!o->cur.key) && (o->prev.key))
3263 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3264 if (!o->pixel_updates) goto done;
3266 if ((o->cur.image.w != o->prev.image.w) ||
3267 (o->cur.image.h != o->prev.image.h) ||
3268 (o->cur.has_alpha != o->prev.has_alpha) ||
3269 (o->cur.cspace != o->prev.cspace) ||
3270 (o->cur.smooth_scale != o->prev.smooth_scale))
3272 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3273 if (!o->pixel_updates) goto done;
3275 if ((o->cur.border.l != o->prev.border.l) ||
3276 (o->cur.border.r != o->prev.border.r) ||
3277 (o->cur.border.t != o->prev.border.t) ||
3278 (o->cur.border.b != o->prev.border.b) ||
3279 (o->cur.border.fill != o->prev.border.fill) ||
3280 (o->cur.border.scale != o->prev.border.scale))
3282 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3283 if (!o->pixel_updates) goto done;
3285 if (o->dirty_pixels)
3287 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3288 if (!o->pixel_updates) goto done;
3290 if (o->cur.frame != o->prev.frame)
3292 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3293 if (!o->pixel_updates) goto done;
3297 /* if it changed geometry - and obviously not visibility or color */
3298 /* calculate differences since we have a constant color fill */
3299 /* we really only need to update the differences */
3300 #if 0 // XXX: maybe buggy?
3301 if (((obj->cur.geometry.x != obj->prev.geometry.x) ||
3302 (obj->cur.geometry.y != obj->prev.geometry.y) ||
3303 (obj->cur.geometry.w != obj->prev.geometry.w) ||
3304 (obj->cur.geometry.h != obj->prev.geometry.h)) &&
3305 (o->cur.fill.w == o->prev.fill.w) &&
3306 (o->cur.fill.h == o->prev.fill.h) &&
3307 ((o->cur.fill.x + obj->cur.geometry.x) == (o->prev.fill.x + obj->prev.geometry.x)) &&
3308 ((o->cur.fill.y + obj->cur.geometry.y) == (o->prev.fill.y + obj->prev.geometry.y)) &&
3312 evas_rects_return_difference_rects(&e->clip_changes,
3313 obj->cur.geometry.x,
3314 obj->cur.geometry.y,
3315 obj->cur.geometry.w,
3316 obj->cur.geometry.h,
3317 obj->prev.geometry.x,
3318 obj->prev.geometry.y,
3319 obj->prev.geometry.w,
3320 obj->prev.geometry.h);
3321 if (!o->pixel_updates) goto done;
3324 if (((obj->cur.geometry.x != obj->prev.geometry.x) ||
3325 (obj->cur.geometry.y != obj->prev.geometry.y) ||
3326 (obj->cur.geometry.w != obj->prev.geometry.w) ||
3327 (obj->cur.geometry.h != obj->prev.geometry.h))
3330 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3331 if (!o->pixel_updates) goto done;
3335 if ((o->cur.fill.x != o->prev.fill.x) ||
3336 (o->cur.fill.y != o->prev.fill.y) ||
3337 (o->cur.fill.w != o->prev.fill.w) ||
3338 (o->cur.fill.h != o->prev.fill.h))
3340 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3341 if (!o->pixel_updates) goto done;
3343 if (o->pixel_updates)
3345 if ((o->cur.border.l == 0) &&
3346 (o->cur.border.r == 0) &&
3347 (o->cur.border.t == 0) &&
3348 (o->cur.border.b == 0) &&
3349 (o->cur.image.w > 0) &&
3350 (o->cur.image.h > 0) &&
3351 (!((obj->cur.map) && (obj->cur.usemap))))
3355 EINA_LIST_FREE(o->pixel_updates, rr)
3357 Evas_Coord idw, idh, idx, idy;
3360 e->engine.func->image_dirty_region(e->engine.data.output, o->engine_data, rr->x, rr->y, rr->w, rr->h);
3362 idx = evas_object_image_figure_x_fill(obj, o->cur.fill.x, o->cur.fill.w, &idw);
3363 idy = evas_object_image_figure_y_fill(obj, o->cur.fill.y, o->cur.fill.h, &idh);
3365 if (idw < 1) idw = 1;
3366 if (idh < 1) idh = 1;
3367 if (idx > 0) idx -= idw;
3368 if (idy > 0) idy -= idh;
3369 while (idx < obj->cur.geometry.w)
3375 w = ((int)(idx + idw)) - x;
3376 while (idy < obj->cur.geometry.h)
3381 h = ((int)(idy + idh)) - y;
3383 r.x = (rr->x * w) / o->cur.image.w;
3384 r.y = (rr->y * h) / o->cur.image.h;
3385 r.w = ((rr->w * w) + (o->cur.image.w * 2) - 1) / o->cur.image.w;
3386 r.h = ((rr->h * h) + (o->cur.image.h * 2) - 1) / o->cur.image.h;
3387 r.x += obj->cur.geometry.x + x;
3388 r.y += obj->cur.geometry.y + y;
3389 RECTS_CLIP_TO_RECT(r.x, r.y, r.w, r.h,
3390 obj->cur.cache.clip.x, obj->cur.cache.clip.y,
3391 obj->cur.cache.clip.w, obj->cur.cache.clip.h);
3392 evas_add_rect(&e->clip_changes, r.x, r.y, r.w, r.h);
3398 eina_rectangle_free(rr);
3406 EINA_LIST_FREE(o->pixel_updates, r)
3407 eina_rectangle_free(r);
3408 e->engine.func->image_dirty_region(e->engine.data.output, o->engine_data, 0, 0, o->cur.image.w, o->cur.image.h);
3409 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3414 #if 0 // filtering disabled
3415 if (obj->filter && obj->filter->dirty)
3417 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3420 /* it obviously didn't change - add a NO obscure - this "unupdates" this */
3421 /* area so if there were updates for it they get wiped. don't do it if we */
3422 /* aren't fully opaque and we are visible */
3423 if (evas_object_is_visible(obj) &&
3424 evas_object_is_opaque(obj))
3426 Evas_Coord x, y, w, h;
3428 x = obj->cur.cache.clip.x;
3429 y = obj->cur.cache.clip.y;
3430 w = obj->cur.cache.clip.w;
3431 h = obj->cur.cache.clip.h;
3432 if (obj->cur.clipper)
3434 RECTS_CLIP_TO_RECT(x, y, w, h,
3435 obj->cur.clipper->cur.cache.clip.x,
3436 obj->cur.clipper->cur.cache.clip.y,
3437 obj->cur.clipper->cur.cache.clip.w,
3438 obj->cur.clipper->cur.cache.clip.h);
3440 e->engine.func->output_redraws_rect_del(e->engine.data.output,
3444 evas_object_render_pre_effect_updates(&e->clip_changes, obj, is_v, was_v);
3448 evas_object_image_render_post(Evas_Object *obj)
3450 Evas_Object_Image *o;
3453 /* this moves the current data to the previous state parts of the object */
3454 /* in whatever way is safest for the object. also if we don't need object */
3455 /* data anymore we can free it if the object deems this is a good idea */
3456 o = (Evas_Object_Image *)(obj->object_data);
3457 /* remove those pesky changes */
3458 evas_object_clip_changes_clean(obj);
3459 EINA_LIST_FREE(o->pixel_updates, r)
3460 eina_rectangle_free(r);
3461 /* move cur to prev safely for object data */
3462 evas_object_cur_prev(obj);
3465 /* FIXME: copy strings across */
3468 static unsigned int evas_object_image_id_get(Evas_Object *obj)
3470 Evas_Object_Image *o;
3472 o = (Evas_Object_Image *)(obj->object_data);
3474 return MAGIC_OBJ_IMAGE;
3477 static unsigned int evas_object_image_visual_id_get(Evas_Object *obj)
3479 Evas_Object_Image *o;
3481 o = (Evas_Object_Image *)(obj->object_data);
3483 return MAGIC_OBJ_IMAGE;
3486 static void *evas_object_image_engine_data_get(Evas_Object *obj)
3488 Evas_Object_Image *o;
3490 o = (Evas_Object_Image *)(obj->object_data);
3491 if (!o) return NULL;
3492 return o->engine_data;
3496 evas_object_image_is_opaque(Evas_Object *obj)
3498 Evas_Object_Image *o;
3500 /* this returns 1 if the internal object data implies that the object is */
3501 /* currently fully opaque over the entire rectangle it occupies */
3502 o = (Evas_Object_Image *)(obj->object_data);
3503 /* disable caching due tyo maps screwing with this
3504 o->cur.opaque_valid = 0;
3505 if (o->cur.opaque_valid)
3507 if (!o->cur.opaque) return 0;
3513 /* disable caching */
3514 /* o->cur.opaque_valid = 1; */
3515 if ((o->cur.fill.w < 1) || (o->cur.fill.h < 1))
3516 return o->cur.opaque;
3517 if (((o->cur.border.l != 0) ||
3518 (o->cur.border.r != 0) ||
3519 (o->cur.border.t != 0) ||
3520 (o->cur.border.b != 0)) &&
3521 (!o->cur.border.fill)) return o->cur.opaque;
3522 if (!o->engine_data) return o->cur.opaque;
3528 o->cur.opaque = evas_object_is_opaque(o->cur.source);
3529 return o->cur.opaque; /* FIXME: Should go poke at the object */
3531 if (o->cur.has_alpha)
3534 return o->cur.opaque;
3536 if ((obj->cur.map) && (obj->cur.usemap))
3538 Evas_Map *m = obj->cur.map;
3540 if ((m->points[0].a == 255) &&
3541 (m->points[1].a == 255) &&
3542 (m->points[2].a == 255) &&
3543 (m->points[3].a == 255))
3546 ((m->points[0].x == m->points[3].x) &&
3547 (m->points[1].x == m->points[2].x) &&
3548 (m->points[0].y == m->points[1].y) &&
3549 (m->points[2].y == m->points[3].y))
3551 ((m->points[0].x == m->points[1].x) &&
3552 (m->points[2].x == m->points[3].x) &&
3553 (m->points[0].y == m->points[3].y) &&
3554 (m->points[1].y == m->points[2].y))
3557 if ((m->points[0].x == obj->cur.geometry.x) &&
3558 (m->points[0].y == obj->cur.geometry.y) &&
3559 (m->points[2].x == (obj->cur.geometry.x + obj->cur.geometry.w)) &&
3560 (m->points[2].y == (obj->cur.geometry.y + obj->cur.geometry.h)))
3561 return o->cur.opaque;
3565 return o->cur.opaque;
3567 if (obj->cur.render_op == EVAS_RENDER_COPY) return o->cur.opaque;
3568 return o->cur.opaque;
3572 evas_object_image_was_opaque(Evas_Object *obj)
3574 Evas_Object_Image *o;
3576 /* this returns 1 if the internal object data implies that the object was */
3577 /* previously fully opaque over the entire rectangle it occupies */
3578 o = (Evas_Object_Image *)(obj->object_data);
3579 if (o->prev.opaque_valid)
3581 if (!o->prev.opaque) return 0;
3586 o->prev.opaque_valid = 1;
3587 if ((o->prev.fill.w < 1) || (o->prev.fill.h < 1))
3589 if (((o->prev.border.l != 0) ||
3590 (o->prev.border.r != 0) ||
3591 (o->prev.border.t != 0) ||
3592 (o->prev.border.b != 0)) &&
3593 (!o->prev.border.fill)) return 0;
3594 if (!o->engine_data) return 0;
3598 if (o->prev.source) return 0; /* FIXME: Should go poke at the object */
3599 if (obj->prev.usemap) return 0;
3600 if (obj->prev.render_op == EVAS_RENDER_COPY) return 1;
3601 if (o->prev.has_alpha) return 0;
3602 if (obj->prev.render_op != EVAS_RENDER_BLEND) return 0;
3607 evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
3609 Evas_Object_Image *o;
3611 int w, h, stride, iw, ih;
3615 o = (Evas_Object_Image *)(obj->object_data);
3617 x -= obj->cur.cache.clip.x;
3618 y -= obj->cur.cache.clip.y;
3619 w = obj->cur.cache.clip.w;
3620 h = obj->cur.cache.clip.h;
3621 iw = o->cur.image.w;
3622 ih = o->cur.image.h;
3624 if ((x < 0) || (y < 0) || (x >= w) || (y >= h)) return 0;
3625 if (!o->cur.has_alpha) return 1;
3627 // FIXME: proxy needs to be honored
3630 x = obj->cur.map->mx;
3631 y = obj->cur.map->my;
3635 int bl, br, bt, bb, bsl, bsr, bst, bsb;
3637 bl = o->cur.border.l;
3638 br = o->cur.border.r;
3639 bt = o->cur.border.t;
3640 bb = o->cur.border.b;
3661 if (o->cur.border.scale != 1.0)
3663 bsl = ((double)bl * o->cur.border.scale);
3664 bsr = ((double)br * o->cur.border.scale);
3665 bst = ((double)bt * o->cur.border.scale);
3666 bsb = ((double)bb * o->cur.border.scale);
3670 bsl = bl; bsr = br; bst = bt; bsb = bb;
3683 if (o->cur.border.fill != EVAS_BORDER_FILL_DEFAULT)
3685 if ((x > bsl) && (x < (w - bsr)) &&
3686 (y > bst) && (y < (h - bsb)))
3688 if (o->cur.border.fill == EVAS_BORDER_FILL_SOLID) return 1;
3693 if (x < bsl) x = (x * bl) / bsl;
3694 else if (x > (w - bsr)) x = iw - (((w - x) * br) / bsr);
3695 else if ((bsl + bsr) < w) x = bl + (((x - bsl) * (iw - bl - br)) / (w - bsl - bsr));
3698 if (y < bst) y = (y * bt) / bst;
3699 else if (y > (h - bsb)) y = ih - (((h - y) * bb) / bsb);
3700 else if ((bst + bsb) < h) y = bt + (((y - bst) * (ih - bt - bb)) / (h - bst - bsb));
3706 if (x >= iw) x = iw - 1;
3707 if (y >= ih) y = ih - 1;
3709 stride = o->cur.image.stride;
3711 o->engine_data = obj->layer->evas->engine.func->image_data_get
3712 (obj->layer->evas->engine.data.output,
3724 switch (o->cur.cspace)
3726 case EVAS_COLORSPACE_ARGB8888:
3727 data = ((DATA32*)(data) + ((y * (stride >> 2)) + x));
3728 a = (*((DATA32*)(data)) >> 24) & 0xff;
3730 case EVAS_COLORSPACE_RGB565_A5P:
3731 data = (void*) ((DATA16*)(data) + (h * (stride >> 1)));
3732 data = (void*) ((DATA8*)(data) + ((y * (stride >> 1)) + x));
3733 a = (*((DATA8*)(data))) & 0x1f;
3741 return_value = (a != 0);
3746 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
3749 return return_value;
3753 evas_object_image_has_opaque_rect(Evas_Object *obj)
3755 Evas_Object_Image *o;
3757 o = (Evas_Object_Image *)(obj->object_data);
3758 if ((obj->cur.map) && (obj->cur.usemap)) return 0;
3759 if (((o->cur.border.l | o->cur.border.r | o->cur.border.t | o->cur.border.b) != 0) &&
3760 (o->cur.border.fill == EVAS_BORDER_FILL_SOLID) &&
3761 (obj->cur.render_op == EVAS_RENDER_BLEND) &&
3762 (obj->cur.cache.clip.a == 255) &&
3763 (o->cur.fill.x == 0) &&
3764 (o->cur.fill.y == 0) &&
3765 (o->cur.fill.w == obj->cur.geometry.w) &&
3766 (o->cur.fill.h == obj->cur.geometry.h)
3772 evas_object_image_get_opaque_rect(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
3774 Evas_Object_Image *o;
3776 o = (Evas_Object_Image *)(obj->object_data);
3777 if (o->cur.border.scale == 1.0)
3779 *x = obj->cur.geometry.x + o->cur.border.l;
3780 *y = obj->cur.geometry.y + o->cur.border.t;
3781 *w = obj->cur.geometry.w - (o->cur.border.l + o->cur.border.r);
3783 *h = obj->cur.geometry.h - (o->cur.border.t + o->cur.border.b);
3788 *x = obj->cur.geometry.x + (o->cur.border.l * o->cur.border.scale);
3789 *y = obj->cur.geometry.y + (o->cur.border.t * o->cur.border.scale);
3790 *w = obj->cur.geometry.w - ((o->cur.border.l * o->cur.border.scale) + (o->cur.border.r * o->cur.border.scale));
3792 *h = obj->cur.geometry.h - ((o->cur.border.t * o->cur.border.scale) + (o->cur.border.b * o->cur.border.scale));
3799 evas_object_image_can_map(Evas_Object *obj __UNUSED__)
3805 evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_Colorspace to_cspace)
3812 switch (o->cur.cspace)
3814 case EVAS_COLORSPACE_ARGB8888:
3815 out = evas_common_convert_argb8888_to(data,
3818 o->cur.image.stride >> 2,
3822 case EVAS_COLORSPACE_RGB565_A5P:
3823 out = evas_common_convert_rgb565_a5p_to(data,
3826 o->cur.image.stride >> 1,
3830 case EVAS_COLORSPACE_YCBCR422601_PL:
3831 out = evas_common_convert_yuv_422_601_to(data,
3836 case EVAS_COLORSPACE_YCBCR422P601_PL:
3837 out = evas_common_convert_yuv_422P_601_to(data,
3842 case EVAS_COLORSPACE_YCBCR420NV12601_PL:
3843 out = evas_common_convert_yuv_420_601_to(data,
3848 case EVAS_COLORSPACE_YCBCR420TM12601_PL:
3849 out = evas_common_convert_yuv_420T_601_to(data,
3855 WRN("unknow colorspace: %i\n", o->cur.cspace);
3863 evas_object_image_filled_resize_listener(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *einfo __UNUSED__)
3867 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3868 evas_object_image_fill_set(obj, 0, 0, w, h);
3873 _evas_object_image_preloading_get(const Evas_Object *obj)
3875 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3876 if (!o) return EINA_FALSE;
3877 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
3880 return o->preloading;
3884 _evas_object_image_preloading_set(Evas_Object *obj, Eina_Bool preloading)
3886 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3887 o->preloading = preloading;
3891 _evas_object_image_preloading_check(Evas_Object *obj)
3893 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3894 if (obj->layer->evas->engine.func->image_load_error_get)
3895 o->load_error = obj->layer->evas->engine.func->image_load_error_get
3896 (obj->layer->evas->engine.data.output, o->engine_data);
3900 _evas_object_image_video_parent_get(Evas_Object *obj)
3902 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3904 return o->video_surface ? o->video.parent : NULL;
3908 _evas_object_image_video_overlay_show(Evas_Object *obj)
3910 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3912 if (obj->cur.cache.clip.x != obj->prev.cache.clip.x ||
3913 obj->cur.cache.clip.y != obj->prev.cache.clip.y ||
3914 o->created || !o->video_visible)
3915 o->video.move(o->video.data, obj, &o->video, obj->cur.cache.clip.x, obj->cur.cache.clip.y);
3916 if (obj->cur.cache.clip.w != obj->prev.cache.clip.w ||
3917 obj->cur.cache.clip.h != obj->prev.cache.clip.h ||
3918 o->created || !o->video_visible)
3919 o->video.resize(o->video.data, obj, &o->video, obj->cur.cache.clip.w, obj->cur.cache.clip.h);
3920 if (!o->video_visible || o->created)
3922 o->video.show(o->video.data, obj, &o->video);
3926 /* Cancel dirty on the image */
3929 o->dirty_pixels = 0;
3930 EINA_LIST_FREE(o->pixel_updates, r)
3931 eina_rectangle_free(r);
3933 o->video_visible = EINA_TRUE;
3934 o->created = EINA_FALSE;
3938 _evas_object_image_video_overlay_hide(Evas_Object *obj)
3940 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3942 if (o->video_visible || o->created)
3943 o->video.hide(o->video.data, obj, &o->video);
3944 if (evas_object_is_visible(obj))
3945 o->video.update_pixels(o->video.data, obj, &o->video);
3946 o->video_visible = EINA_FALSE;
3947 o->created = EINA_FALSE;
3950 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/