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;
665 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
668 o = (Evas_Object_Image *)(obj->object_data);
669 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
672 if ((o->cur.fill.x == x) &&
673 (o->cur.fill.y == y) &&
674 (o->cur.fill.w == w) &&
675 (o->cur.fill.h == h)) return;
680 o->cur.opaque_valid = 0;
682 evas_object_change(obj);
686 evas_object_image_fill_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
688 Evas_Object_Image *o;
690 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
697 o = (Evas_Object_Image *)(obj->object_data);
698 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
705 if (x) *x = o->cur.fill.x;
706 if (y) *y = o->cur.fill.y;
707 if (w) *w = o->cur.fill.w;
708 if (h) *h = o->cur.fill.h;
713 evas_object_image_fill_spread_set(Evas_Object *obj, Evas_Fill_Spread spread)
715 Evas_Object_Image *o;
717 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
720 o = (Evas_Object_Image *)(obj->object_data);
721 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
724 if (spread == (Evas_Fill_Spread)o->cur.spread) return;
725 o->cur.spread = spread;
727 evas_object_change(obj);
730 EAPI Evas_Fill_Spread
731 evas_object_image_fill_spread_get(const Evas_Object *obj)
733 Evas_Object_Image *o;
735 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
736 return EVAS_TEXTURE_REPEAT;
738 o = (Evas_Object_Image *)(obj->object_data);
739 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
740 return EVAS_TEXTURE_REPEAT;
742 return (Evas_Fill_Spread)o->cur.spread;
746 evas_object_image_size_set(Evas_Object *obj, int w, int h)
748 Evas_Object_Image *o;
751 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
754 o = (Evas_Object_Image *)(obj->object_data);
755 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
758 _evas_object_image_cleanup(obj, o);
761 if (w > 32768) return;
762 if (h > 32768) return;
763 if ((w == o->cur.image.w) &&
764 (h == o->cur.image.h)) return;
768 o->engine_data = obj->layer->evas->engine.func->image_size_set(obj->layer->evas->engine.data.output,
772 o->engine_data = obj->layer->evas->engine.func->image_new_from_copied_data
773 (obj->layer->evas->engine.data.output, w, h, NULL, o->cur.has_alpha,
778 if (obj->layer->evas->engine.func->image_scale_hint_set)
779 obj->layer->evas->engine.func->image_scale_hint_set
780 (obj->layer->evas->engine.data.output,
781 o->engine_data, o->scale_hint);
782 if (obj->layer->evas->engine.func->image_content_hint_set)
783 obj->layer->evas->engine.func->image_content_hint_set
784 (obj->layer->evas->engine.data.output,
785 o->engine_data, o->content_hint);
786 if (obj->layer->evas->engine.func->image_stride_get)
787 obj->layer->evas->engine.func->image_stride_get
788 (obj->layer->evas->engine.data.output,
789 o->engine_data, &stride);
795 o->cur.image.stride = stride;
797 /* FIXME - in engine call above
799 o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
803 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
805 evas_object_change(obj);
809 evas_object_image_size_get(const Evas_Object *obj, int *w, int *h)
811 Evas_Object_Image *o;
813 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
818 o = (Evas_Object_Image *)(obj->object_data);
819 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
824 if (w) *w = o->cur.image.w;
825 if (h) *h = o->cur.image.h;
829 evas_object_image_stride_get(const Evas_Object *obj)
831 Evas_Object_Image *o;
833 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
836 o = (Evas_Object_Image *)(obj->object_data);
837 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
840 return o->cur.image.stride;
844 evas_object_image_load_error_get(const Evas_Object *obj)
846 Evas_Object_Image *o;
848 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
851 o = (Evas_Object_Image *)(obj->object_data);
852 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
855 return o->load_error;
859 evas_object_image_data_convert(Evas_Object *obj, Evas_Colorspace to_cspace)
861 Evas_Object_Image *o;
865 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
868 o = (Evas_Object_Image *)(obj->object_data);
869 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
872 if ((o->preloading) && (o->engine_data))
875 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
879 if (!o->engine_data) return NULL;
880 if (o->video_surface)
881 o->video.update_pixels(o->video.data, obj, &o->video);
882 if (o->cur.cspace == to_cspace) return NULL;
885 obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
886 o->engine_data, 0, &data,
888 result = evas_object_image_data_convert_internal(o, data, to_cspace);
892 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
893 o->engine_data, data);
899 evas_object_image_data_set(Evas_Object *obj, void *data)
901 Evas_Object_Image *o;
904 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
907 o = (Evas_Object_Image *)(obj->object_data);
908 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
911 _evas_object_image_cleanup(obj, o);
912 p_data = o->engine_data;
918 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
925 obj->layer->evas->engine.func->image_new_from_data(obj->layer->evas->engine.data.output,
936 if (obj->layer->evas->engine.func->image_scale_hint_set)
937 obj->layer->evas->engine.func->image_scale_hint_set
938 (obj->layer->evas->engine.data.output,
939 o->engine_data, o->scale_hint);
940 if (obj->layer->evas->engine.func->image_content_hint_set)
941 obj->layer->evas->engine.func->image_content_hint_set
942 (obj->layer->evas->engine.data.output,
943 o->engine_data, o->content_hint);
944 if (obj->layer->evas->engine.func->image_stride_get)
945 obj->layer->evas->engine.func->image_stride_get
946 (obj->layer->evas->engine.data.output,
947 o->engine_data, &stride);
949 stride = o->cur.image.w * 4;
950 o->cur.image.stride = stride;
956 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
958 o->load_error = EVAS_LOAD_ERROR_NONE;
961 o->cur.image.stride = 0;
962 o->engine_data = NULL;
964 /* FIXME - in engine call above
966 o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
970 if (o->pixels_checked_out > 0) o->pixels_checked_out--;
971 if (p_data != o->engine_data)
973 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
974 o->pixels_checked_out = 0;
977 evas_object_change(obj);
981 evas_object_image_data_get(const Evas_Object *obj, Eina_Bool for_writing)
983 Evas_Object_Image *o;
986 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
989 o = (Evas_Object_Image *)(obj->object_data);
990 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
993 if (!o->engine_data) return NULL;
996 if (obj->layer->evas->engine.func->image_scale_hint_set)
997 obj->layer->evas->engine.func->image_scale_hint_set
998 (obj->layer->evas->engine.data.output,
999 o->engine_data, o->scale_hint);
1000 if (obj->layer->evas->engine.func->image_content_hint_set)
1001 obj->layer->evas->engine.func->image_content_hint_set
1002 (obj->layer->evas->engine.data.output,
1003 o->engine_data, o->content_hint);
1005 obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1010 /* if we fail to get engine_data, we have to return NULL */
1011 if (!o->engine_data) return NULL;
1017 if (obj->layer->evas->engine.func->image_stride_get)
1018 obj->layer->evas->engine.func->image_stride_get
1019 (obj->layer->evas->engine.data.output,
1020 o->engine_data, &stride);
1022 stride = o->cur.image.w * 4;
1023 o->cur.image.stride = stride;
1025 o->pixels_checked_out++;
1028 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
1035 evas_object_image_preload(Evas_Object *obj, Eina_Bool cancel)
1037 Evas_Object_Image *o;
1039 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1042 o = (Evas_Object_Image *)(obj->object_data);
1043 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1046 if (!o->engine_data)
1049 evas_object_inform_call_image_preloaded(obj);
1052 // FIXME: if already busy preloading, then dont request again until
1059 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
1069 obj->layer->evas->engine.func->image_data_preload_request(obj->layer->evas->engine.data.output,
1077 evas_object_image_data_copy_set(Evas_Object *obj, void *data)
1079 Evas_Object_Image *o;
1082 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1085 o = (Evas_Object_Image *)(obj->object_data);
1086 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1089 _evas_object_image_cleanup(obj, o);
1090 if ((o->cur.image.w <= 0) ||
1091 (o->cur.image.h <= 0)) return;
1093 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
1096 obj->layer->evas->engine.func->image_new_from_copied_data(obj->layer->evas->engine.data.output,
1107 obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1110 if (obj->layer->evas->engine.func->image_scale_hint_set)
1111 obj->layer->evas->engine.func->image_scale_hint_set
1112 (obj->layer->evas->engine.data.output,
1113 o->engine_data, o->scale_hint);
1114 if (obj->layer->evas->engine.func->image_content_hint_set)
1115 obj->layer->evas->engine.func->image_content_hint_set
1116 (obj->layer->evas->engine.data.output,
1117 o->engine_data, o->content_hint);
1118 if (obj->layer->evas->engine.func->image_stride_get)
1119 obj->layer->evas->engine.func->image_stride_get
1120 (obj->layer->evas->engine.data.output,
1121 o->engine_data, &stride);
1123 stride = o->cur.image.w * 4;
1124 o->cur.image.stride = stride;
1126 o->pixels_checked_out = 0;
1127 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
1131 evas_object_image_data_update_add(Evas_Object *obj, int x, int y, int w, int h)
1133 Evas_Object_Image *o;
1136 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1139 o = (Evas_Object_Image *)(obj->object_data);
1140 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1143 RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, o->cur.image.w, o->cur.image.h);
1144 if ((w <= 0) || (h <= 0)) return;
1145 NEW_RECT(r, x, y, w, h);
1146 if (r) o->pixel_updates = eina_list_append(o->pixel_updates, r);
1148 evas_object_change(obj);
1152 evas_object_image_alpha_set(Evas_Object *obj, Eina_Bool has_alpha)
1154 Evas_Object_Image *o;
1156 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1159 o = (Evas_Object_Image *)(obj->object_data);
1160 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1163 if ((o->preloading) && (o->engine_data))
1166 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
1170 if (((has_alpha) && (o->cur.has_alpha)) ||
1171 ((!has_alpha) && (!o->cur.has_alpha)))
1173 o->cur.has_alpha = has_alpha;
1179 obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1182 if (obj->layer->evas->engine.func->image_scale_hint_set)
1183 obj->layer->evas->engine.func->image_scale_hint_set
1184 (obj->layer->evas->engine.data.output,
1185 o->engine_data, o->scale_hint);
1186 if (obj->layer->evas->engine.func->image_content_hint_set)
1187 obj->layer->evas->engine.func->image_content_hint_set
1188 (obj->layer->evas->engine.data.output,
1189 o->engine_data, o->content_hint);
1190 if (obj->layer->evas->engine.func->image_stride_get)
1191 obj->layer->evas->engine.func->image_stride_get
1192 (obj->layer->evas->engine.data.output,
1193 o->engine_data, &stride);
1195 stride = o->cur.image.w * 4;
1196 o->cur.image.stride = stride;
1198 evas_object_image_data_update_add(obj, 0, 0, o->cur.image.w, o->cur.image.h);
1199 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
1204 evas_object_image_alpha_get(const Evas_Object *obj)
1206 Evas_Object_Image *o;
1208 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1211 o = (Evas_Object_Image *)(obj->object_data);
1212 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1215 return o->cur.has_alpha;
1219 evas_object_image_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth_scale)
1221 Evas_Object_Image *o;
1223 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1226 o = (Evas_Object_Image *)(obj->object_data);
1227 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1230 if (((smooth_scale) && (o->cur.smooth_scale)) ||
1231 ((!smooth_scale) && (!o->cur.smooth_scale)))
1233 o->cur.smooth_scale = smooth_scale;
1235 evas_object_change(obj);
1239 evas_object_image_smooth_scale_get(const Evas_Object *obj)
1241 Evas_Object_Image *o;
1243 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1246 o = (Evas_Object_Image *)(obj->object_data);
1247 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1250 return o->cur.smooth_scale;
1254 evas_object_image_reload(Evas_Object *obj)
1256 Evas_Object_Image *o;
1258 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1261 o = (Evas_Object_Image *)(obj->object_data);
1262 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1265 if ((o->preloading) && (o->engine_data))
1268 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
1272 if ((!o->cur.file) ||
1273 (o->pixels_checked_out > 0)) return;
1275 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);
1276 evas_object_image_unload(obj, 1);
1277 evas_object_inform_call_image_unloaded(obj);
1278 evas_object_image_load(obj);
1279 o->prev.file = NULL;
1282 evas_object_change(obj);
1286 evas_object_image_save(const Evas_Object *obj, const char *file, const char *key, const char *flags)
1288 Evas_Object_Image *o;
1289 DATA32 *data = NULL;
1290 int quality = 80, compress = 9, ok = 0;
1293 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1296 o = (Evas_Object_Image *)(obj->object_data);
1297 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1301 if (!o->engine_data) return 0;
1302 o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1312 tflags = alloca(strlen(flags) + 1);
1313 strcpy(tflags, flags);
1317 pp = strchr(p, ' ');
1319 sscanf(p, "quality=%i", &quality);
1320 sscanf(p, "compress=%i", &compress);
1325 im = (RGBA_Image*) evas_cache_image_data(evas_common_image_cache_get(),
1330 EVAS_COLORSPACE_ARGB8888);
1333 if (o->cur.cspace == EVAS_COLORSPACE_ARGB8888)
1334 im->image.data = data;
1336 im->image.data = evas_object_image_data_convert_internal(o,
1338 EVAS_COLORSPACE_ARGB8888);
1341 ok = evas_common_save_image_to_file(im, file, key, quality, compress);
1343 if (o->cur.cspace != EVAS_COLORSPACE_ARGB8888)
1344 free(im->image.data);
1347 evas_cache_image_drop(&im->cache_entry);
1349 o->engine_data = obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
1356 evas_object_image_pixels_import(Evas_Object *obj, Evas_Pixel_Import_Source *pixels)
1358 Evas_Object_Image *o;
1360 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1363 o = (Evas_Object_Image *)(obj->object_data);
1364 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1367 _evas_object_image_cleanup(obj, o);
1368 if ((pixels->w != o->cur.image.w) || (pixels->h != o->cur.image.h)) return 0;
1369 switch (pixels->format)
1372 case EVAS_PIXEL_FORMAT_ARGB32:
1376 DATA32 *image_pixels = NULL;
1379 obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1384 /* FIXME: need to actualyl support this */
1385 /* memcpy(image_pixels, pixels->rows, o->cur.image.w * o->cur.image.h * 4);*/
1388 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
1393 obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1397 evas_object_change(obj);
1402 #ifdef BUILD_CONVERT_YUV
1403 case EVAS_PIXEL_FORMAT_YUV420P_601:
1407 DATA32 *image_pixels = NULL;
1410 obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1416 evas_common_convert_yuv_420p_601_rgba((DATA8 **) pixels->rows,
1417 (DATA8 *) image_pixels,
1422 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
1427 obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1431 evas_object_change(obj);
1444 evas_object_image_pixels_get_callback_set(Evas_Object *obj, Evas_Object_Image_Pixels_Get_Cb func, void *data)
1446 Evas_Object_Image *o;
1448 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1451 o = (Evas_Object_Image *)(obj->object_data);
1452 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1455 o->func.get_pixels = func;
1456 o->func.get_pixels_data = data;
1460 evas_object_image_pixels_dirty_set(Evas_Object *obj, Eina_Bool dirty)
1462 Evas_Object_Image *o;
1464 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1467 o = (Evas_Object_Image *)(obj->object_data);
1468 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1471 if (dirty) o->dirty_pixels = 1;
1472 else o->dirty_pixels = 0;
1474 evas_object_change(obj);
1478 evas_object_image_pixels_dirty_get(const Evas_Object *obj)
1480 Evas_Object_Image *o;
1482 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1485 o = (Evas_Object_Image *)(obj->object_data);
1486 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1489 if (o->dirty_pixels) return 1;
1494 evas_object_image_load_dpi_set(Evas_Object *obj, double dpi)
1496 Evas_Object_Image *o;
1498 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1501 o = (Evas_Object_Image *)(obj->object_data);
1502 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1505 if (dpi == o->load_opts.dpi) return;
1506 o->load_opts.dpi = dpi;
1509 evas_object_image_unload(obj, 0);
1510 evas_object_inform_call_image_unloaded(obj);
1511 evas_object_image_load(obj);
1513 evas_object_change(obj);
1518 evas_object_image_load_dpi_get(const Evas_Object *obj)
1520 Evas_Object_Image *o;
1522 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1525 o = (Evas_Object_Image *)(obj->object_data);
1526 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1529 return o->load_opts.dpi;
1533 evas_object_image_load_size_set(Evas_Object *obj, int w, int h)
1535 Evas_Object_Image *o;
1537 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1540 o = (Evas_Object_Image *)(obj->object_data);
1541 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1544 if ((o->load_opts.w == w) && (o->load_opts.h == h)) return;
1549 evas_object_image_unload(obj, 0);
1550 evas_object_inform_call_image_unloaded(obj);
1551 evas_object_image_load(obj);
1553 evas_object_change(obj);
1558 evas_object_image_load_size_get(const Evas_Object *obj, int *w, int *h)
1560 Evas_Object_Image *o;
1562 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1565 o = (Evas_Object_Image *)(obj->object_data);
1566 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1569 if (w) *w = o->load_opts.w;
1570 if (h) *h = o->load_opts.h;
1574 evas_object_image_load_scale_down_set(Evas_Object *obj, int scale_down)
1576 Evas_Object_Image *o;
1578 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1581 o = (Evas_Object_Image *)(obj->object_data);
1582 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1585 if (o->load_opts.scale_down_by == scale_down) return;
1586 o->load_opts.scale_down_by = scale_down;
1589 evas_object_image_unload(obj, 0);
1590 evas_object_inform_call_image_unloaded(obj);
1591 evas_object_image_load(obj);
1593 evas_object_change(obj);
1598 evas_object_image_load_scale_down_get(const Evas_Object *obj)
1600 Evas_Object_Image *o;
1602 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1605 o = (Evas_Object_Image *)(obj->object_data);
1606 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1609 return o->load_opts.scale_down_by;
1613 evas_object_image_load_region_set(Evas_Object *obj, int x, int y, int w, int h)
1615 Evas_Object_Image *o;
1617 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1620 o = (Evas_Object_Image *)(obj->object_data);
1621 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1624 if ((o->load_opts.region.x == x) && (o->load_opts.region.y == y) &&
1625 (o->load_opts.region.w == w) && (o->load_opts.region.h == h)) return;
1626 o->load_opts.region.x = x;
1627 o->load_opts.region.y = y;
1628 o->load_opts.region.w = w;
1629 o->load_opts.region.h = h;
1632 evas_object_image_unload(obj, 0);
1633 evas_object_inform_call_image_unloaded(obj);
1634 evas_object_image_load(obj);
1636 evas_object_change(obj);
1641 evas_object_image_load_region_get(const Evas_Object *obj, int *x, int *y, int *w, int *h)
1643 Evas_Object_Image *o;
1645 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1648 o = (Evas_Object_Image *)(obj->object_data);
1649 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1652 if (x) *x = o->load_opts.region.x;
1653 if (y) *y = o->load_opts.region.y;
1654 if (w) *w = o->load_opts.region.w;
1655 if (h) *h = o->load_opts.region.h;
1659 evas_object_image_load_orientation_set(Evas_Object *obj, Eina_Bool enable)
1661 Evas_Object_Image *o;
1663 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1666 o = (Evas_Object_Image *)(obj->object_data);
1667 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1670 o->load_opts.orientation = !!enable;
1674 evas_object_image_load_orientation_get(const Evas_Object *obj)
1676 Evas_Object_Image *o;
1678 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1681 o = (Evas_Object_Image *)(obj->object_data);
1682 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1685 return o->load_opts.orientation;
1689 evas_object_image_colorspace_set(Evas_Object *obj, Evas_Colorspace cspace)
1691 Evas_Object_Image *o;
1693 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1696 o = (Evas_Object_Image *)(obj->object_data);
1697 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1701 _evas_object_image_cleanup(obj, o);
1703 o->cur.cspace = cspace;
1705 obj->layer->evas->engine.func->image_colorspace_set(obj->layer->evas->engine.data.output,
1710 EAPI Evas_Colorspace
1711 evas_object_image_colorspace_get(const Evas_Object *obj)
1713 Evas_Object_Image *o;
1715 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1716 return EVAS_COLORSPACE_ARGB8888;
1718 o = (Evas_Object_Image *)(obj->object_data);
1719 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1720 return EVAS_COLORSPACE_ARGB8888;
1722 return o->cur.cspace;
1726 evas_object_image_video_surface_set(Evas_Object *obj, Evas_Video_Surface *surf)
1728 Evas_Object_Image *o;
1730 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1733 o = (Evas_Object_Image *)(obj->object_data);
1734 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1737 _evas_object_image_cleanup(obj, o);
1738 if (o->video_surface)
1740 o->video_surface = 0;
1741 obj->layer->evas->video_objects = eina_list_remove(obj->layer->evas->video_objects, obj);
1746 if (surf->version != EVAS_VIDEO_SURFACE_VERSION) return ;
1748 if (!surf->update_pixels ||
1755 o->created = EINA_TRUE;
1756 o->video_surface = 1;
1759 obj->layer->evas->video_objects = eina_list_append(obj->layer->evas->video_objects, obj);
1763 o->video_surface = 0;
1764 o->video.update_pixels = NULL;
1765 o->video.move = NULL;
1766 o->video.resize = NULL;
1767 o->video.hide = NULL;
1768 o->video.show = NULL;
1769 o->video.data = NULL;
1773 EAPI const Evas_Video_Surface *
1774 evas_object_image_video_surface_get(const Evas_Object *obj)
1776 Evas_Object_Image *o;
1778 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1781 o = (Evas_Object_Image *)(obj->object_data);
1782 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1785 if (!o->video_surface) return NULL;
1790 evas_object_image_native_surface_set(Evas_Object *obj, Evas_Native_Surface *surf)
1792 Evas_Object_Image *o;
1794 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1797 o = (Evas_Object_Image *)(obj->object_data);
1798 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1801 _evas_object_image_cleanup(obj, o);
1802 if (!obj->layer->evas->engine.func->image_native_set) return;
1804 ((surf->version < 2) ||
1805 (surf->version > EVAS_NATIVE_SURFACE_VERSION))) return;
1807 obj->layer->evas->engine.func->image_native_set(obj->layer->evas->engine.data.output,
1812 EAPI Evas_Native_Surface *
1813 evas_object_image_native_surface_get(const Evas_Object *obj)
1815 Evas_Object_Image *o;
1817 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1820 o = (Evas_Object_Image *)(obj->object_data);
1821 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1824 if (!obj->layer->evas->engine.func->image_native_get) return NULL;
1825 return obj->layer->evas->engine.func->image_native_get(obj->layer->evas->engine.data.output,
1830 evas_object_image_scale_hint_set(Evas_Object *obj, Evas_Image_Scale_Hint hint)
1832 Evas_Object_Image *o;
1834 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1837 o = (Evas_Object_Image *)(obj->object_data);
1838 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1841 if (o->scale_hint == hint) return;
1842 o->scale_hint = hint;
1847 if (obj->layer->evas->engine.func->image_scale_hint_set)
1848 obj->layer->evas->engine.func->image_scale_hint_set
1849 (obj->layer->evas->engine.data.output,
1850 o->engine_data, o->scale_hint);
1851 if (obj->layer->evas->engine.func->image_stride_get)
1852 obj->layer->evas->engine.func->image_stride_get
1853 (obj->layer->evas->engine.data.output,
1854 o->engine_data, &stride);
1856 stride = o->cur.image.w * 4;
1857 o->cur.image.stride = stride;
1861 EAPI Evas_Image_Scale_Hint
1862 evas_object_image_scale_hint_get(const Evas_Object *obj)
1864 Evas_Object_Image *o;
1866 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1867 return EVAS_IMAGE_SCALE_HINT_NONE;
1869 o = (Evas_Object_Image *)(obj->object_data);
1870 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1871 return EVAS_IMAGE_SCALE_HINT_NONE;
1873 return o->scale_hint;
1877 evas_object_image_content_hint_set(Evas_Object *obj, Evas_Image_Content_Hint hint)
1879 Evas_Object_Image *o;
1881 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1884 o = (Evas_Object_Image *)(obj->object_data);
1885 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1888 if (o->content_hint == hint) return;
1889 o->content_hint = hint;
1894 if (obj->layer->evas->engine.func->image_content_hint_set)
1895 obj->layer->evas->engine.func->image_content_hint_set
1896 (obj->layer->evas->engine.data.output,
1897 o->engine_data, o->content_hint);
1898 if (obj->layer->evas->engine.func->image_stride_get)
1899 obj->layer->evas->engine.func->image_stride_get
1900 (obj->layer->evas->engine.data.output,
1901 o->engine_data, &stride);
1903 stride = o->cur.image.w * 4;
1904 o->cur.image.stride = stride;
1909 evas_object_image_alpha_mask_set(Evas_Object *obj, Eina_Bool ismask)
1911 Evas_Object_Image *o;
1913 if (!ismask) return;
1915 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1918 o = (Evas_Object_Image *)(obj->object_data);
1919 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1923 /* Convert to A8 if not already */
1929 #define FRAME_MAX 1024
1930 EAPI Evas_Image_Content_Hint
1931 evas_object_image_content_hint_get(const Evas_Object *obj)
1933 Evas_Object_Image *o;
1935 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1936 return EVAS_IMAGE_CONTENT_HINT_NONE;
1938 o = (Evas_Object_Image *)(obj->object_data);
1939 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1940 return EVAS_IMAGE_CONTENT_HINT_NONE;
1942 return o->content_hint;
1946 evas_object_image_region_support_get(const Evas_Object *obj)
1948 Evas_Object_Image *o;
1950 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1953 o = (Evas_Object_Image *) (obj->object_data);
1954 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1958 return obj->layer->evas->engine.func->image_can_region_get(
1959 obj->layer->evas->engine.data.output,
1963 /* animated feature */
1965 evas_object_image_animated_get(const Evas_Object *obj)
1967 Evas_Object_Image *o;
1969 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1972 o = (Evas_Object_Image *)(obj->object_data);
1973 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1977 if (obj->layer->evas->engine.func->image_animated_get)
1978 return obj->layer->evas->engine.func->image_animated_get(obj->layer->evas->engine.data.output, o->engine_data);
1983 evas_object_image_animated_frame_count_get(const Evas_Object *obj)
1985 Evas_Object_Image *o;
1987 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1990 o = (Evas_Object_Image *)(obj->object_data);
1991 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1995 if (!evas_object_image_animated_get(obj)) return -1;
1996 if (obj->layer->evas->engine.func->image_animated_frame_count_get)
1997 return obj->layer->evas->engine.func->image_animated_frame_count_get(obj->layer->evas->engine.data.output, o->engine_data);
2001 EAPI Evas_Image_Animated_Loop_Hint
2002 evas_object_image_animated_loop_type_get(const Evas_Object *obj)
2004 Evas_Object_Image *o;
2006 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2007 return EVAS_IMAGE_ANIMATED_HINT_NONE;
2009 o = (Evas_Object_Image *)(obj->object_data);
2010 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2011 return EVAS_IMAGE_ANIMATED_HINT_NONE;
2014 if (!evas_object_image_animated_get(obj)) return EVAS_IMAGE_ANIMATED_HINT_NONE;
2016 if (obj->layer->evas->engine.func->image_animated_loop_type_get)
2017 return obj->layer->evas->engine.func->image_animated_loop_type_get(obj->layer->evas->engine.data.output, o->engine_data);
2018 return EVAS_IMAGE_ANIMATED_HINT_NONE;
2022 evas_object_image_animated_loop_count_get(const Evas_Object *obj)
2024 Evas_Object_Image *o;
2026 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2029 o = (Evas_Object_Image *)(obj->object_data);
2030 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2034 if (!evas_object_image_animated_get(obj)) return -1;
2036 if (obj->layer->evas->engine.func->image_animated_loop_count_get)
2037 return obj->layer->evas->engine.func->image_animated_loop_count_get(obj->layer->evas->engine.data.output, o->engine_data);
2042 evas_object_image_animated_frame_duration_get(const Evas_Object *obj, int start_frame, int frame_num)
2044 Evas_Object_Image *o;
2045 int frame_count = 0;
2047 if (start_frame < 1) return -1;
2048 if (frame_num < 0) return -1;
2050 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2053 o = (Evas_Object_Image *)(obj->object_data);
2054 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2058 if (!evas_object_image_animated_get(obj)) return -1;
2060 if (!obj->layer->evas->engine.func->image_animated_frame_count_get) return -1;
2062 frame_count = obj->layer->evas->engine.func->image_animated_frame_count_get(obj->layer->evas->engine.data.output, o->engine_data);
2064 if ((start_frame + frame_num) > frame_count) return -1;
2065 if (obj->layer->evas->engine.func->image_animated_frame_duration_get)
2066 return obj->layer->evas->engine.func->image_animated_frame_duration_get(obj->layer->evas->engine.data.output, o->engine_data, start_frame, frame_num);
2071 evas_object_image_animated_frame_set(Evas_Object *obj, int frame_index)
2073 Evas_Object_Image *o;
2074 int frame_count = 0;
2076 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2079 o = (Evas_Object_Image *)(obj->object_data);
2080 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2084 if (!o->cur.file) return;
2085 if (o->cur.frame == frame_index) return;
2087 if (!evas_object_image_animated_get(obj)) return;
2089 frame_count = evas_object_image_animated_frame_count_get(obj);
2091 /* limit the size of frame to FRAME_MAX */
2092 if ((frame_count > FRAME_MAX) || (frame_count < 0) || (frame_index > frame_count))
2095 if (!obj->layer->evas->engine.func->image_animated_frame_set) return;
2096 if (!obj->layer->evas->engine.func->image_animated_frame_set(obj->layer->evas->engine.data.output, o->engine_data, frame_index))
2099 o->prev.frame = o->cur.frame;
2100 o->cur.frame = frame_index;
2103 evas_object_change(obj);
2108 evas_image_cache_flush(Evas *e)
2110 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2114 e->engine.func->image_cache_flush(e->engine.data.output);
2118 evas_image_cache_reload(Evas *e)
2122 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2126 evas_image_cache_flush(e);
2127 EINA_INLIST_FOREACH(e->layers, layer)
2131 EINA_INLIST_FOREACH(layer->objects, obj)
2133 Evas_Object_Image *o;
2135 o = (Evas_Object_Image *)(obj->object_data);
2136 if (o->magic == MAGIC_OBJ_IMAGE)
2138 evas_object_image_unload(obj, 1);
2139 evas_object_inform_call_image_unloaded(obj);
2143 evas_image_cache_flush(e);
2144 EINA_INLIST_FOREACH(e->layers, layer)
2148 EINA_INLIST_FOREACH(layer->objects, obj)
2150 Evas_Object_Image *o;
2152 o = (Evas_Object_Image *)(obj->object_data);
2153 if (o->magic == MAGIC_OBJ_IMAGE)
2155 evas_object_image_load(obj);
2157 evas_object_change(obj);
2161 evas_image_cache_flush(e);
2165 evas_image_cache_set(Evas *e, int size)
2167 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2171 if (size < 0) size = 0;
2172 e->engine.func->image_cache_set(e->engine.data.output, size);
2176 evas_image_cache_get(const Evas *e)
2178 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2182 return e->engine.func->image_cache_get(e->engine.data.output);
2186 evas_image_max_size_get(const Evas *e, int *maxw, int *maxh)
2189 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2193 if (maxw) *maxw = 0xffff;
2194 if (maxh) *maxh = 0xffff;
2195 if (!e->engine.func->image_max_size_get) return EINA_FALSE;
2196 e->engine.func->image_max_size_get(e->engine.data.output, &w, &h);
2197 if (maxw) *maxw = w;
2198 if (maxh) *maxh = h;
2202 /* all nice and private */
2204 _proxy_unset(Evas_Object *proxy)
2206 Evas_Object_Image *o;
2208 o = proxy->object_data;
2209 if (!o->cur.source) return;
2211 o->cur.source->proxy.proxies = eina_list_remove(o->cur.source->proxy.proxies, proxy);
2213 o->cur.source = NULL;
2216 evas_map_free(o->cur.defmap);
2217 o->cur.defmap = NULL;
2223 _proxy_set(Evas_Object *proxy, Evas_Object *src)
2225 Evas_Object_Image *o;
2227 o = proxy->object_data;
2229 evas_object_image_file_set(proxy, NULL, NULL);
2231 o->cur.source = src;
2232 o->load_error = EVAS_LOAD_ERROR_NONE;
2234 src->proxy.proxies = eina_list_append(src->proxy.proxies, proxy);
2235 src->proxy.redraw = EINA_TRUE;
2238 /* Some moron just set a proxy on a proxy.
2239 * Give them some pixels. A random color
2242 _proxy_error(Evas_Object *proxy, void *context, void *output, void *surface,
2246 int r = rand() % 255;
2247 int g = rand() % 255;
2248 int b = rand() % 255;
2250 /* XXX: Eina log error or something I'm sure
2251 * If it bugs you, just fix it. Don't tell me */
2252 if (VERBOSE_PROXY_ERROR) printf("Err: Argh! Recursive proxies.\n");
2254 func = proxy->layer->evas->engine.func;
2255 func->context_color_set(output, context, r, g, b, 255);
2256 func->context_multiplier_unset(output, context);
2257 func->context_render_op_set(output, context, proxy->cur.render_op);
2258 func->rectangle_draw(output, context, surface, proxy->cur.geometry.x + x,
2259 proxy->cur.geometry.y + y,
2260 proxy->cur.geometry.w,
2261 proxy->cur.geometry.h);
2267 _proxy_subrender_recurse(Evas_Object *obj, Evas_Object *clip, void *output, void *surface, void *ctx, int x, int y)
2270 Evas *e = obj->layer->evas;
2272 if (obj->clip.clipees) return;
2273 if (!obj->cur.visible) return;
2274 if ((!clip) || (clip != obj->cur.clipper))
2276 if (!obj->cur.cache.clip.visible) return;
2277 if ((obj->cur.cache.clip.a == 0) &&
2278 (obj->cur.render_op == EVAS_RENDER_BLEND)) return;
2280 if ((obj->func->is_visible) && (!obj->func->is_visible(obj))) return;
2282 if (!obj->pre_render_done)
2283 obj->func->render_pre(obj);
2284 ctx = e->engine.func->context_new(output);
2285 if (obj->smart.smart)
2287 EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
2289 _proxy_subrender_recurse(obj2, clip, output, surface, ctx, x, y);
2294 obj->func->render(obj, output, ctx, surface, x, y);
2296 e->engine.func->context_free(output, ctx);
2301 * Render the source object when a proxy is set.
2303 * Used to force a draw if necessary, else just makes sures it's available.
2306 _proxy_subrender(Evas *e, Evas_Object *source)
2309 /* Evas_Object *obj2, *clip;*/
2312 if (!source) return;
2314 w = source->cur.geometry.w;
2315 h = source->cur.geometry.h;
2317 source->proxy.redraw = EINA_FALSE;
2319 /* We need to redraw surface then */
2320 if ((source->proxy.surface) &&
2321 ((source->proxy.w != w) || (source->proxy.h != h)))
2323 e->engine.func->image_map_surface_free(e->engine.data.output,
2324 source->proxy.surface);
2325 source->proxy.surface = NULL;
2328 /* FIXME: Hardcoded alpha 'on' */
2329 /* FIXME (cont): Should see if the object has alpha */
2330 if (!source->proxy.surface)
2332 source->proxy.surface = e->engine.func->image_map_surface_new
2333 (e->engine.data.output, w, h, 1);
2334 source->proxy.w = w;
2335 source->proxy.h = h;
2338 ctx = e->engine.func->context_new(e->engine.data.output);
2339 e->engine.func->context_color_set(e->engine.data.output, ctx, 0, 0, 0, 0);
2340 e->engine.func->context_render_op_set(e->engine.data.output, ctx, EVAS_RENDER_COPY);
2341 e->engine.func->rectangle_draw(e->engine.data.output, ctx,
2342 source->proxy.surface, 0, 0, w, h);
2343 e->engine.func->context_free(e->engine.data.output, ctx);
2345 ctx = e->engine.func->context_new(e->engine.data.output);
2346 evas_render_mapped(e, source, ctx, source->proxy.surface,
2347 -source->cur.geometry.x,
2348 -source->cur.geometry.y,
2349 1, 0, 0, e->output.w, e->output.h);
2350 e->engine.func->context_free(e->engine.data.output, ctx);
2351 source->proxy.surface = e->engine.func->image_dirty_region
2352 (e->engine.data.output, source->proxy.surface, 0, 0, w, h);
2354 ctx = e->engine.func->context_new(e->engine.data.output);
2355 if (source->smart.smart)
2357 clip = evas_object_smart_clipped_clipper_get(source);
2358 EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(source), obj2)
2360 _proxy_subrender_recurse(obj2, clip, e->engine.data.output,
2361 source->proxy.surface,
2363 -source->cur.geometry.x,
2364 -source->cur.geometry.y);
2369 if (!source->pre_render_done)
2370 source->func->render_pre(source);
2371 source->func->render(source, e->engine.data.output, ctx,
2372 source->proxy.surface,
2373 -source->cur.geometry.x,
2374 -source->cur.geometry.y);
2377 e->engine.func->context_free(e->engine.data.output, ctx);
2378 source->proxy.surface = e->engine.func->image_dirty_region
2379 (e->engine.data.output, source->proxy.surface, 0, 0, w, h);
2383 #if 0 // filtering disabled
2386 * Note that this is similar to proxy_subrender_recurse. It should be
2387 * possible to merge I guess
2390 image_filter_draw_under_recurse(Evas *e, Evas_Object *obj, Evas_Object *stop,
2391 void *output, void *ctx, void *surface,
2396 if (obj->clip.clipees) return;
2397 /* FIXME: Doing bounding box test */
2398 if (!evas_object_is_in_output_rect(obj, stop->cur.geometry.x,
2399 stop->cur.geometry.y,
2400 stop->cur.geometry.w,
2401 stop->cur.geometry.h))
2404 if (!evas_object_is_visible(obj)) return;
2405 obj->pre_render_done = 1;
2406 ctx = e->engine.func->context_new(output);
2408 if (obj->smart.smart)
2410 EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
2412 if (obj2 == stop) return;
2413 image_filter_draw_under_recurse(e, obj2, stop, output, surface,
2418 obj->func->render(obj, output, ctx, surface, x ,y);
2419 e->engine.func->context_free(output, ctx);
2423 * Draw all visible objects intersecting an object which are _beneath_ it.
2426 image_filter_draw_under(Evas *e, Evas_Object *stop, void *output, void *ctx, void *surface, int dx, int dy)
2431 x = stop->cur.geometry.x - dx;
2432 y = stop->cur.geometry.y - dy;
2434 EINA_INLIST_FOREACH(e->layers, lay)
2437 EINA_INLIST_FOREACH(lay->objects, obj)
2439 if (obj->delete_me) continue;
2440 if (obj == stop) return;
2441 /* FIXME: Do bounding box check */
2442 image_filter_draw_under_recurse(e, obj, stop, output, ctx,
2446 e->engine.func->image_dirty_region(output, surface, 0, 0, 300, 300);
2447 e->engine.func->output_flush(output);
2451 * Update the filtered object.
2453 * Creates a new context, and renders stuff (filtered) onto that.
2456 image_filter_update(Evas *e, Evas_Object *obj, void *src, int imagew, int imageh, int *outw, int *outh)
2460 Evas_Filter_Info *info;
2466 if (info->mode == EVAS_FILTER_MODE_BELOW)
2468 w = obj->cur.geometry.w;
2469 h = obj->cur.geometry.h;
2470 evas_filter_get_size(info, w, h, &imagew, &imageh, EINA_TRUE);
2475 evas_filter_get_size(info, imagew, imageh, &w, &h, EINA_FALSE);
2476 alpha = e->engine.func->image_alpha_get(e->engine.data.output, src);
2479 /* Certain filters may make alpha images anyway */
2480 if (alpha == EINA_FALSE) alpha = evas_filter_always_alpha(info);
2482 surface = e->engine.func->image_map_surface_new(e->engine.data.output, w, h,
2485 if (info->mode == EVAS_FILTER_MODE_BELOW)
2490 disw = obj->cur.geometry.w;
2491 dish = obj->cur.geometry.h;
2492 dx = (imagew - w) >> 1;
2493 dy = (imageh - h) >> 1;
2494 subsurface = e->engine.func->image_map_surface_new
2495 (e->engine.data.output, imagew, imageh, 1);
2496 ctx = e->engine.func->context_new(e->engine.data.output);
2497 e->engine.func->context_color_set(e->engine.data.output, ctx, 0, 255, 0, 255);
2498 e->engine.func->context_render_op_set(e->engine.data.output, ctx, EVAS_RENDER_COPY);
2499 e->engine.func->rectangle_draw(e->engine.data.output, ctx,
2500 subsurface, 0, 0, imagew, imageh);
2502 image_filter_draw_under(e, obj, e->engine.data.output, ctx,
2503 subsurface, dx, dy);
2505 e->engine.func->context_free(e->engine.data.output, ctx);
2507 ctx = e->engine.func->context_new(e->engine.data.output);
2509 e->engine.func->image_draw_filtered(e->engine.data.output,
2510 ctx, surface, subsurface, info);
2512 e->engine.func->context_free(e->engine.data.output, ctx);
2514 e->engine.func->image_map_surface_free(e->engine.data.output,
2519 ctx = e->engine.func->context_new(e->engine.data.output);
2520 e->engine.func->image_draw_filtered(e->engine.data.output,
2521 ctx, surface, src, info);
2522 e->engine.func->context_free(e->engine.data.output, ctx);
2525 e->engine.func->image_dirty_region(e->engine.data.output, surface,
2527 if (outw) *outw = w;
2528 if (outh) *outh = h;
2529 return e->engine.func->image_filtered_save(src, surface,
2536 evas_object_image_unload(Evas_Object *obj, Eina_Bool dirty)
2538 Evas_Object_Image *o;
2540 o = (Evas_Object_Image *)(obj->object_data);
2542 if ((!o->cur.file) ||
2543 (o->pixels_checked_out > 0)) return;
2547 o->engine_data = obj->layer->evas->engine.func->image_dirty_region
2548 (obj->layer->evas->engine.data.output,
2551 o->cur.image.w, o->cur.image.h);
2558 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
2562 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
2565 o->engine_data = NULL;
2566 o->load_error = EVAS_LOAD_ERROR_NONE;
2567 o->cur.has_alpha = 1;
2568 o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
2571 o->cur.image.stride = 0;
2575 evas_object_image_load(Evas_Object *obj)
2577 Evas_Object_Image *o;
2578 Evas_Image_Load_Opts lo;
2580 o = (Evas_Object_Image *)(obj->object_data);
2581 if (o->engine_data) return;
2583 lo.scale_down_by = o->load_opts.scale_down_by;
2584 lo.dpi = o->load_opts.dpi;
2585 lo.w = o->load_opts.w;
2586 lo.h = o->load_opts.h;
2587 lo.region.x = o->load_opts.region.x;
2588 lo.region.y = o->load_opts.region.y;
2589 lo.region.w = o->load_opts.region.w;
2590 lo.region.h = o->load_opts.region.h;
2591 lo.orientation = o->load_opts.orientation;
2592 o->engine_data = obj->layer->evas->engine.func->image_load
2593 (obj->layer->evas->engine.data.output,
2603 obj->layer->evas->engine.func->image_size_get
2604 (obj->layer->evas->engine.data.output,
2605 o->engine_data, &w, &h);
2606 if (obj->layer->evas->engine.func->image_stride_get)
2607 obj->layer->evas->engine.func->image_stride_get
2608 (obj->layer->evas->engine.data.output,
2609 o->engine_data, &stride);
2612 o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get
2613 (obj->layer->evas->engine.data.output,
2615 o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get
2616 (obj->layer->evas->engine.data.output,
2620 o->cur.image.stride = stride;
2624 o->load_error = EVAS_LOAD_ERROR_GENERIC;
2629 evas_object_image_figure_x_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret)
2633 w = ((size * obj->layer->evas->output.w) /
2634 (Evas_Coord)obj->layer->evas->viewport.w);
2635 if (size <= 0) size = 1;
2638 while (start - size > 0) start -= size;
2642 while (start < 0) start += size;
2644 start = ((start * obj->layer->evas->output.w) /
2645 (Evas_Coord)obj->layer->evas->viewport.w);
2651 evas_object_image_figure_y_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret)
2655 h = ((size * obj->layer->evas->output.h) /
2656 (Evas_Coord)obj->layer->evas->viewport.h);
2657 if (size <= 0) size = 1;
2660 while (start - size > 0) start -= size;
2664 while (start < 0) start += size;
2666 start = ((start * obj->layer->evas->output.h) /
2667 (Evas_Coord)obj->layer->evas->viewport.h);
2673 evas_object_image_init(Evas_Object *obj)
2675 /* alloc image ob, setup methods and default values */
2676 obj->object_data = evas_object_image_new();
2677 /* set up default settings for this kind of object */
2678 obj->cur.color.r = 255;
2679 obj->cur.color.g = 255;
2680 obj->cur.color.b = 255;
2681 obj->cur.color.a = 255;
2682 obj->cur.geometry.x = 0;
2683 obj->cur.geometry.y = 0;
2684 obj->cur.geometry.w = 0;
2685 obj->cur.geometry.h = 0;
2687 obj->cur.anti_alias = 0;
2688 obj->cur.render_op = EVAS_RENDER_BLEND;
2689 /* set up object-specific settings */
2690 obj->prev = obj->cur;
2691 /* set up methods (compulsory) */
2692 obj->func = &object_func;
2697 evas_object_image_new(void)
2699 Evas_Object_Image *o;
2701 /* alloc obj private data */
2702 EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_image", Evas_Object_Image, 16, NULL);
2703 o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Image);
2704 if (!o) return NULL;
2705 EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Image);
2706 o->magic = MAGIC_OBJ_IMAGE;
2709 o->cur.smooth_scale = 1;
2710 o->cur.border.fill = 1;
2711 o->cur.border.scale = 1.0;
2712 o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
2713 o->cur.spread = EVAS_TEXTURE_REPEAT;
2714 o->cur.opaque_valid = 0;
2715 o->cur.source = NULL;
2722 evas_object_image_free(Evas_Object *obj)
2724 Evas_Object_Image *o;
2727 /* frees private object data. very simple here */
2728 o = (Evas_Object_Image *)(obj->object_data);
2729 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2734 if (o->cur.file) eina_stringshare_del(o->cur.file);
2735 if (o->cur.key) eina_stringshare_del(o->cur.key);
2736 if (o->cur.source) _proxy_unset(obj);
2742 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
2746 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
2749 if (o->video_surface)
2751 o->video_surface = 0;
2752 obj->layer->evas->video_objects = eina_list_remove(obj->layer->evas->video_objects, obj);
2754 o->engine_data = NULL;
2756 EINA_LIST_FREE(o->pixel_updates, r)
2757 eina_rectangle_free(r);
2758 EVAS_MEMPOOL_FREE(_mp_obj, o);
2762 evas_object_image_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
2764 Evas_Object_Image *o;
2765 int imagew, imageh, uvw, uvh;
2768 /* render object to surface with context, and offset by x,y */
2769 o = (Evas_Object_Image *)(obj->object_data);
2771 if ((o->cur.fill.w < 1) || (o->cur.fill.h < 1))
2772 return; /* no error message, already printed in pre_render */
2775 if (o->proxyrendering)
2777 _proxy_error(obj, context, output, surface, x, y);
2781 /* We are displaying the overlay */
2782 if (o->video_visible)
2784 /* Create a transparent rectangle */
2785 obj->layer->evas->engine.func->context_color_set(output,
2788 obj->layer->evas->engine.func->context_multiplier_unset(output,
2790 obj->layer->evas->engine.func->context_render_op_set(output, context,
2792 obj->layer->evas->engine.func->rectangle_draw(output,
2795 obj->cur.geometry.x + x,
2796 obj->cur.geometry.y + y,
2797 obj->cur.geometry.w,
2798 obj->cur.geometry.h);
2803 obj->layer->evas->engine.func->context_color_set(output,
2805 255, 255, 255, 255);
2807 if ((obj->cur.cache.clip.r == 255) &&
2808 (obj->cur.cache.clip.g == 255) &&
2809 (obj->cur.cache.clip.b == 255) &&
2810 (obj->cur.cache.clip.a == 255))
2812 obj->layer->evas->engine.func->context_multiplier_unset(output,
2816 obj->layer->evas->engine.func->context_multiplier_set(output,
2818 obj->cur.cache.clip.r,
2819 obj->cur.cache.clip.g,
2820 obj->cur.cache.clip.b,
2821 obj->cur.cache.clip.a);
2823 obj->layer->evas->engine.func->context_render_op_set(output, context,
2824 obj->cur.render_op);
2828 pixels = o->engine_data;
2829 imagew = o->cur.image.w;
2830 imageh = o->cur.image.h;
2834 else if (o->cur.source->proxy.surface && !o->cur.source->proxy.redraw)
2836 pixels = o->cur.source->proxy.surface;
2837 imagew = o->cur.source->proxy.w;
2838 imageh = o->cur.source->proxy.h;
2842 else if (o->cur.source->type == o_type &&
2843 ((Evas_Object_Image *)o->cur.source->object_data)->engine_data)
2845 Evas_Object_Image *oi;
2846 oi = o->cur.source->object_data;
2847 pixels = oi->engine_data;
2848 imagew = oi->cur.image.w;
2849 imageh = oi->cur.image.h;
2850 uvw = o->cur.source->cur.geometry.w;
2851 uvh = o->cur.source->cur.geometry.h;
2855 o->proxyrendering = 1;
2856 _proxy_subrender(obj->layer->evas, o->cur.source);
2857 pixels = o->cur.source->proxy.surface;
2858 imagew = o->cur.source->proxy.w;
2859 imageh = o->cur.source->proxy.h;
2862 o->proxyrendering = 0;
2865 #if 0 // filtering disabled
2866 /* Now check/update filter */
2867 if (obj->filter && obj->filter->filter)
2869 Filtered_Image *fi = NULL;
2870 //printf("%p has filter: %s\n", obj,obj->filter->dirty?"dirty":"clean");
2871 if (obj->filter->dirty)
2873 if (obj->filter->mode != EVAS_FILTER_MODE_BELOW)
2878 if (obj->filter->key) free(obj->filter->key);
2879 obj->filter->key = NULL;
2880 obj->filter->len = 0;
2881 key = evas_filter_key_get(obj->filter, &len);
2884 obj->filter->key = key;
2885 obj->filter->len = len;
2886 fi = obj->layer->evas->engine.func->image_filtered_get
2887 (o->engine_data, key, len);
2888 if (obj->filter->cached && fi != obj->filter->cached)
2890 obj->layer->evas->engine.func->image_filtered_free
2891 (o->engine_data, obj->filter->cached);
2892 obj->filter->cached = NULL;
2896 else if (obj->filter->cached)
2898 obj->layer->evas->engine.func->image_filtered_free
2899 (o->engine_data, obj->filter->cached);
2902 fi = image_filter_update(obj->layer->evas, obj, pixels,
2903 imagew, imageh, &imagew, &imageh);
2905 obj->filter->dirty = 0;
2906 obj->filter->cached = fi;
2910 fi = obj->filter->cached;
2918 Evas_Coord idw, idh, idx, idy;
2922 if (o->dirty_pixels)
2924 if (o->func.get_pixels)
2926 // Set img object for direct rendering optimization
2927 // Check for image w/h against image geometry w/h
2928 // Check for image color r,g,b,a = {255,255,255,255}
2929 // Check and make sure that there are no maps.
2930 if ( (obj->cur.geometry.w == o->cur.image.w) &&
2931 (obj->cur.geometry.h == o->cur.image.h) &&
2932 (obj->cur.color.r == 255) &&
2933 (obj->cur.color.g == 255) &&
2934 (obj->cur.color.b == 255) &&
2935 (obj->cur.color.a == 255) &&
2938 if (obj->layer->evas->engine.func->gl_img_obj_set)
2940 obj->layer->evas->engine.func->gl_img_obj_set(output, obj, o->cur.has_alpha);
2945 o->func.get_pixels(o->func.get_pixels_data, obj);
2946 if (o->engine_data != pixels)
2947 pixels = o->engine_data;
2948 o->engine_data = obj->layer->evas->engine.func->image_dirty_region
2949 (obj->layer->evas->engine.data.output, o->engine_data,
2950 0, 0, o->cur.image.w, o->cur.image.h);
2952 o->dirty_pixels = 0;
2954 if ((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap))
2956 evas_object_map_update(obj, x, y, imagew, imageh, uvw, uvh);
2958 obj->layer->evas->engine.func->image_map_draw
2959 (output, context, surface, pixels, obj->spans,
2960 o->cur.smooth_scale | obj->cur.map->smooth, 0);
2964 obj->layer->evas->engine.func->image_scale_hint_set(output,
2967 /* This is technically a bug here: If the value is recreated
2968 * (which is returned)it may be a new object, however exactly 0
2969 * of all the evas engines do this. */
2970 obj->layer->evas->engine.func->image_border_set(output, pixels,
2971 o->cur.border.l, o->cur.border.r,
2972 o->cur.border.t, o->cur.border.b);
2973 idx = evas_object_image_figure_x_fill(obj, o->cur.fill.x, o->cur.fill.w, &idw);
2974 idy = evas_object_image_figure_y_fill(obj, o->cur.fill.y, o->cur.fill.h, &idh);
2975 if (idw < 1) idw = 1;
2976 if (idh < 1) idh = 1;
2977 if (idx > 0) idx -= idw;
2978 if (idy > 0) idy -= idh;
2979 while ((int)idx < obj->cur.geometry.w)
2986 if ((o->cur.fill.w == obj->cur.geometry.w) &&
2987 (o->cur.fill.x == 0))
2990 iw = obj->cur.geometry.w;
2993 iw = ((int)(idx + idw)) - ix;
2994 while ((int)idy < obj->cur.geometry.h)
2999 if ((o->cur.fill.h == obj->cur.geometry.h) &&
3000 (o->cur.fill.y == 0))
3002 ih = obj->cur.geometry.h;
3006 ih = ((int)(idy + idh)) - iy;
3007 if ((o->cur.border.l == 0) &&
3008 (o->cur.border.r == 0) &&
3009 (o->cur.border.t == 0) &&
3010 (o->cur.border.b == 0) &&
3011 (o->cur.border.fill != 0))
3012 obj->layer->evas->engine.func->image_draw(output,
3019 obj->cur.geometry.x + ix + x,
3020 obj->cur.geometry.y + iy + y,
3022 o->cur.smooth_scale);
3025 int inx, iny, inw, inh, outx, outy, outw, outh;
3026 int bl, br, bt, bb, bsl, bsr, bst, bsb;
3027 int imw, imh, ox, oy;
3029 ox = obj->cur.geometry.x + ix + x;
3030 oy = obj->cur.geometry.y + iy + y;
3033 bl = o->cur.border.l;
3034 br = o->cur.border.r;
3035 bt = o->cur.border.t;
3036 bb = o->cur.border.b;
3042 if ((bl + br) > imw)
3052 if ((bt + bb) > imh)
3057 if (o->cur.border.scale != 1.0)
3059 bsl = ((double)bl * o->cur.border.scale);
3060 bsr = ((double)br * o->cur.border.scale);
3061 bst = ((double)bt * o->cur.border.scale);
3062 bsb = ((double)bb * o->cur.border.scale);
3066 bsl = bl; bsr = br; bst = bt; bsb = bb;
3072 outx = ox; outy = oy;
3073 outw = bsl; outh = bst;
3074 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3078 inw = imw - bl - br; inh = bt;
3079 outx = ox + bsl; outy = oy;
3080 outw = iw - bsl - bsr; outh = bst;
3081 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3084 inx = imw - br; iny = 0;
3086 outx = ox + iw - bsr; outy = oy;
3087 outw = bsr; outh = bst;
3088 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3092 inw = bl; inh = imh - bt - bb;
3093 outx = ox; outy = oy + bst;
3094 outw = bsl; outh = ih - bst - bsb;
3095 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3098 if (o->cur.border.fill > EVAS_BORDER_FILL_NONE)
3101 inw = imw - bl - br; inh = imh - bt - bb;
3102 outx = ox + bsl; outy = oy + bst;
3103 outw = iw - bsl - bsr; outh = ih - bst - bsb;
3104 if ((o->cur.border.fill == EVAS_BORDER_FILL_SOLID) &&
3105 (obj->cur.cache.clip.a == 255) &&
3106 (obj->cur.render_op == EVAS_RENDER_BLEND))
3108 obj->layer->evas->engine.func->context_render_op_set(output, context,
3110 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3111 obj->layer->evas->engine.func->context_render_op_set(output, context,
3112 obj->cur.render_op);
3115 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3119 inx = imw - br; iny = bt;
3120 inw = br; inh = imh - bt - bb;
3121 outx = ox + iw - bsr; outy = oy + bst;
3122 outw = bsr; outh = ih - bst - bsb;
3123 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3126 inx = 0; iny = imh - bb;
3128 outx = ox; outy = oy + ih - bsb;
3129 outw = bsl; outh = bsb;
3130 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3133 inx = bl; iny = imh - bb;
3134 inw = imw - bl - br; inh = bb;
3135 outx = ox + bsl; outy = oy + ih - bsb;
3136 outw = iw - bsl - bsr; outh = bsb;
3137 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3140 inx = imw - br; iny = imh - bb;
3142 outx = ox + iw - bsr; outy = oy + ih - bsb;
3143 outw = bsr; outh = bsb;
3144 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3147 if (dobreak_h) break;
3151 if (dobreak_w) break;
3158 if (obj->layer->evas->engine.func->gl_img_obj_set)
3160 obj->layer->evas->engine.func->gl_img_obj_set(output, NULL, 0);
3168 evas_object_image_render_pre(Evas_Object *obj)
3170 Evas_Object_Image *o;
3171 int is_v = 0, was_v = 0;
3174 /* dont pre-render the obj twice! */
3175 if (obj->pre_render_done) return;
3176 obj->pre_render_done = 1;
3177 /* pre-render phase. this does anything an object needs to do just before */
3178 /* rendering. this could mean loading the image data, retrieving it from */
3179 /* elsewhere, decoding video etc. */
3180 /* then when this is done the object needs to figure if it changed and */
3181 /* if so what and where and add the appropriate redraw rectangles */
3182 o = (Evas_Object_Image *)(obj->object_data);
3183 e = obj->layer->evas;
3185 if ((o->cur.fill.w < 1) || (o->cur.fill.h < 1))
3187 ERR("%p has invalid fill size: %dx%d. Ignored",
3188 obj, o->cur.fill.w, o->cur.fill.h);
3192 /* if someone is clipping this obj - go calculate the clipper */
3193 if (obj->cur.clipper)
3195 if (obj->cur.cache.clip.dirty)
3196 evas_object_clip_recalc(obj->cur.clipper);
3197 obj->cur.clipper->func->render_pre(obj->cur.clipper);
3199 /* Proxy: Do it early */
3200 if (o->cur.source &&
3201 (o->cur.source->proxy.redraw || o->cur.source->changed))
3203 /* XXX: Do I need to sort out the map here? */
3204 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3208 /* now figure what changed and add draw rects */
3209 /* if it just became visible or invisible */
3210 is_v = evas_object_is_visible(obj);
3211 was_v = evas_object_was_visible(obj);
3214 evas_object_render_pre_visible_change(&e->clip_changes, obj, is_v, was_v);
3215 if (!o->pixel_updates) goto done;
3217 if (obj->changed_map)
3219 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3222 /* it's not visible - we accounted for it appearing or not so just abort */
3223 if (!is_v) goto done;
3224 /* clipper changed this is in addition to anything else for obj */
3225 evas_object_render_pre_clipper_change(&e->clip_changes, obj);
3226 /* if we restacked (layer or just within a layer) and don't clip anyone */
3229 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3230 if (!o->pixel_updates) goto done;
3232 /* if it changed color */
3233 if ((obj->cur.color.r != obj->prev.color.r) ||
3234 (obj->cur.color.g != obj->prev.color.g) ||
3235 (obj->cur.color.b != obj->prev.color.b) ||
3236 (obj->cur.color.a != obj->prev.color.a))
3238 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3239 if (!o->pixel_updates) goto done;
3241 /* if it changed render op */
3242 if (obj->cur.render_op != obj->prev.render_op)
3244 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3245 if (!o->pixel_updates) goto done;
3247 /* if it changed anti_alias */
3248 if (obj->cur.anti_alias != obj->prev.anti_alias)
3250 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3251 if (!o->pixel_updates) goto done;
3255 if (((o->cur.file) && (!o->prev.file)) ||
3256 ((!o->cur.file) && (o->prev.file)) ||
3257 ((o->cur.key) && (!o->prev.key)) ||
3258 ((!o->cur.key) && (o->prev.key))
3261 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3262 if (!o->pixel_updates) goto done;
3264 if ((o->cur.image.w != o->prev.image.w) ||
3265 (o->cur.image.h != o->prev.image.h) ||
3266 (o->cur.has_alpha != o->prev.has_alpha) ||
3267 (o->cur.cspace != o->prev.cspace) ||
3268 (o->cur.smooth_scale != o->prev.smooth_scale))
3270 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3271 if (!o->pixel_updates) goto done;
3273 if ((o->cur.border.l != o->prev.border.l) ||
3274 (o->cur.border.r != o->prev.border.r) ||
3275 (o->cur.border.t != o->prev.border.t) ||
3276 (o->cur.border.b != o->prev.border.b) ||
3277 (o->cur.border.fill != o->prev.border.fill) ||
3278 (o->cur.border.scale != o->prev.border.scale))
3280 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3281 if (!o->pixel_updates) goto done;
3283 if (o->dirty_pixels)
3285 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3286 if (!o->pixel_updates) goto done;
3288 if (o->cur.frame != o->prev.frame)
3290 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3291 if (!o->pixel_updates) goto done;
3295 /* if it changed geometry - and obviously not visibility or color */
3296 /* calculate differences since we have a constant color fill */
3297 /* we really only need to update the differences */
3298 #if 0 // XXX: maybe buggy?
3299 if (((obj->cur.geometry.x != obj->prev.geometry.x) ||
3300 (obj->cur.geometry.y != obj->prev.geometry.y) ||
3301 (obj->cur.geometry.w != obj->prev.geometry.w) ||
3302 (obj->cur.geometry.h != obj->prev.geometry.h)) &&
3303 (o->cur.fill.w == o->prev.fill.w) &&
3304 (o->cur.fill.h == o->prev.fill.h) &&
3305 ((o->cur.fill.x + obj->cur.geometry.x) == (o->prev.fill.x + obj->prev.geometry.x)) &&
3306 ((o->cur.fill.y + obj->cur.geometry.y) == (o->prev.fill.y + obj->prev.geometry.y)) &&
3310 evas_rects_return_difference_rects(&e->clip_changes,
3311 obj->cur.geometry.x,
3312 obj->cur.geometry.y,
3313 obj->cur.geometry.w,
3314 obj->cur.geometry.h,
3315 obj->prev.geometry.x,
3316 obj->prev.geometry.y,
3317 obj->prev.geometry.w,
3318 obj->prev.geometry.h);
3319 if (!o->pixel_updates) goto done;
3322 if (((obj->cur.geometry.x != obj->prev.geometry.x) ||
3323 (obj->cur.geometry.y != obj->prev.geometry.y) ||
3324 (obj->cur.geometry.w != obj->prev.geometry.w) ||
3325 (obj->cur.geometry.h != obj->prev.geometry.h))
3328 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3329 if (!o->pixel_updates) goto done;
3333 if ((o->cur.fill.x != o->prev.fill.x) ||
3334 (o->cur.fill.y != o->prev.fill.y) ||
3335 (o->cur.fill.w != o->prev.fill.w) ||
3336 (o->cur.fill.h != o->prev.fill.h))
3338 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3339 if (!o->pixel_updates) goto done;
3341 if (o->pixel_updates)
3343 if ((o->cur.border.l == 0) &&
3344 (o->cur.border.r == 0) &&
3345 (o->cur.border.t == 0) &&
3346 (o->cur.border.b == 0) &&
3347 (o->cur.image.w > 0) &&
3348 (o->cur.image.h > 0) &&
3349 (!((obj->cur.map) && (obj->cur.usemap))))
3353 EINA_LIST_FREE(o->pixel_updates, rr)
3355 Evas_Coord idw, idh, idx, idy;
3358 e->engine.func->image_dirty_region(e->engine.data.output, o->engine_data, rr->x, rr->y, rr->w, rr->h);
3360 idx = evas_object_image_figure_x_fill(obj, o->cur.fill.x, o->cur.fill.w, &idw);
3361 idy = evas_object_image_figure_y_fill(obj, o->cur.fill.y, o->cur.fill.h, &idh);
3363 if (idw < 1) idw = 1;
3364 if (idh < 1) idh = 1;
3365 if (idx > 0) idx -= idw;
3366 if (idy > 0) idy -= idh;
3367 while (idx < obj->cur.geometry.w)
3373 w = ((int)(idx + idw)) - x;
3374 while (idy < obj->cur.geometry.h)
3379 h = ((int)(idy + idh)) - y;
3381 r.x = (rr->x * w) / o->cur.image.w;
3382 r.y = (rr->y * h) / o->cur.image.h;
3383 r.w = ((rr->w * w) + (o->cur.image.w * 2) - 1) / o->cur.image.w;
3384 r.h = ((rr->h * h) + (o->cur.image.h * 2) - 1) / o->cur.image.h;
3385 r.x += obj->cur.geometry.x + x;
3386 r.y += obj->cur.geometry.y + y;
3387 RECTS_CLIP_TO_RECT(r.x, r.y, r.w, r.h,
3388 obj->cur.cache.clip.x, obj->cur.cache.clip.y,
3389 obj->cur.cache.clip.w, obj->cur.cache.clip.h);
3390 evas_add_rect(&e->clip_changes, r.x, r.y, r.w, r.h);
3396 eina_rectangle_free(rr);
3404 EINA_LIST_FREE(o->pixel_updates, r)
3405 eina_rectangle_free(r);
3406 e->engine.func->image_dirty_region(e->engine.data.output, o->engine_data, 0, 0, o->cur.image.w, o->cur.image.h);
3407 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3412 #if 0 // filtering disabled
3413 if (obj->filter && obj->filter->dirty)
3415 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3418 /* it obviously didn't change - add a NO obscure - this "unupdates" this */
3419 /* area so if there were updates for it they get wiped. don't do it if we */
3420 /* aren't fully opaque and we are visible */
3421 if (evas_object_is_visible(obj) &&
3422 evas_object_is_opaque(obj))
3424 Evas_Coord x, y, w, h;
3426 x = obj->cur.cache.clip.x;
3427 y = obj->cur.cache.clip.y;
3428 w = obj->cur.cache.clip.w;
3429 h = obj->cur.cache.clip.h;
3430 if (obj->cur.clipper)
3432 RECTS_CLIP_TO_RECT(x, y, w, h,
3433 obj->cur.clipper->cur.cache.clip.x,
3434 obj->cur.clipper->cur.cache.clip.y,
3435 obj->cur.clipper->cur.cache.clip.w,
3436 obj->cur.clipper->cur.cache.clip.h);
3438 e->engine.func->output_redraws_rect_del(e->engine.data.output,
3442 evas_object_render_pre_effect_updates(&e->clip_changes, obj, is_v, was_v);
3446 evas_object_image_render_post(Evas_Object *obj)
3448 Evas_Object_Image *o;
3451 /* this moves the current data to the previous state parts of the object */
3452 /* in whatever way is safest for the object. also if we don't need object */
3453 /* data anymore we can free it if the object deems this is a good idea */
3454 o = (Evas_Object_Image *)(obj->object_data);
3455 /* remove those pesky changes */
3456 evas_object_clip_changes_clean(obj);
3457 EINA_LIST_FREE(o->pixel_updates, r)
3458 eina_rectangle_free(r);
3459 /* move cur to prev safely for object data */
3460 evas_object_cur_prev(obj);
3463 /* FIXME: copy strings across */
3466 static unsigned int evas_object_image_id_get(Evas_Object *obj)
3468 Evas_Object_Image *o;
3470 o = (Evas_Object_Image *)(obj->object_data);
3472 return MAGIC_OBJ_IMAGE;
3475 static unsigned int evas_object_image_visual_id_get(Evas_Object *obj)
3477 Evas_Object_Image *o;
3479 o = (Evas_Object_Image *)(obj->object_data);
3481 return MAGIC_OBJ_IMAGE;
3484 static void *evas_object_image_engine_data_get(Evas_Object *obj)
3486 Evas_Object_Image *o;
3488 o = (Evas_Object_Image *)(obj->object_data);
3489 if (!o) return NULL;
3490 return o->engine_data;
3494 evas_object_image_is_opaque(Evas_Object *obj)
3496 Evas_Object_Image *o;
3498 /* this returns 1 if the internal object data implies that the object is */
3499 /* currently fully opaque over the entire rectangle it occupies */
3500 o = (Evas_Object_Image *)(obj->object_data);
3501 /* disable caching due tyo maps screwing with this
3502 o->cur.opaque_valid = 0;
3503 if (o->cur.opaque_valid)
3505 if (!o->cur.opaque) return 0;
3511 /* disable caching */
3512 /* o->cur.opaque_valid = 1; */
3513 if ((o->cur.fill.w < 1) || (o->cur.fill.h < 1))
3514 return o->cur.opaque;
3515 if (((o->cur.border.l != 0) ||
3516 (o->cur.border.r != 0) ||
3517 (o->cur.border.t != 0) ||
3518 (o->cur.border.b != 0)) &&
3519 (!o->cur.border.fill)) return o->cur.opaque;
3520 if (!o->engine_data) return o->cur.opaque;
3526 o->cur.opaque = evas_object_is_opaque(o->cur.source);
3527 return o->cur.opaque; /* FIXME: Should go poke at the object */
3529 if (o->cur.has_alpha)
3532 return o->cur.opaque;
3534 if ((obj->cur.map) && (obj->cur.usemap))
3536 Evas_Map *m = obj->cur.map;
3538 if ((m->points[0].a == 255) &&
3539 (m->points[1].a == 255) &&
3540 (m->points[2].a == 255) &&
3541 (m->points[3].a == 255))
3544 ((m->points[0].x == m->points[3].x) &&
3545 (m->points[1].x == m->points[2].x) &&
3546 (m->points[0].y == m->points[1].y) &&
3547 (m->points[2].y == m->points[3].y))
3549 ((m->points[0].x == m->points[1].x) &&
3550 (m->points[2].x == m->points[3].x) &&
3551 (m->points[0].y == m->points[3].y) &&
3552 (m->points[1].y == m->points[2].y))
3555 if ((m->points[0].x == obj->cur.geometry.x) &&
3556 (m->points[0].y == obj->cur.geometry.y) &&
3557 (m->points[2].x == (obj->cur.geometry.x + obj->cur.geometry.w)) &&
3558 (m->points[2].y == (obj->cur.geometry.y + obj->cur.geometry.h)))
3559 return o->cur.opaque;
3563 return o->cur.opaque;
3565 if (obj->cur.render_op == EVAS_RENDER_COPY) return o->cur.opaque;
3566 return o->cur.opaque;
3570 evas_object_image_was_opaque(Evas_Object *obj)
3572 Evas_Object_Image *o;
3574 /* this returns 1 if the internal object data implies that the object was */
3575 /* previously fully opaque over the entire rectangle it occupies */
3576 o = (Evas_Object_Image *)(obj->object_data);
3577 if (o->prev.opaque_valid)
3579 if (!o->prev.opaque) return 0;
3584 o->prev.opaque_valid = 1;
3585 if ((o->prev.fill.w < 1) || (o->prev.fill.h < 1))
3587 if (((o->prev.border.l != 0) ||
3588 (o->prev.border.r != 0) ||
3589 (o->prev.border.t != 0) ||
3590 (o->prev.border.b != 0)) &&
3591 (!o->prev.border.fill)) return 0;
3592 if (!o->engine_data) return 0;
3596 if (o->prev.source) return 0; /* FIXME: Should go poke at the object */
3597 if (obj->prev.usemap) return 0;
3598 if (obj->prev.render_op == EVAS_RENDER_COPY) return 1;
3599 if (o->prev.has_alpha) return 0;
3600 if (obj->prev.render_op != EVAS_RENDER_BLEND) return 0;
3605 evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
3607 Evas_Object_Image *o;
3609 int w, h, stride, iw, ih;
3613 o = (Evas_Object_Image *)(obj->object_data);
3615 x -= obj->cur.cache.clip.x;
3616 y -= obj->cur.cache.clip.y;
3617 w = obj->cur.cache.clip.w;
3618 h = obj->cur.cache.clip.h;
3619 iw = o->cur.image.w;
3620 ih = o->cur.image.h;
3622 if ((x < 0) || (y < 0) || (x >= w) || (y >= h)) return 0;
3623 if (!o->cur.has_alpha) return 1;
3625 // FIXME: proxy needs to be honored
3628 x = obj->cur.map->mx;
3629 y = obj->cur.map->my;
3633 int bl, br, bt, bb, bsl, bsr, bst, bsb;
3635 bl = o->cur.border.l;
3636 br = o->cur.border.r;
3637 bt = o->cur.border.t;
3638 bb = o->cur.border.b;
3659 if (o->cur.border.scale != 1.0)
3661 bsl = ((double)bl * o->cur.border.scale);
3662 bsr = ((double)br * o->cur.border.scale);
3663 bst = ((double)bt * o->cur.border.scale);
3664 bsb = ((double)bb * o->cur.border.scale);
3668 bsl = bl; bsr = br; bst = bt; bsb = bb;
3681 if (o->cur.border.fill != EVAS_BORDER_FILL_DEFAULT)
3683 if ((x > bsl) && (x < (w - bsr)) &&
3684 (y > bst) && (y < (h - bsb)))
3686 if (o->cur.border.fill == EVAS_BORDER_FILL_SOLID) return 1;
3691 if (x < bsl) x = (x * bl) / bsl;
3692 else if (x > (w - bsr)) x = iw - (((w - x) * br) / bsr);
3693 else if ((bsl + bsr) < w) x = bl + (((x - bsl) * (iw - bl - br)) / (w - bsl - bsr));
3696 if (y < bst) y = (y * bt) / bst;
3697 else if (y > (h - bsb)) y = ih - (((h - y) * bb) / bsb);
3698 else if ((bst + bsb) < h) y = bt + (((y - bst) * (ih - bt - bb)) / (h - bst - bsb));
3704 if (x >= iw) x = iw - 1;
3705 if (y >= ih) y = ih - 1;
3707 stride = o->cur.image.stride;
3709 o->engine_data = obj->layer->evas->engine.func->image_data_get
3710 (obj->layer->evas->engine.data.output,
3722 switch (o->cur.cspace)
3724 case EVAS_COLORSPACE_ARGB8888:
3725 data = ((DATA32*)(data) + ((y * (stride >> 2)) + x));
3726 a = (*((DATA32*)(data)) >> 24) & 0xff;
3728 case EVAS_COLORSPACE_RGB565_A5P:
3729 data = (void*) ((DATA16*)(data) + (h * (stride >> 1)));
3730 data = (void*) ((DATA8*)(data) + ((y * (stride >> 1)) + x));
3731 a = (*((DATA8*)(data))) & 0x1f;
3739 return_value = (a != 0);
3744 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
3747 return return_value;
3751 evas_object_image_has_opaque_rect(Evas_Object *obj)
3753 Evas_Object_Image *o;
3755 o = (Evas_Object_Image *)(obj->object_data);
3756 if ((obj->cur.map) && (obj->cur.usemap)) return 0;
3757 if (((o->cur.border.l | o->cur.border.r | o->cur.border.t | o->cur.border.b) != 0) &&
3758 (o->cur.border.fill == EVAS_BORDER_FILL_SOLID) &&
3759 (obj->cur.render_op == EVAS_RENDER_BLEND) &&
3760 (obj->cur.cache.clip.a == 255) &&
3761 (o->cur.fill.x == 0) &&
3762 (o->cur.fill.y == 0) &&
3763 (o->cur.fill.w == obj->cur.geometry.w) &&
3764 (o->cur.fill.h == obj->cur.geometry.h)
3770 evas_object_image_get_opaque_rect(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
3772 Evas_Object_Image *o;
3774 o = (Evas_Object_Image *)(obj->object_data);
3775 if (o->cur.border.scale == 1.0)
3777 *x = obj->cur.geometry.x + o->cur.border.l;
3778 *y = obj->cur.geometry.y + o->cur.border.t;
3779 *w = obj->cur.geometry.w - (o->cur.border.l + o->cur.border.r);
3781 *h = obj->cur.geometry.h - (o->cur.border.t + o->cur.border.b);
3786 *x = obj->cur.geometry.x + (o->cur.border.l * o->cur.border.scale);
3787 *y = obj->cur.geometry.y + (o->cur.border.t * o->cur.border.scale);
3788 *w = obj->cur.geometry.w - ((o->cur.border.l * o->cur.border.scale) + (o->cur.border.r * o->cur.border.scale));
3790 *h = obj->cur.geometry.h - ((o->cur.border.t * o->cur.border.scale) + (o->cur.border.b * o->cur.border.scale));
3797 evas_object_image_can_map(Evas_Object *obj __UNUSED__)
3803 evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_Colorspace to_cspace)
3810 switch (o->cur.cspace)
3812 case EVAS_COLORSPACE_ARGB8888:
3813 out = evas_common_convert_argb8888_to(data,
3816 o->cur.image.stride >> 2,
3820 case EVAS_COLORSPACE_RGB565_A5P:
3821 out = evas_common_convert_rgb565_a5p_to(data,
3824 o->cur.image.stride >> 1,
3828 case EVAS_COLORSPACE_YCBCR422601_PL:
3829 out = evas_common_convert_yuv_422_601_to(data,
3834 case EVAS_COLORSPACE_YCBCR422P601_PL:
3835 out = evas_common_convert_yuv_422P_601_to(data,
3840 case EVAS_COLORSPACE_YCBCR420NV12601_PL:
3841 out = evas_common_convert_yuv_420_601_to(data,
3846 case EVAS_COLORSPACE_YCBCR420TM12601_PL:
3847 out = evas_common_convert_yuv_420T_601_to(data,
3853 WRN("unknow colorspace: %i\n", o->cur.cspace);
3861 evas_object_image_filled_resize_listener(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *einfo __UNUSED__)
3865 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3866 evas_object_image_fill_set(obj, 0, 0, w, h);
3871 _evas_object_image_preloading_get(const Evas_Object *obj)
3873 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3874 if (!o) return EINA_FALSE;
3875 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
3878 return o->preloading;
3882 _evas_object_image_preloading_set(Evas_Object *obj, Eina_Bool preloading)
3884 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3885 o->preloading = preloading;
3889 _evas_object_image_preloading_check(Evas_Object *obj)
3891 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3892 if (obj->layer->evas->engine.func->image_load_error_get)
3893 o->load_error = obj->layer->evas->engine.func->image_load_error_get
3894 (obj->layer->evas->engine.data.output, o->engine_data);
3898 _evas_object_image_video_parent_get(Evas_Object *obj)
3900 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3902 return o->video_surface ? o->video.parent : NULL;
3906 _evas_object_image_video_overlay_show(Evas_Object *obj)
3908 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3910 if (obj->cur.cache.clip.x != obj->prev.cache.clip.x ||
3911 obj->cur.cache.clip.y != obj->prev.cache.clip.y ||
3912 o->created || !o->video_visible)
3913 o->video.move(o->video.data, obj, &o->video, obj->cur.cache.clip.x, obj->cur.cache.clip.y);
3914 if (obj->cur.cache.clip.w != obj->prev.cache.clip.w ||
3915 obj->cur.cache.clip.h != obj->prev.cache.clip.h ||
3916 o->created || !o->video_visible)
3917 o->video.resize(o->video.data, obj, &o->video, obj->cur.cache.clip.w, obj->cur.cache.clip.h);
3918 if (!o->video_visible || o->created)
3920 o->video.show(o->video.data, obj, &o->video);
3924 /* Cancel dirty on the image */
3927 o->dirty_pixels = 0;
3928 EINA_LIST_FREE(o->pixel_updates, r)
3929 eina_rectangle_free(r);
3931 o->video_visible = EINA_TRUE;
3932 o->created = EINA_FALSE;
3936 _evas_object_image_video_overlay_hide(Evas_Object *obj)
3938 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3940 if (o->video_visible || o->created)
3941 o->video.hide(o->video.data, obj, &o->video);
3942 if (evas_object_is_visible(obj))
3943 o->video.update_pixels(o->video.data, obj, &o->video);
3944 o->video_visible = EINA_FALSE;
3945 o->created = EINA_FALSE;
3948 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/