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);
452 CRIT("Setting deleted object %p as image source %p", src, obj);
458 CRIT("Setting object %p to deleted image source %p", src, obj);
464 CRIT("No evas surface associated with source object (%p)", obj);
468 if ((obj->layer && src->layer) &&
469 (obj->layer->evas != src->layer->evas))
471 CRIT("Setting object %p from Evas (%p) from another Evas (%p)", src, src->layer->evas, obj->layer->evas);
477 CRIT("Setting object %p as a source for itself", obj);
481 if (o->cur.source == src) return EINA_TRUE;
483 _evas_object_image_cleanup(obj, o);
484 /* Kill the image if any */
485 if (o->cur.file || o->cur.key)
486 evas_object_image_file_set(obj, NULL, NULL);
490 _proxy_set(obj, src);
498 evas_object_image_source_get(const Evas_Object *obj)
500 Evas_Object_Image *o;
502 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
505 o = obj->object_data;
506 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
510 return o->cur.source;
514 evas_object_image_source_unset(Evas_Object *obj)
516 return evas_object_image_source_set(obj, NULL);
520 evas_object_image_border_set(Evas_Object *obj, int l, int r, int t, int b)
522 Evas_Object_Image *o;
524 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
527 o = (Evas_Object_Image *)(obj->object_data);
528 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
535 if ((o->cur.border.l == l) &&
536 (o->cur.border.r == r) &&
537 (o->cur.border.t == t) &&
538 (o->cur.border.b == b)) return;
543 o->cur.opaque_valid = 0;
545 evas_object_change(obj);
549 evas_object_image_border_get(const Evas_Object *obj, int *l, int *r, int *t, int *b)
551 Evas_Object_Image *o;
553 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
560 o = (Evas_Object_Image *)(obj->object_data);
561 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
568 if (l) *l = o->cur.border.l;
569 if (r) *r = o->cur.border.r;
570 if (t) *t = o->cur.border.t;
571 if (b) *b = o->cur.border.b;
575 evas_object_image_border_center_fill_set(Evas_Object *obj, Evas_Border_Fill_Mode fill)
577 Evas_Object_Image *o;
579 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
582 o = (Evas_Object_Image *)(obj->object_data);
583 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
586 if (fill == o->cur.border.fill) return;
587 o->cur.border.fill = fill;
589 evas_object_change(obj);
592 EAPI Evas_Border_Fill_Mode
593 evas_object_image_border_center_fill_get(const Evas_Object *obj)
595 Evas_Object_Image *o;
597 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
600 o = (Evas_Object_Image *)(obj->object_data);
601 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
604 return o->cur.border.fill;
608 evas_object_image_filled_set(Evas_Object *obj, Eina_Bool setting)
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);
621 if (o->filled == setting) return;
625 evas_object_event_callback_del(obj, EVAS_CALLBACK_RESIZE, evas_object_image_filled_resize_listener);
630 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
631 evas_object_image_fill_set(obj, 0, 0, w, h);
633 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, evas_object_image_filled_resize_listener, NULL);
638 evas_object_image_filled_get(const Evas_Object *obj)
640 Evas_Object_Image *o;
642 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
645 o = (Evas_Object_Image *)(obj->object_data);
646 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
654 evas_object_image_border_scale_set(Evas_Object *obj, double scale)
656 Evas_Object_Image *o;
658 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
661 o = (Evas_Object_Image *)(obj->object_data);
662 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
665 if (scale == o->cur.border.scale) return;
666 o->cur.border.scale = scale;
668 evas_object_change(obj);
672 evas_object_image_border_scale_get(const Evas_Object *obj)
674 Evas_Object_Image *o;
676 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
679 o = (Evas_Object_Image *)(obj->object_data);
680 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
683 return o->cur.border.scale;
687 evas_object_image_fill_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
689 Evas_Object_Image *o;
696 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);
704 if ((o->cur.fill.x == x) &&
705 (o->cur.fill.y == y) &&
706 (o->cur.fill.w == w) &&
707 (o->cur.fill.h == h)) return;
712 o->cur.opaque_valid = 0;
714 evas_object_change(obj);
718 evas_object_image_fill_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
720 Evas_Object_Image *o;
722 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
729 o = (Evas_Object_Image *)(obj->object_data);
730 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
737 if (x) *x = o->cur.fill.x;
738 if (y) *y = o->cur.fill.y;
739 if (w) *w = o->cur.fill.w;
740 if (h) *h = o->cur.fill.h;
745 evas_object_image_fill_spread_set(Evas_Object *obj, Evas_Fill_Spread spread)
747 Evas_Object_Image *o;
749 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
752 o = (Evas_Object_Image *)(obj->object_data);
753 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
756 if (spread == (Evas_Fill_Spread)o->cur.spread) return;
757 o->cur.spread = spread;
759 evas_object_change(obj);
762 EAPI Evas_Fill_Spread
763 evas_object_image_fill_spread_get(const Evas_Object *obj)
765 Evas_Object_Image *o;
767 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
768 return EVAS_TEXTURE_REPEAT;
770 o = (Evas_Object_Image *)(obj->object_data);
771 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
772 return EVAS_TEXTURE_REPEAT;
774 return (Evas_Fill_Spread)o->cur.spread;
778 evas_object_image_size_set(Evas_Object *obj, int w, int h)
780 Evas_Object_Image *o;
783 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
786 o = (Evas_Object_Image *)(obj->object_data);
787 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
790 _evas_object_image_cleanup(obj, o);
793 if (w > 32768) return;
794 if (h > 32768) return;
795 if ((w == o->cur.image.w) &&
796 (h == o->cur.image.h)) return;
800 o->engine_data = obj->layer->evas->engine.func->image_size_set(obj->layer->evas->engine.data.output,
804 o->engine_data = obj->layer->evas->engine.func->image_new_from_copied_data
805 (obj->layer->evas->engine.data.output, w, h, NULL, o->cur.has_alpha,
810 if (obj->layer->evas->engine.func->image_scale_hint_set)
811 obj->layer->evas->engine.func->image_scale_hint_set
812 (obj->layer->evas->engine.data.output,
813 o->engine_data, o->scale_hint);
814 if (obj->layer->evas->engine.func->image_content_hint_set)
815 obj->layer->evas->engine.func->image_content_hint_set
816 (obj->layer->evas->engine.data.output,
817 o->engine_data, o->content_hint);
818 if (obj->layer->evas->engine.func->image_stride_get)
819 obj->layer->evas->engine.func->image_stride_get
820 (obj->layer->evas->engine.data.output,
821 o->engine_data, &stride);
827 o->cur.image.stride = stride;
829 /* FIXME - in engine call above
831 o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
835 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
837 evas_object_change(obj);
841 evas_object_image_size_get(const Evas_Object *obj, int *w, int *h)
843 Evas_Object_Image *o;
845 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
850 o = (Evas_Object_Image *)(obj->object_data);
851 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
856 if (w) *w = o->cur.image.w;
857 if (h) *h = o->cur.image.h;
861 evas_object_image_stride_get(const Evas_Object *obj)
863 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 return o->cur.image.stride;
876 evas_object_image_load_error_get(const Evas_Object *obj)
878 Evas_Object_Image *o;
880 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
883 o = (Evas_Object_Image *)(obj->object_data);
884 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
887 return o->load_error;
891 evas_object_image_data_convert(Evas_Object *obj, Evas_Colorspace to_cspace)
893 Evas_Object_Image *o;
897 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
900 o = (Evas_Object_Image *)(obj->object_data);
901 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
904 if ((o->preloading) && (o->engine_data))
907 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
911 if (!o->engine_data) return NULL;
912 if (o->video_surface)
913 o->video.update_pixels(o->video.data, obj, &o->video);
914 if (o->cur.cspace == to_cspace) return NULL;
917 obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
918 o->engine_data, 0, &data,
920 result = evas_object_image_data_convert_internal(o, data, to_cspace);
924 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
925 o->engine_data, data);
931 evas_object_image_data_set(Evas_Object *obj, void *data)
933 Evas_Object_Image *o;
936 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
939 o = (Evas_Object_Image *)(obj->object_data);
940 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
943 _evas_object_image_cleanup(obj, o);
944 p_data = o->engine_data;
950 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
957 obj->layer->evas->engine.func->image_new_from_data(obj->layer->evas->engine.data.output,
968 if (obj->layer->evas->engine.func->image_scale_hint_set)
969 obj->layer->evas->engine.func->image_scale_hint_set
970 (obj->layer->evas->engine.data.output,
971 o->engine_data, o->scale_hint);
972 if (obj->layer->evas->engine.func->image_content_hint_set)
973 obj->layer->evas->engine.func->image_content_hint_set
974 (obj->layer->evas->engine.data.output,
975 o->engine_data, o->content_hint);
976 if (obj->layer->evas->engine.func->image_stride_get)
977 obj->layer->evas->engine.func->image_stride_get
978 (obj->layer->evas->engine.data.output,
979 o->engine_data, &stride);
981 stride = o->cur.image.w * 4;
982 o->cur.image.stride = stride;
988 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
990 o->load_error = EVAS_LOAD_ERROR_NONE;
993 o->cur.image.stride = 0;
994 o->engine_data = NULL;
996 /* FIXME - in engine call above
998 o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1002 if (o->pixels_checked_out > 0) o->pixels_checked_out--;
1003 if (p_data != o->engine_data)
1005 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
1006 o->pixels_checked_out = 0;
1009 evas_object_change(obj);
1013 evas_object_image_data_get(const Evas_Object *obj, Eina_Bool for_writing)
1015 Evas_Object_Image *o;
1018 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1021 o = (Evas_Object_Image *)(obj->object_data);
1022 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1025 if (!o->engine_data) return NULL;
1028 if (obj->layer->evas->engine.func->image_scale_hint_set)
1029 obj->layer->evas->engine.func->image_scale_hint_set
1030 (obj->layer->evas->engine.data.output,
1031 o->engine_data, o->scale_hint);
1032 if (obj->layer->evas->engine.func->image_content_hint_set)
1033 obj->layer->evas->engine.func->image_content_hint_set
1034 (obj->layer->evas->engine.data.output,
1035 o->engine_data, o->content_hint);
1037 obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1042 /* if we fail to get engine_data, we have to return NULL */
1043 if (!o->engine_data) return NULL;
1049 if (obj->layer->evas->engine.func->image_stride_get)
1050 obj->layer->evas->engine.func->image_stride_get
1051 (obj->layer->evas->engine.data.output,
1052 o->engine_data, &stride);
1054 stride = o->cur.image.w * 4;
1055 o->cur.image.stride = stride;
1057 o->pixels_checked_out++;
1060 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
1067 evas_object_image_preload(Evas_Object *obj, Eina_Bool cancel)
1069 Evas_Object_Image *o;
1071 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1074 o = (Evas_Object_Image *)(obj->object_data);
1075 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1078 if (!o->engine_data)
1081 evas_object_inform_call_image_preloaded(obj);
1084 // FIXME: if already busy preloading, then dont request again until
1091 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
1101 obj->layer->evas->engine.func->image_data_preload_request(obj->layer->evas->engine.data.output,
1109 evas_object_image_data_copy_set(Evas_Object *obj, void *data)
1111 Evas_Object_Image *o;
1114 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1117 o = (Evas_Object_Image *)(obj->object_data);
1118 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1121 _evas_object_image_cleanup(obj, o);
1122 if ((o->cur.image.w <= 0) ||
1123 (o->cur.image.h <= 0)) return;
1125 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
1128 obj->layer->evas->engine.func->image_new_from_copied_data(obj->layer->evas->engine.data.output,
1139 obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1142 if (obj->layer->evas->engine.func->image_scale_hint_set)
1143 obj->layer->evas->engine.func->image_scale_hint_set
1144 (obj->layer->evas->engine.data.output,
1145 o->engine_data, o->scale_hint);
1146 if (obj->layer->evas->engine.func->image_content_hint_set)
1147 obj->layer->evas->engine.func->image_content_hint_set
1148 (obj->layer->evas->engine.data.output,
1149 o->engine_data, o->content_hint);
1150 if (obj->layer->evas->engine.func->image_stride_get)
1151 obj->layer->evas->engine.func->image_stride_get
1152 (obj->layer->evas->engine.data.output,
1153 o->engine_data, &stride);
1155 stride = o->cur.image.w * 4;
1156 o->cur.image.stride = stride;
1158 o->pixels_checked_out = 0;
1159 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
1163 evas_object_image_data_update_add(Evas_Object *obj, int x, int y, int w, int h)
1165 Evas_Object_Image *o;
1168 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1171 o = (Evas_Object_Image *)(obj->object_data);
1172 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1175 RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, o->cur.image.w, o->cur.image.h);
1176 if ((w <= 0) || (h <= 0)) return;
1177 NEW_RECT(r, x, y, w, h);
1178 if (r) o->pixel_updates = eina_list_append(o->pixel_updates, r);
1180 evas_object_change(obj);
1184 evas_object_image_alpha_set(Evas_Object *obj, Eina_Bool has_alpha)
1186 Evas_Object_Image *o;
1188 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1191 o = (Evas_Object_Image *)(obj->object_data);
1192 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1195 if ((o->preloading) && (o->engine_data))
1198 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
1202 if (((has_alpha) && (o->cur.has_alpha)) ||
1203 ((!has_alpha) && (!o->cur.has_alpha)))
1205 o->cur.has_alpha = has_alpha;
1211 obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1214 if (obj->layer->evas->engine.func->image_scale_hint_set)
1215 obj->layer->evas->engine.func->image_scale_hint_set
1216 (obj->layer->evas->engine.data.output,
1217 o->engine_data, o->scale_hint);
1218 if (obj->layer->evas->engine.func->image_content_hint_set)
1219 obj->layer->evas->engine.func->image_content_hint_set
1220 (obj->layer->evas->engine.data.output,
1221 o->engine_data, o->content_hint);
1222 if (obj->layer->evas->engine.func->image_stride_get)
1223 obj->layer->evas->engine.func->image_stride_get
1224 (obj->layer->evas->engine.data.output,
1225 o->engine_data, &stride);
1227 stride = o->cur.image.w * 4;
1228 o->cur.image.stride = stride;
1230 evas_object_image_data_update_add(obj, 0, 0, o->cur.image.w, o->cur.image.h);
1231 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
1236 evas_object_image_alpha_get(const Evas_Object *obj)
1238 Evas_Object_Image *o;
1240 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1243 o = (Evas_Object_Image *)(obj->object_data);
1244 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1247 return o->cur.has_alpha;
1251 evas_object_image_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth_scale)
1253 Evas_Object_Image *o;
1255 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1258 o = (Evas_Object_Image *)(obj->object_data);
1259 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1262 if (((smooth_scale) && (o->cur.smooth_scale)) ||
1263 ((!smooth_scale) && (!o->cur.smooth_scale)))
1265 o->cur.smooth_scale = smooth_scale;
1267 evas_object_change(obj);
1271 evas_object_image_smooth_scale_get(const Evas_Object *obj)
1273 Evas_Object_Image *o;
1275 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1278 o = (Evas_Object_Image *)(obj->object_data);
1279 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1282 return o->cur.smooth_scale;
1286 evas_object_image_reload(Evas_Object *obj)
1288 Evas_Object_Image *o;
1290 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1293 o = (Evas_Object_Image *)(obj->object_data);
1294 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1297 if ((o->preloading) && (o->engine_data))
1300 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
1304 if ((!o->cur.file) ||
1305 (o->pixels_checked_out > 0)) return;
1307 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);
1308 evas_object_image_unload(obj, 1);
1309 evas_object_inform_call_image_unloaded(obj);
1310 evas_object_image_load(obj);
1311 o->prev.file = NULL;
1314 evas_object_change(obj);
1318 evas_object_image_save(const Evas_Object *obj, const char *file, const char *key, const char *flags)
1320 Evas_Object_Image *o;
1321 DATA32 *data = NULL;
1322 int quality = 80, compress = 9, ok = 0;
1325 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1328 o = (Evas_Object_Image *)(obj->object_data);
1329 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1333 if (!o->engine_data) return 0;
1334 o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1344 tflags = alloca(strlen(flags) + 1);
1345 strcpy(tflags, flags);
1349 pp = strchr(p, ' ');
1351 sscanf(p, "quality=%i", &quality);
1352 sscanf(p, "compress=%i", &compress);
1357 im = (RGBA_Image*) evas_cache_image_data(evas_common_image_cache_get(),
1362 EVAS_COLORSPACE_ARGB8888);
1365 if (o->cur.cspace == EVAS_COLORSPACE_ARGB8888)
1366 im->image.data = data;
1368 im->image.data = evas_object_image_data_convert_internal(o,
1370 EVAS_COLORSPACE_ARGB8888);
1373 ok = evas_common_save_image_to_file(im, file, key, quality, compress);
1375 if (o->cur.cspace != EVAS_COLORSPACE_ARGB8888)
1376 free(im->image.data);
1379 evas_cache_image_drop(&im->cache_entry);
1381 o->engine_data = obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
1388 evas_object_image_pixels_import(Evas_Object *obj, Evas_Pixel_Import_Source *pixels)
1390 Evas_Object_Image *o;
1392 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1395 o = (Evas_Object_Image *)(obj->object_data);
1396 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1399 _evas_object_image_cleanup(obj, o);
1400 if ((pixels->w != o->cur.image.w) || (pixels->h != o->cur.image.h)) return 0;
1401 switch (pixels->format)
1404 case EVAS_PIXEL_FORMAT_ARGB32:
1408 DATA32 *image_pixels = NULL;
1411 obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1416 /* FIXME: need to actualyl support this */
1417 /* memcpy(image_pixels, pixels->rows, o->cur.image.w * o->cur.image.h * 4);*/
1420 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
1425 obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1429 evas_object_change(obj);
1434 #ifdef BUILD_CONVERT_YUV
1435 case EVAS_PIXEL_FORMAT_YUV420P_601:
1439 DATA32 *image_pixels = NULL;
1442 obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1448 evas_common_convert_yuv_420p_601_rgba((DATA8 **) pixels->rows,
1449 (DATA8 *) image_pixels,
1454 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
1459 obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1463 evas_object_change(obj);
1476 evas_object_image_pixels_get_callback_set(Evas_Object *obj, Evas_Object_Image_Pixels_Get_Cb func, void *data)
1478 Evas_Object_Image *o;
1480 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1483 o = (Evas_Object_Image *)(obj->object_data);
1484 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1487 o->func.get_pixels = func;
1488 o->func.get_pixels_data = data;
1492 evas_object_image_pixels_dirty_set(Evas_Object *obj, Eina_Bool dirty)
1494 Evas_Object_Image *o;
1496 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1499 o = (Evas_Object_Image *)(obj->object_data);
1500 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1503 if (dirty) o->dirty_pixels = 1;
1504 else o->dirty_pixels = 0;
1506 evas_object_change(obj);
1510 evas_object_image_pixels_dirty_get(const Evas_Object *obj)
1512 Evas_Object_Image *o;
1514 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1517 o = (Evas_Object_Image *)(obj->object_data);
1518 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1521 if (o->dirty_pixels) return 1;
1526 evas_object_image_load_dpi_set(Evas_Object *obj, double dpi)
1528 Evas_Object_Image *o;
1530 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1533 o = (Evas_Object_Image *)(obj->object_data);
1534 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1537 if (dpi == o->load_opts.dpi) return;
1538 o->load_opts.dpi = dpi;
1541 evas_object_image_unload(obj, 0);
1542 evas_object_inform_call_image_unloaded(obj);
1543 evas_object_image_load(obj);
1545 evas_object_change(obj);
1550 evas_object_image_load_dpi_get(const Evas_Object *obj)
1552 Evas_Object_Image *o;
1554 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1557 o = (Evas_Object_Image *)(obj->object_data);
1558 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1561 return o->load_opts.dpi;
1565 evas_object_image_load_size_set(Evas_Object *obj, int w, int h)
1567 Evas_Object_Image *o;
1569 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1572 o = (Evas_Object_Image *)(obj->object_data);
1573 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1576 if ((o->load_opts.w == w) && (o->load_opts.h == h)) return;
1581 evas_object_image_unload(obj, 0);
1582 evas_object_inform_call_image_unloaded(obj);
1583 evas_object_image_load(obj);
1585 evas_object_change(obj);
1590 evas_object_image_load_size_get(const Evas_Object *obj, int *w, int *h)
1592 Evas_Object_Image *o;
1594 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1597 o = (Evas_Object_Image *)(obj->object_data);
1598 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1601 if (w) *w = o->load_opts.w;
1602 if (h) *h = o->load_opts.h;
1606 evas_object_image_load_scale_down_set(Evas_Object *obj, int scale_down)
1608 Evas_Object_Image *o;
1610 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1613 o = (Evas_Object_Image *)(obj->object_data);
1614 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1617 if (o->load_opts.scale_down_by == scale_down) return;
1618 o->load_opts.scale_down_by = scale_down;
1621 evas_object_image_unload(obj, 0);
1622 evas_object_inform_call_image_unloaded(obj);
1623 evas_object_image_load(obj);
1625 evas_object_change(obj);
1630 evas_object_image_load_scale_down_get(const Evas_Object *obj)
1632 Evas_Object_Image *o;
1634 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1637 o = (Evas_Object_Image *)(obj->object_data);
1638 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1641 return o->load_opts.scale_down_by;
1645 evas_object_image_load_region_set(Evas_Object *obj, int x, int y, int w, int h)
1647 Evas_Object_Image *o;
1649 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1652 o = (Evas_Object_Image *)(obj->object_data);
1653 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1656 if ((o->load_opts.region.x == x) && (o->load_opts.region.y == y) &&
1657 (o->load_opts.region.w == w) && (o->load_opts.region.h == h)) return;
1658 o->load_opts.region.x = x;
1659 o->load_opts.region.y = y;
1660 o->load_opts.region.w = w;
1661 o->load_opts.region.h = h;
1664 evas_object_image_unload(obj, 0);
1665 evas_object_inform_call_image_unloaded(obj);
1666 evas_object_image_load(obj);
1668 evas_object_change(obj);
1673 evas_object_image_load_region_get(const Evas_Object *obj, int *x, int *y, int *w, int *h)
1675 Evas_Object_Image *o;
1677 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1680 o = (Evas_Object_Image *)(obj->object_data);
1681 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1684 if (x) *x = o->load_opts.region.x;
1685 if (y) *y = o->load_opts.region.y;
1686 if (w) *w = o->load_opts.region.w;
1687 if (h) *h = o->load_opts.region.h;
1691 evas_object_image_load_orientation_set(Evas_Object *obj, Eina_Bool enable)
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);
1702 o->load_opts.orientation = !!enable;
1706 evas_object_image_load_orientation_get(const Evas_Object *obj)
1708 Evas_Object_Image *o;
1710 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1713 o = (Evas_Object_Image *)(obj->object_data);
1714 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1717 return o->load_opts.orientation;
1721 evas_object_image_colorspace_set(Evas_Object *obj, Evas_Colorspace cspace)
1723 Evas_Object_Image *o;
1725 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1728 o = (Evas_Object_Image *)(obj->object_data);
1729 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1733 _evas_object_image_cleanup(obj, o);
1735 o->cur.cspace = cspace;
1737 obj->layer->evas->engine.func->image_colorspace_set(obj->layer->evas->engine.data.output,
1742 EAPI Evas_Colorspace
1743 evas_object_image_colorspace_get(const Evas_Object *obj)
1745 Evas_Object_Image *o;
1747 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1748 return EVAS_COLORSPACE_ARGB8888;
1750 o = (Evas_Object_Image *)(obj->object_data);
1751 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1752 return EVAS_COLORSPACE_ARGB8888;
1754 return o->cur.cspace;
1758 evas_object_image_video_surface_set(Evas_Object *obj, Evas_Video_Surface *surf)
1760 Evas_Object_Image *o;
1762 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1765 o = (Evas_Object_Image *)(obj->object_data);
1766 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1769 _evas_object_image_cleanup(obj, o);
1770 if (o->video_surface)
1772 o->video_surface = 0;
1773 obj->layer->evas->video_objects = eina_list_remove(obj->layer->evas->video_objects, obj);
1778 if (surf->version != EVAS_VIDEO_SURFACE_VERSION) return ;
1780 if (!surf->update_pixels ||
1787 o->created = EINA_TRUE;
1788 o->video_surface = 1;
1791 obj->layer->evas->video_objects = eina_list_append(obj->layer->evas->video_objects, obj);
1795 o->video_surface = 0;
1796 o->video.update_pixels = NULL;
1797 o->video.move = NULL;
1798 o->video.resize = NULL;
1799 o->video.hide = NULL;
1800 o->video.show = NULL;
1801 o->video.data = NULL;
1805 EAPI const Evas_Video_Surface *
1806 evas_object_image_video_surface_get(const Evas_Object *obj)
1808 Evas_Object_Image *o;
1810 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1813 o = (Evas_Object_Image *)(obj->object_data);
1814 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1817 if (!o->video_surface) return NULL;
1822 evas_object_image_native_surface_set(Evas_Object *obj, Evas_Native_Surface *surf)
1824 Evas_Object_Image *o;
1826 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1829 o = (Evas_Object_Image *)(obj->object_data);
1830 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1833 _evas_object_image_cleanup(obj, o);
1834 if (!obj->layer->evas->engine.func->image_native_set) return;
1836 ((surf->version < 2) ||
1837 (surf->version > EVAS_NATIVE_SURFACE_VERSION))) return;
1839 obj->layer->evas->engine.func->image_native_set(obj->layer->evas->engine.data.output,
1844 EAPI Evas_Native_Surface *
1845 evas_object_image_native_surface_get(const Evas_Object *obj)
1847 Evas_Object_Image *o;
1849 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1852 o = (Evas_Object_Image *)(obj->object_data);
1853 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1856 if (!obj->layer->evas->engine.func->image_native_get) return NULL;
1857 return obj->layer->evas->engine.func->image_native_get(obj->layer->evas->engine.data.output,
1862 evas_object_image_scale_hint_set(Evas_Object *obj, Evas_Image_Scale_Hint hint)
1864 Evas_Object_Image *o;
1866 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1869 o = (Evas_Object_Image *)(obj->object_data);
1870 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1873 if (o->scale_hint == hint) return;
1874 o->scale_hint = hint;
1879 if (obj->layer->evas->engine.func->image_scale_hint_set)
1880 obj->layer->evas->engine.func->image_scale_hint_set
1881 (obj->layer->evas->engine.data.output,
1882 o->engine_data, o->scale_hint);
1883 if (obj->layer->evas->engine.func->image_stride_get)
1884 obj->layer->evas->engine.func->image_stride_get
1885 (obj->layer->evas->engine.data.output,
1886 o->engine_data, &stride);
1888 stride = o->cur.image.w * 4;
1889 o->cur.image.stride = stride;
1893 EAPI Evas_Image_Scale_Hint
1894 evas_object_image_scale_hint_get(const Evas_Object *obj)
1896 Evas_Object_Image *o;
1898 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1899 return EVAS_IMAGE_SCALE_HINT_NONE;
1901 o = (Evas_Object_Image *)(obj->object_data);
1902 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1903 return EVAS_IMAGE_SCALE_HINT_NONE;
1905 return o->scale_hint;
1909 evas_object_image_content_hint_set(Evas_Object *obj, Evas_Image_Content_Hint hint)
1911 Evas_Object_Image *o;
1913 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1916 o = (Evas_Object_Image *)(obj->object_data);
1917 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1920 if (o->content_hint == hint) return;
1921 o->content_hint = hint;
1926 if (obj->layer->evas->engine.func->image_content_hint_set)
1927 obj->layer->evas->engine.func->image_content_hint_set
1928 (obj->layer->evas->engine.data.output,
1929 o->engine_data, o->content_hint);
1930 if (obj->layer->evas->engine.func->image_stride_get)
1931 obj->layer->evas->engine.func->image_stride_get
1932 (obj->layer->evas->engine.data.output,
1933 o->engine_data, &stride);
1935 stride = o->cur.image.w * 4;
1936 o->cur.image.stride = stride;
1941 evas_object_image_alpha_mask_set(Evas_Object *obj, Eina_Bool ismask)
1943 Evas_Object_Image *o;
1945 if (!ismask) return;
1947 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1950 o = (Evas_Object_Image *)(obj->object_data);
1951 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1955 /* Convert to A8 if not already */
1961 #define FRAME_MAX 1024
1962 EAPI Evas_Image_Content_Hint
1963 evas_object_image_content_hint_get(const Evas_Object *obj)
1965 Evas_Object_Image *o;
1967 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1968 return EVAS_IMAGE_CONTENT_HINT_NONE;
1970 o = (Evas_Object_Image *)(obj->object_data);
1971 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1972 return EVAS_IMAGE_CONTENT_HINT_NONE;
1974 return o->content_hint;
1978 evas_object_image_region_support_get(const Evas_Object *obj)
1980 Evas_Object_Image *o;
1982 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1985 o = (Evas_Object_Image *) (obj->object_data);
1986 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1990 return obj->layer->evas->engine.func->image_can_region_get(
1991 obj->layer->evas->engine.data.output,
1995 /* animated feature */
1997 evas_object_image_animated_get(const Evas_Object *obj)
1999 Evas_Object_Image *o;
2001 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2004 o = (Evas_Object_Image *)(obj->object_data);
2005 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2009 if (obj->layer->evas->engine.func->image_animated_get)
2010 return obj->layer->evas->engine.func->image_animated_get(obj->layer->evas->engine.data.output, o->engine_data);
2015 evas_object_image_animated_frame_count_get(const Evas_Object *obj)
2017 Evas_Object_Image *o;
2019 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2022 o = (Evas_Object_Image *)(obj->object_data);
2023 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2027 if (!evas_object_image_animated_get(obj)) return -1;
2028 if (obj->layer->evas->engine.func->image_animated_frame_count_get)
2029 return obj->layer->evas->engine.func->image_animated_frame_count_get(obj->layer->evas->engine.data.output, o->engine_data);
2033 EAPI Evas_Image_Animated_Loop_Hint
2034 evas_object_image_animated_loop_type_get(const Evas_Object *obj)
2036 Evas_Object_Image *o;
2038 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2039 return EVAS_IMAGE_ANIMATED_HINT_NONE;
2041 o = (Evas_Object_Image *)(obj->object_data);
2042 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2043 return EVAS_IMAGE_ANIMATED_HINT_NONE;
2046 if (!evas_object_image_animated_get(obj)) return EVAS_IMAGE_ANIMATED_HINT_NONE;
2048 if (obj->layer->evas->engine.func->image_animated_loop_type_get)
2049 return obj->layer->evas->engine.func->image_animated_loop_type_get(obj->layer->evas->engine.data.output, o->engine_data);
2050 return EVAS_IMAGE_ANIMATED_HINT_NONE;
2054 evas_object_image_animated_loop_count_get(const Evas_Object *obj)
2056 Evas_Object_Image *o;
2058 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2061 o = (Evas_Object_Image *)(obj->object_data);
2062 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2066 if (!evas_object_image_animated_get(obj)) return -1;
2068 if (obj->layer->evas->engine.func->image_animated_loop_count_get)
2069 return obj->layer->evas->engine.func->image_animated_loop_count_get(obj->layer->evas->engine.data.output, o->engine_data);
2074 evas_object_image_animated_frame_duration_get(const Evas_Object *obj, int start_frame, int frame_num)
2076 Evas_Object_Image *o;
2077 int frame_count = 0;
2079 if (start_frame < 1) return -1;
2080 if (frame_num < 0) return -1;
2082 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2085 o = (Evas_Object_Image *)(obj->object_data);
2086 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2090 if (!evas_object_image_animated_get(obj)) return -1;
2092 if (!obj->layer->evas->engine.func->image_animated_frame_count_get) return -1;
2094 frame_count = obj->layer->evas->engine.func->image_animated_frame_count_get(obj->layer->evas->engine.data.output, o->engine_data);
2096 if ((start_frame + frame_num) > frame_count) return -1;
2097 if (obj->layer->evas->engine.func->image_animated_frame_duration_get)
2098 return obj->layer->evas->engine.func->image_animated_frame_duration_get(obj->layer->evas->engine.data.output, o->engine_data, start_frame, frame_num);
2103 evas_object_image_animated_frame_set(Evas_Object *obj, int frame_index)
2105 Evas_Object_Image *o;
2106 int frame_count = 0;
2108 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2111 o = (Evas_Object_Image *)(obj->object_data);
2112 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2116 if (!o->cur.file) return;
2117 if (o->cur.frame == frame_index) return;
2119 if (!evas_object_image_animated_get(obj)) return;
2121 frame_count = evas_object_image_animated_frame_count_get(obj);
2123 /* limit the size of frame to FRAME_MAX */
2124 if ((frame_count > FRAME_MAX) || (frame_count < 0) || (frame_index > frame_count))
2127 if (!obj->layer->evas->engine.func->image_animated_frame_set) return;
2128 if (!obj->layer->evas->engine.func->image_animated_frame_set(obj->layer->evas->engine.data.output, o->engine_data, frame_index))
2131 o->prev.frame = o->cur.frame;
2132 o->cur.frame = frame_index;
2135 evas_object_change(obj);
2140 evas_image_cache_flush(Evas *e)
2142 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2146 e->engine.func->image_cache_flush(e->engine.data.output);
2150 evas_image_cache_reload(Evas *e)
2154 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2158 evas_image_cache_flush(e);
2159 EINA_INLIST_FOREACH(e->layers, layer)
2163 EINA_INLIST_FOREACH(layer->objects, obj)
2165 Evas_Object_Image *o;
2167 o = (Evas_Object_Image *)(obj->object_data);
2168 if (o->magic == MAGIC_OBJ_IMAGE)
2170 evas_object_image_unload(obj, 1);
2171 evas_object_inform_call_image_unloaded(obj);
2175 evas_image_cache_flush(e);
2176 EINA_INLIST_FOREACH(e->layers, layer)
2180 EINA_INLIST_FOREACH(layer->objects, obj)
2182 Evas_Object_Image *o;
2184 o = (Evas_Object_Image *)(obj->object_data);
2185 if (o->magic == MAGIC_OBJ_IMAGE)
2187 evas_object_image_load(obj);
2189 evas_object_change(obj);
2193 evas_image_cache_flush(e);
2197 evas_image_cache_set(Evas *e, int size)
2199 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2203 if (size < 0) size = 0;
2204 e->engine.func->image_cache_set(e->engine.data.output, size);
2208 evas_image_cache_get(const Evas *e)
2210 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2214 return e->engine.func->image_cache_get(e->engine.data.output);
2218 evas_image_max_size_get(const Evas *e, int *maxw, int *maxh)
2221 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2225 if (maxw) *maxw = 0xffff;
2226 if (maxh) *maxh = 0xffff;
2227 if (!e->engine.func->image_max_size_get) return EINA_FALSE;
2228 e->engine.func->image_max_size_get(e->engine.data.output, &w, &h);
2229 if (maxw) *maxw = w;
2230 if (maxh) *maxh = h;
2234 /* all nice and private */
2236 _proxy_unset(Evas_Object *proxy)
2238 Evas_Object_Image *o;
2240 o = proxy->object_data;
2241 if (!o->cur.source) return;
2243 o->cur.source->proxy.proxies = eina_list_remove(o->cur.source->proxy.proxies, proxy);
2245 o->cur.source = NULL;
2248 evas_map_free(o->cur.defmap);
2249 o->cur.defmap = NULL;
2255 _proxy_set(Evas_Object *proxy, Evas_Object *src)
2257 Evas_Object_Image *o;
2259 o = proxy->object_data;
2261 evas_object_image_file_set(proxy, NULL, NULL);
2263 o->cur.source = src;
2264 o->load_error = EVAS_LOAD_ERROR_NONE;
2266 src->proxy.proxies = eina_list_append(src->proxy.proxies, proxy);
2267 src->proxy.redraw = EINA_TRUE;
2270 /* Some moron just set a proxy on a proxy.
2271 * Give them some pixels. A random color
2274 _proxy_error(Evas_Object *proxy, void *context, void *output, void *surface,
2278 int r = rand() % 255;
2279 int g = rand() % 255;
2280 int b = rand() % 255;
2282 /* XXX: Eina log error or something I'm sure
2283 * If it bugs you, just fix it. Don't tell me */
2284 if (VERBOSE_PROXY_ERROR) printf("Err: Argh! Recursive proxies.\n");
2286 func = proxy->layer->evas->engine.func;
2287 func->context_color_set(output, context, r, g, b, 255);
2288 func->context_multiplier_unset(output, context);
2289 func->context_render_op_set(output, context, proxy->cur.render_op);
2290 func->rectangle_draw(output, context, surface, proxy->cur.geometry.x + x,
2291 proxy->cur.geometry.y + y,
2292 proxy->cur.geometry.w,
2293 proxy->cur.geometry.h);
2299 _proxy_subrender_recurse(Evas_Object *obj, Evas_Object *clip, void *output, void *surface, void *ctx, int x, int y)
2302 Evas *e = obj->layer->evas;
2304 if (obj->clip.clipees) return;
2305 if (!obj->cur.visible) return;
2306 if ((!clip) || (clip != obj->cur.clipper))
2308 if (!obj->cur.cache.clip.visible) return;
2309 if ((obj->cur.cache.clip.a == 0) &&
2310 (obj->cur.render_op == EVAS_RENDER_BLEND)) return;
2312 if ((obj->func->is_visible) && (!obj->func->is_visible(obj))) return;
2314 if (!obj->pre_render_done)
2315 obj->func->render_pre(obj);
2316 ctx = e->engine.func->context_new(output);
2317 if (obj->smart.smart)
2319 EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
2321 _proxy_subrender_recurse(obj2, clip, output, surface, ctx, x, y);
2326 obj->func->render(obj, output, ctx, surface, x, y);
2328 e->engine.func->context_free(output, ctx);
2333 * Render the source object when a proxy is set.
2335 * Used to force a draw if necessary, else just makes sures it's available.
2338 _proxy_subrender(Evas *e, Evas_Object *source)
2341 /* Evas_Object *obj2, *clip;*/
2344 if (!source) return;
2346 w = source->cur.geometry.w;
2347 h = source->cur.geometry.h;
2349 source->proxy.redraw = EINA_FALSE;
2351 /* We need to redraw surface then */
2352 if ((source->proxy.surface) &&
2353 ((source->proxy.w != w) || (source->proxy.h != h)))
2355 e->engine.func->image_map_surface_free(e->engine.data.output,
2356 source->proxy.surface);
2357 source->proxy.surface = NULL;
2360 /* FIXME: Hardcoded alpha 'on' */
2361 /* FIXME (cont): Should see if the object has alpha */
2362 if (!source->proxy.surface)
2364 source->proxy.surface = e->engine.func->image_map_surface_new
2365 (e->engine.data.output, w, h, 1);
2366 source->proxy.w = w;
2367 source->proxy.h = h;
2370 ctx = e->engine.func->context_new(e->engine.data.output);
2371 e->engine.func->context_color_set(e->engine.data.output, ctx, 0, 0, 0, 0);
2372 e->engine.func->context_render_op_set(e->engine.data.output, ctx, EVAS_RENDER_COPY);
2373 e->engine.func->rectangle_draw(e->engine.data.output, ctx,
2374 source->proxy.surface, 0, 0, w, h);
2375 e->engine.func->context_free(e->engine.data.output, ctx);
2377 ctx = e->engine.func->context_new(e->engine.data.output);
2378 evas_render_mapped(e, source, ctx, source->proxy.surface,
2379 -source->cur.geometry.x,
2380 -source->cur.geometry.y,
2381 1, 0, 0, e->output.w, e->output.h);
2382 e->engine.func->context_free(e->engine.data.output, ctx);
2383 source->proxy.surface = e->engine.func->image_dirty_region
2384 (e->engine.data.output, source->proxy.surface, 0, 0, w, h);
2386 ctx = e->engine.func->context_new(e->engine.data.output);
2387 if (source->smart.smart)
2389 clip = evas_object_smart_clipped_clipper_get(source);
2390 EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(source), obj2)
2392 _proxy_subrender_recurse(obj2, clip, e->engine.data.output,
2393 source->proxy.surface,
2395 -source->cur.geometry.x,
2396 -source->cur.geometry.y);
2401 if (!source->pre_render_done)
2402 source->func->render_pre(source);
2403 source->func->render(source, e->engine.data.output, ctx,
2404 source->proxy.surface,
2405 -source->cur.geometry.x,
2406 -source->cur.geometry.y);
2409 e->engine.func->context_free(e->engine.data.output, ctx);
2410 source->proxy.surface = e->engine.func->image_dirty_region
2411 (e->engine.data.output, source->proxy.surface, 0, 0, w, h);
2415 #if 0 // filtering disabled
2418 * Note that this is similar to proxy_subrender_recurse. It should be
2419 * possible to merge I guess
2422 image_filter_draw_under_recurse(Evas *e, Evas_Object *obj, Evas_Object *stop,
2423 void *output, void *ctx, void *surface,
2428 if (obj->clip.clipees) return;
2429 /* FIXME: Doing bounding box test */
2430 if (!evas_object_is_in_output_rect(obj, stop->cur.geometry.x,
2431 stop->cur.geometry.y,
2432 stop->cur.geometry.w,
2433 stop->cur.geometry.h))
2436 if (!evas_object_is_visible(obj)) return;
2437 obj->pre_render_done = 1;
2438 ctx = e->engine.func->context_new(output);
2440 if (obj->smart.smart)
2442 EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
2444 if (obj2 == stop) return;
2445 image_filter_draw_under_recurse(e, obj2, stop, output, surface,
2450 obj->func->render(obj, output, ctx, surface, x ,y);
2451 e->engine.func->context_free(output, ctx);
2455 * Draw all visible objects intersecting an object which are _beneath_ it.
2458 image_filter_draw_under(Evas *e, Evas_Object *stop, void *output, void *ctx, void *surface, int dx, int dy)
2463 x = stop->cur.geometry.x - dx;
2464 y = stop->cur.geometry.y - dy;
2466 EINA_INLIST_FOREACH(e->layers, lay)
2469 EINA_INLIST_FOREACH(lay->objects, obj)
2471 if (obj->delete_me) continue;
2472 if (obj == stop) return;
2473 /* FIXME: Do bounding box check */
2474 image_filter_draw_under_recurse(e, obj, stop, output, ctx,
2478 e->engine.func->image_dirty_region(output, surface, 0, 0, 300, 300);
2479 e->engine.func->output_flush(output);
2483 * Update the filtered object.
2485 * Creates a new context, and renders stuff (filtered) onto that.
2488 image_filter_update(Evas *e, Evas_Object *obj, void *src, int imagew, int imageh, int *outw, int *outh)
2492 Evas_Filter_Info *info;
2498 if (info->mode == EVAS_FILTER_MODE_BELOW)
2500 w = obj->cur.geometry.w;
2501 h = obj->cur.geometry.h;
2502 evas_filter_get_size(info, w, h, &imagew, &imageh, EINA_TRUE);
2507 evas_filter_get_size(info, imagew, imageh, &w, &h, EINA_FALSE);
2508 alpha = e->engine.func->image_alpha_get(e->engine.data.output, src);
2511 /* Certain filters may make alpha images anyway */
2512 if (alpha == EINA_FALSE) alpha = evas_filter_always_alpha(info);
2514 surface = e->engine.func->image_map_surface_new(e->engine.data.output, w, h,
2517 if (info->mode == EVAS_FILTER_MODE_BELOW)
2522 disw = obj->cur.geometry.w;
2523 dish = obj->cur.geometry.h;
2524 dx = (imagew - w) >> 1;
2525 dy = (imageh - h) >> 1;
2526 subsurface = e->engine.func->image_map_surface_new
2527 (e->engine.data.output, imagew, imageh, 1);
2528 ctx = e->engine.func->context_new(e->engine.data.output);
2529 e->engine.func->context_color_set(e->engine.data.output, ctx, 0, 255, 0, 255);
2530 e->engine.func->context_render_op_set(e->engine.data.output, ctx, EVAS_RENDER_COPY);
2531 e->engine.func->rectangle_draw(e->engine.data.output, ctx,
2532 subsurface, 0, 0, imagew, imageh);
2534 image_filter_draw_under(e, obj, e->engine.data.output, ctx,
2535 subsurface, dx, dy);
2537 e->engine.func->context_free(e->engine.data.output, ctx);
2539 ctx = e->engine.func->context_new(e->engine.data.output);
2541 e->engine.func->image_draw_filtered(e->engine.data.output,
2542 ctx, surface, subsurface, info);
2544 e->engine.func->context_free(e->engine.data.output, ctx);
2546 e->engine.func->image_map_surface_free(e->engine.data.output,
2551 ctx = e->engine.func->context_new(e->engine.data.output);
2552 e->engine.func->image_draw_filtered(e->engine.data.output,
2553 ctx, surface, src, info);
2554 e->engine.func->context_free(e->engine.data.output, ctx);
2557 e->engine.func->image_dirty_region(e->engine.data.output, surface,
2559 if (outw) *outw = w;
2560 if (outh) *outh = h;
2561 return e->engine.func->image_filtered_save(src, surface,
2568 evas_object_image_unload(Evas_Object *obj, Eina_Bool dirty)
2570 Evas_Object_Image *o;
2572 o = (Evas_Object_Image *)(obj->object_data);
2574 if ((!o->cur.file) ||
2575 (o->pixels_checked_out > 0)) return;
2579 o->engine_data = obj->layer->evas->engine.func->image_dirty_region
2580 (obj->layer->evas->engine.data.output,
2583 o->cur.image.w, o->cur.image.h);
2590 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
2594 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
2597 o->engine_data = NULL;
2598 o->load_error = EVAS_LOAD_ERROR_NONE;
2599 o->cur.has_alpha = 1;
2600 o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
2603 o->cur.image.stride = 0;
2607 evas_object_image_load(Evas_Object *obj)
2609 Evas_Object_Image *o;
2610 Evas_Image_Load_Opts lo;
2612 o = (Evas_Object_Image *)(obj->object_data);
2613 if (o->engine_data) return;
2615 lo.scale_down_by = o->load_opts.scale_down_by;
2616 lo.dpi = o->load_opts.dpi;
2617 lo.w = o->load_opts.w;
2618 lo.h = o->load_opts.h;
2619 lo.region.x = o->load_opts.region.x;
2620 lo.region.y = o->load_opts.region.y;
2621 lo.region.w = o->load_opts.region.w;
2622 lo.region.h = o->load_opts.region.h;
2623 lo.orientation = o->load_opts.orientation;
2624 o->engine_data = obj->layer->evas->engine.func->image_load
2625 (obj->layer->evas->engine.data.output,
2635 obj->layer->evas->engine.func->image_size_get
2636 (obj->layer->evas->engine.data.output,
2637 o->engine_data, &w, &h);
2638 if (obj->layer->evas->engine.func->image_stride_get)
2639 obj->layer->evas->engine.func->image_stride_get
2640 (obj->layer->evas->engine.data.output,
2641 o->engine_data, &stride);
2644 o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get
2645 (obj->layer->evas->engine.data.output,
2647 o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get
2648 (obj->layer->evas->engine.data.output,
2652 o->cur.image.stride = stride;
2656 o->load_error = EVAS_LOAD_ERROR_GENERIC;
2661 evas_object_image_figure_x_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret)
2665 w = ((size * obj->layer->evas->output.w) /
2666 (Evas_Coord)obj->layer->evas->viewport.w);
2667 if (size <= 0) size = 1;
2670 while (start - size > 0) start -= size;
2674 while (start < 0) start += size;
2676 start = ((start * obj->layer->evas->output.w) /
2677 (Evas_Coord)obj->layer->evas->viewport.w);
2683 evas_object_image_figure_y_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret)
2687 h = ((size * obj->layer->evas->output.h) /
2688 (Evas_Coord)obj->layer->evas->viewport.h);
2689 if (size <= 0) size = 1;
2692 while (start - size > 0) start -= size;
2696 while (start < 0) start += size;
2698 start = ((start * obj->layer->evas->output.h) /
2699 (Evas_Coord)obj->layer->evas->viewport.h);
2705 evas_object_image_init(Evas_Object *obj)
2707 /* alloc image ob, setup methods and default values */
2708 obj->object_data = evas_object_image_new();
2709 /* set up default settings for this kind of object */
2710 obj->cur.color.r = 255;
2711 obj->cur.color.g = 255;
2712 obj->cur.color.b = 255;
2713 obj->cur.color.a = 255;
2714 obj->cur.geometry.x = 0;
2715 obj->cur.geometry.y = 0;
2716 obj->cur.geometry.w = 0;
2717 obj->cur.geometry.h = 0;
2719 obj->cur.anti_alias = 0;
2720 obj->cur.render_op = EVAS_RENDER_BLEND;
2721 /* set up object-specific settings */
2722 obj->prev = obj->cur;
2723 /* set up methods (compulsory) */
2724 obj->func = &object_func;
2729 evas_object_image_new(void)
2731 Evas_Object_Image *o;
2733 /* alloc obj private data */
2734 EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_image", Evas_Object_Image, 16, NULL);
2735 o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Image);
2736 if (!o) return NULL;
2737 EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Image);
2738 o->magic = MAGIC_OBJ_IMAGE;
2741 o->cur.smooth_scale = 1;
2742 o->cur.border.fill = 1;
2743 o->cur.border.scale = 1.0;
2744 o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
2745 o->cur.spread = EVAS_TEXTURE_REPEAT;
2746 o->cur.opaque_valid = 0;
2747 o->cur.source = NULL;
2754 evas_object_image_free(Evas_Object *obj)
2756 Evas_Object_Image *o;
2759 /* frees private object data. very simple here */
2760 o = (Evas_Object_Image *)(obj->object_data);
2761 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2766 if (o->cur.file) eina_stringshare_del(o->cur.file);
2767 if (o->cur.key) eina_stringshare_del(o->cur.key);
2768 if (o->cur.source) _proxy_unset(obj);
2774 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
2778 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
2781 if (o->video_surface)
2783 o->video_surface = 0;
2784 obj->layer->evas->video_objects = eina_list_remove(obj->layer->evas->video_objects, obj);
2786 o->engine_data = NULL;
2788 EINA_LIST_FREE(o->pixel_updates, r)
2789 eina_rectangle_free(r);
2790 EVAS_MEMPOOL_FREE(_mp_obj, o);
2794 evas_object_image_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
2796 Evas_Object_Image *o;
2797 int imagew, imageh, uvw, uvh;
2800 /* render object to surface with context, and offset by x,y */
2801 o = (Evas_Object_Image *)(obj->object_data);
2803 if ((o->cur.fill.w < 1) || (o->cur.fill.h < 1))
2804 return; /* no error message, already printed in pre_render */
2807 if (o->proxyrendering)
2809 _proxy_error(obj, context, output, surface, x, y);
2813 /* We are displaying the overlay */
2814 if (o->video_visible)
2816 /* Create a transparent rectangle */
2817 obj->layer->evas->engine.func->context_color_set(output,
2820 obj->layer->evas->engine.func->context_multiplier_unset(output,
2822 obj->layer->evas->engine.func->context_render_op_set(output, context,
2824 obj->layer->evas->engine.func->rectangle_draw(output,
2827 obj->cur.geometry.x + x,
2828 obj->cur.geometry.y + y,
2829 obj->cur.geometry.w,
2830 obj->cur.geometry.h);
2835 obj->layer->evas->engine.func->context_color_set(output,
2837 255, 255, 255, 255);
2839 if ((obj->cur.cache.clip.r == 255) &&
2840 (obj->cur.cache.clip.g == 255) &&
2841 (obj->cur.cache.clip.b == 255) &&
2842 (obj->cur.cache.clip.a == 255))
2844 obj->layer->evas->engine.func->context_multiplier_unset(output,
2848 obj->layer->evas->engine.func->context_multiplier_set(output,
2850 obj->cur.cache.clip.r,
2851 obj->cur.cache.clip.g,
2852 obj->cur.cache.clip.b,
2853 obj->cur.cache.clip.a);
2855 obj->layer->evas->engine.func->context_render_op_set(output, context,
2856 obj->cur.render_op);
2860 pixels = o->engine_data;
2861 imagew = o->cur.image.w;
2862 imageh = o->cur.image.h;
2866 else if (o->cur.source->proxy.surface && !o->cur.source->proxy.redraw)
2868 pixels = o->cur.source->proxy.surface;
2869 imagew = o->cur.source->proxy.w;
2870 imageh = o->cur.source->proxy.h;
2874 else if (o->cur.source->type == o_type &&
2875 ((Evas_Object_Image *)o->cur.source->object_data)->engine_data)
2877 Evas_Object_Image *oi;
2878 oi = o->cur.source->object_data;
2879 pixels = oi->engine_data;
2880 imagew = oi->cur.image.w;
2881 imageh = oi->cur.image.h;
2882 uvw = o->cur.source->cur.geometry.w;
2883 uvh = o->cur.source->cur.geometry.h;
2887 o->proxyrendering = 1;
2888 _proxy_subrender(obj->layer->evas, o->cur.source);
2889 pixels = o->cur.source->proxy.surface;
2890 imagew = o->cur.source->proxy.w;
2891 imageh = o->cur.source->proxy.h;
2894 o->proxyrendering = 0;
2897 #if 0 // filtering disabled
2898 /* Now check/update filter */
2899 if (obj->filter && obj->filter->filter)
2901 Filtered_Image *fi = NULL;
2902 //printf("%p has filter: %s\n", obj,obj->filter->dirty?"dirty":"clean");
2903 if (obj->filter->dirty)
2905 if (obj->filter->mode != EVAS_FILTER_MODE_BELOW)
2910 if (obj->filter->key) free(obj->filter->key);
2911 obj->filter->key = NULL;
2912 obj->filter->len = 0;
2913 key = evas_filter_key_get(obj->filter, &len);
2916 obj->filter->key = key;
2917 obj->filter->len = len;
2918 fi = obj->layer->evas->engine.func->image_filtered_get
2919 (o->engine_data, key, len);
2920 if (obj->filter->cached && fi != obj->filter->cached)
2922 obj->layer->evas->engine.func->image_filtered_free
2923 (o->engine_data, obj->filter->cached);
2924 obj->filter->cached = NULL;
2928 else if (obj->filter->cached)
2930 obj->layer->evas->engine.func->image_filtered_free
2931 (o->engine_data, obj->filter->cached);
2934 fi = image_filter_update(obj->layer->evas, obj, pixels,
2935 imagew, imageh, &imagew, &imageh);
2937 obj->filter->dirty = 0;
2938 obj->filter->cached = fi;
2942 fi = obj->filter->cached;
2950 Evas_Coord idw, idh, idx, idy;
2954 if (o->dirty_pixels)
2956 if (o->func.get_pixels)
2958 // Set img object for direct rendering optimization
2959 // Check for image w/h against image geometry w/h
2960 // Check for image color r,g,b,a = {255,255,255,255}
2961 // Check and make sure that there are no maps.
2962 if ( (obj->cur.geometry.w == o->cur.image.w) &&
2963 (obj->cur.geometry.h == o->cur.image.h) &&
2964 (obj->cur.color.r == 255) &&
2965 (obj->cur.color.g == 255) &&
2966 (obj->cur.color.b == 255) &&
2967 (obj->cur.color.a == 255) &&
2970 if (obj->layer->evas->engine.func->gl_img_obj_set)
2972 obj->layer->evas->engine.func->gl_img_obj_set(output, obj, o->cur.has_alpha);
2977 o->func.get_pixels(o->func.get_pixels_data, obj);
2978 if (o->engine_data != pixels)
2979 pixels = o->engine_data;
2980 o->engine_data = obj->layer->evas->engine.func->image_dirty_region
2981 (obj->layer->evas->engine.data.output, o->engine_data,
2982 0, 0, o->cur.image.w, o->cur.image.h);
2984 o->dirty_pixels = 0;
2986 if ((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap))
2988 evas_object_map_update(obj, x, y, imagew, imageh, uvw, uvh);
2990 obj->layer->evas->engine.func->image_map_draw
2991 (output, context, surface, pixels, obj->spans,
2992 o->cur.smooth_scale | obj->cur.map->smooth, 0);
2996 obj->layer->evas->engine.func->image_scale_hint_set(output,
2999 /* This is technically a bug here: If the value is recreated
3000 * (which is returned)it may be a new object, however exactly 0
3001 * of all the evas engines do this. */
3002 obj->layer->evas->engine.func->image_border_set(output, pixels,
3003 o->cur.border.l, o->cur.border.r,
3004 o->cur.border.t, o->cur.border.b);
3005 idx = evas_object_image_figure_x_fill(obj, o->cur.fill.x, o->cur.fill.w, &idw);
3006 idy = evas_object_image_figure_y_fill(obj, o->cur.fill.y, o->cur.fill.h, &idh);
3007 if (idw < 1) idw = 1;
3008 if (idh < 1) idh = 1;
3009 if (idx > 0) idx -= idw;
3010 if (idy > 0) idy -= idh;
3011 while ((int)idx < obj->cur.geometry.w)
3018 if ((o->cur.fill.w == obj->cur.geometry.w) &&
3019 (o->cur.fill.x == 0))
3022 iw = obj->cur.geometry.w;
3025 iw = ((int)(idx + idw)) - ix;
3026 while ((int)idy < obj->cur.geometry.h)
3031 if ((o->cur.fill.h == obj->cur.geometry.h) &&
3032 (o->cur.fill.y == 0))
3034 ih = obj->cur.geometry.h;
3038 ih = ((int)(idy + idh)) - iy;
3039 if ((o->cur.border.l == 0) &&
3040 (o->cur.border.r == 0) &&
3041 (o->cur.border.t == 0) &&
3042 (o->cur.border.b == 0) &&
3043 (o->cur.border.fill != 0))
3044 obj->layer->evas->engine.func->image_draw(output,
3051 obj->cur.geometry.x + ix + x,
3052 obj->cur.geometry.y + iy + y,
3054 o->cur.smooth_scale);
3057 int inx, iny, inw, inh, outx, outy, outw, outh;
3058 int bl, br, bt, bb, bsl, bsr, bst, bsb;
3059 int imw, imh, ox, oy;
3061 ox = obj->cur.geometry.x + ix + x;
3062 oy = obj->cur.geometry.y + iy + y;
3065 bl = o->cur.border.l;
3066 br = o->cur.border.r;
3067 bt = o->cur.border.t;
3068 bb = o->cur.border.b;
3074 if ((bl + br) > imw)
3084 if ((bt + bb) > imh)
3089 if (o->cur.border.scale != 1.0)
3091 bsl = ((double)bl * o->cur.border.scale);
3092 bsr = ((double)br * o->cur.border.scale);
3093 bst = ((double)bt * o->cur.border.scale);
3094 bsb = ((double)bb * o->cur.border.scale);
3098 bsl = bl; bsr = br; bst = bt; bsb = bb;
3104 outx = ox; outy = oy;
3105 outw = bsl; outh = bst;
3106 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3110 inw = imw - bl - br; inh = bt;
3111 outx = ox + bsl; outy = oy;
3112 outw = iw - bsl - bsr; outh = bst;
3113 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3116 inx = imw - br; iny = 0;
3118 outx = ox + iw - bsr; outy = oy;
3119 outw = bsr; outh = bst;
3120 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3124 inw = bl; inh = imh - bt - bb;
3125 outx = ox; outy = oy + bst;
3126 outw = bsl; outh = ih - bst - bsb;
3127 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3130 if (o->cur.border.fill > EVAS_BORDER_FILL_NONE)
3133 inw = imw - bl - br; inh = imh - bt - bb;
3134 outx = ox + bsl; outy = oy + bst;
3135 outw = iw - bsl - bsr; outh = ih - bst - bsb;
3136 if ((o->cur.border.fill == EVAS_BORDER_FILL_SOLID) &&
3137 (obj->cur.cache.clip.a == 255) &&
3138 (obj->cur.render_op == EVAS_RENDER_BLEND))
3140 obj->layer->evas->engine.func->context_render_op_set(output, context,
3142 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3143 obj->layer->evas->engine.func->context_render_op_set(output, context,
3144 obj->cur.render_op);
3147 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3151 inx = imw - br; iny = bt;
3152 inw = br; inh = imh - bt - bb;
3153 outx = ox + iw - bsr; outy = oy + bst;
3154 outw = bsr; outh = ih - bst - bsb;
3155 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3158 inx = 0; iny = imh - bb;
3160 outx = ox; outy = oy + ih - bsb;
3161 outw = bsl; outh = bsb;
3162 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3165 inx = bl; iny = imh - bb;
3166 inw = imw - bl - br; inh = bb;
3167 outx = ox + bsl; outy = oy + ih - bsb;
3168 outw = iw - bsl - bsr; outh = bsb;
3169 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3172 inx = imw - br; iny = imh - bb;
3174 outx = ox + iw - bsr; outy = oy + ih - bsb;
3175 outw = bsr; outh = bsb;
3176 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3179 if (dobreak_h) break;
3183 if (dobreak_w) break;
3190 if (obj->layer->evas->engine.func->gl_img_obj_set)
3192 obj->layer->evas->engine.func->gl_img_obj_set(output, NULL, 0);
3200 evas_object_image_render_pre(Evas_Object *obj)
3202 Evas_Object_Image *o;
3203 int is_v = 0, was_v = 0;
3206 /* dont pre-render the obj twice! */
3207 if (obj->pre_render_done) return;
3208 obj->pre_render_done = 1;
3209 /* pre-render phase. this does anything an object needs to do just before */
3210 /* rendering. this could mean loading the image data, retrieving it from */
3211 /* elsewhere, decoding video etc. */
3212 /* then when this is done the object needs to figure if it changed and */
3213 /* if so what and where and add the appropriate redraw rectangles */
3214 o = (Evas_Object_Image *)(obj->object_data);
3215 e = obj->layer->evas;
3217 if ((o->cur.fill.w < 1) || (o->cur.fill.h < 1))
3219 ERR("%p has invalid fill size: %dx%d. Ignored",
3220 obj, o->cur.fill.w, o->cur.fill.h);
3224 /* if someone is clipping this obj - go calculate the clipper */
3225 if (obj->cur.clipper)
3227 if (obj->cur.cache.clip.dirty)
3228 evas_object_clip_recalc(obj->cur.clipper);
3229 obj->cur.clipper->func->render_pre(obj->cur.clipper);
3231 /* Proxy: Do it early */
3232 if (o->cur.source &&
3233 (o->cur.source->proxy.redraw || o->cur.source->changed))
3235 /* XXX: Do I need to sort out the map here? */
3236 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3240 /* now figure what changed and add draw rects */
3241 /* if it just became visible or invisible */
3242 is_v = evas_object_is_visible(obj);
3243 was_v = evas_object_was_visible(obj);
3246 evas_object_render_pre_visible_change(&e->clip_changes, obj, is_v, was_v);
3247 if (!o->pixel_updates) goto done;
3249 if (obj->changed_map)
3251 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3254 /* it's not visible - we accounted for it appearing or not so just abort */
3255 if (!is_v) goto done;
3256 /* clipper changed this is in addition to anything else for obj */
3257 evas_object_render_pre_clipper_change(&e->clip_changes, obj);
3258 /* if we restacked (layer or just within a layer) and don't clip anyone */
3261 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3262 if (!o->pixel_updates) goto done;
3264 /* if it changed color */
3265 if ((obj->cur.color.r != obj->prev.color.r) ||
3266 (obj->cur.color.g != obj->prev.color.g) ||
3267 (obj->cur.color.b != obj->prev.color.b) ||
3268 (obj->cur.color.a != obj->prev.color.a))
3270 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3271 if (!o->pixel_updates) goto done;
3273 /* if it changed render op */
3274 if (obj->cur.render_op != obj->prev.render_op)
3276 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3277 if (!o->pixel_updates) goto done;
3279 /* if it changed anti_alias */
3280 if (obj->cur.anti_alias != obj->prev.anti_alias)
3282 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3283 if (!o->pixel_updates) goto done;
3287 if (((o->cur.file) && (!o->prev.file)) ||
3288 ((!o->cur.file) && (o->prev.file)) ||
3289 ((o->cur.key) && (!o->prev.key)) ||
3290 ((!o->cur.key) && (o->prev.key))
3293 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3294 if (!o->pixel_updates) goto done;
3296 if ((o->cur.image.w != o->prev.image.w) ||
3297 (o->cur.image.h != o->prev.image.h) ||
3298 (o->cur.has_alpha != o->prev.has_alpha) ||
3299 (o->cur.cspace != o->prev.cspace) ||
3300 (o->cur.smooth_scale != o->prev.smooth_scale))
3302 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3303 if (!o->pixel_updates) goto done;
3305 if ((o->cur.border.l != o->prev.border.l) ||
3306 (o->cur.border.r != o->prev.border.r) ||
3307 (o->cur.border.t != o->prev.border.t) ||
3308 (o->cur.border.b != o->prev.border.b) ||
3309 (o->cur.border.fill != o->prev.border.fill) ||
3310 (o->cur.border.scale != o->prev.border.scale))
3312 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3313 if (!o->pixel_updates) goto done;
3315 if (o->dirty_pixels)
3317 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3318 if (!o->pixel_updates) goto done;
3320 if (o->cur.frame != o->prev.frame)
3322 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3323 if (!o->pixel_updates) goto done;
3327 /* if it changed geometry - and obviously not visibility or color */
3328 /* calculate differences since we have a constant color fill */
3329 /* we really only need to update the differences */
3330 #if 0 // XXX: maybe buggy?
3331 if (((obj->cur.geometry.x != obj->prev.geometry.x) ||
3332 (obj->cur.geometry.y != obj->prev.geometry.y) ||
3333 (obj->cur.geometry.w != obj->prev.geometry.w) ||
3334 (obj->cur.geometry.h != obj->prev.geometry.h)) &&
3335 (o->cur.fill.w == o->prev.fill.w) &&
3336 (o->cur.fill.h == o->prev.fill.h) &&
3337 ((o->cur.fill.x + obj->cur.geometry.x) == (o->prev.fill.x + obj->prev.geometry.x)) &&
3338 ((o->cur.fill.y + obj->cur.geometry.y) == (o->prev.fill.y + obj->prev.geometry.y)) &&
3342 evas_rects_return_difference_rects(&e->clip_changes,
3343 obj->cur.geometry.x,
3344 obj->cur.geometry.y,
3345 obj->cur.geometry.w,
3346 obj->cur.geometry.h,
3347 obj->prev.geometry.x,
3348 obj->prev.geometry.y,
3349 obj->prev.geometry.w,
3350 obj->prev.geometry.h);
3351 if (!o->pixel_updates) goto done;
3354 if (((obj->cur.geometry.x != obj->prev.geometry.x) ||
3355 (obj->cur.geometry.y != obj->prev.geometry.y) ||
3356 (obj->cur.geometry.w != obj->prev.geometry.w) ||
3357 (obj->cur.geometry.h != obj->prev.geometry.h))
3360 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3361 if (!o->pixel_updates) goto done;
3365 if ((o->cur.fill.x != o->prev.fill.x) ||
3366 (o->cur.fill.y != o->prev.fill.y) ||
3367 (o->cur.fill.w != o->prev.fill.w) ||
3368 (o->cur.fill.h != o->prev.fill.h))
3370 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3371 if (!o->pixel_updates) goto done;
3373 if (o->pixel_updates)
3375 if ((o->cur.border.l == 0) &&
3376 (o->cur.border.r == 0) &&
3377 (o->cur.border.t == 0) &&
3378 (o->cur.border.b == 0) &&
3379 (o->cur.image.w > 0) &&
3380 (o->cur.image.h > 0) &&
3381 (!((obj->cur.map) && (obj->cur.usemap))))
3385 EINA_LIST_FREE(o->pixel_updates, rr)
3387 Evas_Coord idw, idh, idx, idy;
3390 e->engine.func->image_dirty_region(e->engine.data.output, o->engine_data, rr->x, rr->y, rr->w, rr->h);
3392 idx = evas_object_image_figure_x_fill(obj, o->cur.fill.x, o->cur.fill.w, &idw);
3393 idy = evas_object_image_figure_y_fill(obj, o->cur.fill.y, o->cur.fill.h, &idh);
3395 if (idw < 1) idw = 1;
3396 if (idh < 1) idh = 1;
3397 if (idx > 0) idx -= idw;
3398 if (idy > 0) idy -= idh;
3399 while (idx < obj->cur.geometry.w)
3405 w = ((int)(idx + idw)) - x;
3406 while (idy < obj->cur.geometry.h)
3411 h = ((int)(idy + idh)) - y;
3413 r.x = (rr->x * w) / o->cur.image.w;
3414 r.y = (rr->y * h) / o->cur.image.h;
3415 r.w = ((rr->w * w) + (o->cur.image.w * 2) - 1) / o->cur.image.w;
3416 r.h = ((rr->h * h) + (o->cur.image.h * 2) - 1) / o->cur.image.h;
3417 r.x += obj->cur.geometry.x + x;
3418 r.y += obj->cur.geometry.y + y;
3419 RECTS_CLIP_TO_RECT(r.x, r.y, r.w, r.h,
3420 obj->cur.cache.clip.x, obj->cur.cache.clip.y,
3421 obj->cur.cache.clip.w, obj->cur.cache.clip.h);
3422 evas_add_rect(&e->clip_changes, r.x, r.y, r.w, r.h);
3428 eina_rectangle_free(rr);
3436 EINA_LIST_FREE(o->pixel_updates, r)
3437 eina_rectangle_free(r);
3438 e->engine.func->image_dirty_region(e->engine.data.output, o->engine_data, 0, 0, o->cur.image.w, o->cur.image.h);
3439 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3444 #if 0 // filtering disabled
3445 if (obj->filter && obj->filter->dirty)
3447 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3450 /* it obviously didn't change - add a NO obscure - this "unupdates" this */
3451 /* area so if there were updates for it they get wiped. don't do it if we */
3452 /* aren't fully opaque and we are visible */
3453 if (evas_object_is_visible(obj) &&
3454 evas_object_is_opaque(obj))
3456 Evas_Coord x, y, w, h;
3458 x = obj->cur.cache.clip.x;
3459 y = obj->cur.cache.clip.y;
3460 w = obj->cur.cache.clip.w;
3461 h = obj->cur.cache.clip.h;
3462 if (obj->cur.clipper)
3464 RECTS_CLIP_TO_RECT(x, y, w, h,
3465 obj->cur.clipper->cur.cache.clip.x,
3466 obj->cur.clipper->cur.cache.clip.y,
3467 obj->cur.clipper->cur.cache.clip.w,
3468 obj->cur.clipper->cur.cache.clip.h);
3470 e->engine.func->output_redraws_rect_del(e->engine.data.output,
3474 evas_object_render_pre_effect_updates(&e->clip_changes, obj, is_v, was_v);
3478 evas_object_image_render_post(Evas_Object *obj)
3480 Evas_Object_Image *o;
3483 /* this moves the current data to the previous state parts of the object */
3484 /* in whatever way is safest for the object. also if we don't need object */
3485 /* data anymore we can free it if the object deems this is a good idea */
3486 o = (Evas_Object_Image *)(obj->object_data);
3487 /* remove those pesky changes */
3488 evas_object_clip_changes_clean(obj);
3489 EINA_LIST_FREE(o->pixel_updates, r)
3490 eina_rectangle_free(r);
3491 /* move cur to prev safely for object data */
3492 evas_object_cur_prev(obj);
3495 /* FIXME: copy strings across */
3498 static unsigned int evas_object_image_id_get(Evas_Object *obj)
3500 Evas_Object_Image *o;
3502 o = (Evas_Object_Image *)(obj->object_data);
3504 return MAGIC_OBJ_IMAGE;
3507 static unsigned int evas_object_image_visual_id_get(Evas_Object *obj)
3509 Evas_Object_Image *o;
3511 o = (Evas_Object_Image *)(obj->object_data);
3513 return MAGIC_OBJ_IMAGE;
3516 static void *evas_object_image_engine_data_get(Evas_Object *obj)
3518 Evas_Object_Image *o;
3520 o = (Evas_Object_Image *)(obj->object_data);
3521 if (!o) return NULL;
3522 return o->engine_data;
3526 evas_object_image_is_opaque(Evas_Object *obj)
3528 Evas_Object_Image *o;
3530 /* this returns 1 if the internal object data implies that the object is */
3531 /* currently fully opaque over the entire rectangle it occupies */
3532 o = (Evas_Object_Image *)(obj->object_data);
3533 /* disable caching due tyo maps screwing with this
3534 o->cur.opaque_valid = 0;
3535 if (o->cur.opaque_valid)
3537 if (!o->cur.opaque) return 0;
3543 /* disable caching */
3544 /* o->cur.opaque_valid = 1; */
3545 if ((o->cur.fill.w < 1) || (o->cur.fill.h < 1))
3546 return o->cur.opaque;
3547 if (((o->cur.border.l != 0) ||
3548 (o->cur.border.r != 0) ||
3549 (o->cur.border.t != 0) ||
3550 (o->cur.border.b != 0)) &&
3551 (!o->cur.border.fill)) return o->cur.opaque;
3552 if (!o->engine_data) return o->cur.opaque;
3558 o->cur.opaque = evas_object_is_opaque(o->cur.source);
3559 return o->cur.opaque; /* FIXME: Should go poke at the object */
3561 if (o->cur.has_alpha)
3564 return o->cur.opaque;
3566 if ((obj->cur.map) && (obj->cur.usemap))
3568 Evas_Map *m = obj->cur.map;
3570 if ((m->points[0].a == 255) &&
3571 (m->points[1].a == 255) &&
3572 (m->points[2].a == 255) &&
3573 (m->points[3].a == 255))
3576 ((m->points[0].x == m->points[3].x) &&
3577 (m->points[1].x == m->points[2].x) &&
3578 (m->points[0].y == m->points[1].y) &&
3579 (m->points[2].y == m->points[3].y))
3581 ((m->points[0].x == m->points[1].x) &&
3582 (m->points[2].x == m->points[3].x) &&
3583 (m->points[0].y == m->points[3].y) &&
3584 (m->points[1].y == m->points[2].y))
3587 if ((m->points[0].x == obj->cur.geometry.x) &&
3588 (m->points[0].y == obj->cur.geometry.y) &&
3589 (m->points[2].x == (obj->cur.geometry.x + obj->cur.geometry.w)) &&
3590 (m->points[2].y == (obj->cur.geometry.y + obj->cur.geometry.h)))
3591 return o->cur.opaque;
3595 return o->cur.opaque;
3597 if (obj->cur.render_op == EVAS_RENDER_COPY) return o->cur.opaque;
3598 return o->cur.opaque;
3602 evas_object_image_was_opaque(Evas_Object *obj)
3604 Evas_Object_Image *o;
3606 /* this returns 1 if the internal object data implies that the object was */
3607 /* previously fully opaque over the entire rectangle it occupies */
3608 o = (Evas_Object_Image *)(obj->object_data);
3609 if (o->prev.opaque_valid)
3611 if (!o->prev.opaque) return 0;
3616 o->prev.opaque_valid = 1;
3617 if ((o->prev.fill.w < 1) || (o->prev.fill.h < 1))
3619 if (((o->prev.border.l != 0) ||
3620 (o->prev.border.r != 0) ||
3621 (o->prev.border.t != 0) ||
3622 (o->prev.border.b != 0)) &&
3623 (!o->prev.border.fill)) return 0;
3624 if (!o->engine_data) return 0;
3628 if (o->prev.source) return 0; /* FIXME: Should go poke at the object */
3629 if (obj->prev.usemap) return 0;
3630 if (obj->prev.render_op == EVAS_RENDER_COPY) return 1;
3631 if (o->prev.has_alpha) return 0;
3632 if (obj->prev.render_op != EVAS_RENDER_BLEND) return 0;
3637 evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
3639 Evas_Object_Image *o;
3641 int w, h, stride, iw, ih;
3645 o = (Evas_Object_Image *)(obj->object_data);
3647 x -= obj->cur.cache.clip.x;
3648 y -= obj->cur.cache.clip.y;
3649 w = obj->cur.cache.clip.w;
3650 h = obj->cur.cache.clip.h;
3651 iw = o->cur.image.w;
3652 ih = o->cur.image.h;
3654 if ((x < 0) || (y < 0) || (x >= w) || (y >= h)) return 0;
3655 if (!o->cur.has_alpha) return 1;
3657 // FIXME: proxy needs to be honored
3660 x = obj->cur.map->mx;
3661 y = obj->cur.map->my;
3665 int bl, br, bt, bb, bsl, bsr, bst, bsb;
3667 bl = o->cur.border.l;
3668 br = o->cur.border.r;
3669 bt = o->cur.border.t;
3670 bb = o->cur.border.b;
3691 if (o->cur.border.scale != 1.0)
3693 bsl = ((double)bl * o->cur.border.scale);
3694 bsr = ((double)br * o->cur.border.scale);
3695 bst = ((double)bt * o->cur.border.scale);
3696 bsb = ((double)bb * o->cur.border.scale);
3700 bsl = bl; bsr = br; bst = bt; bsb = bb;
3713 if (o->cur.border.fill != EVAS_BORDER_FILL_DEFAULT)
3715 if ((x > bsl) && (x < (w - bsr)) &&
3716 (y > bst) && (y < (h - bsb)))
3718 if (o->cur.border.fill == EVAS_BORDER_FILL_SOLID) return 1;
3723 if (x < bsl) x = (x * bl) / bsl;
3724 else if (x > (w - bsr)) x = iw - (((w - x) * br) / bsr);
3725 else if ((bsl + bsr) < w) x = bl + (((x - bsl) * (iw - bl - br)) / (w - bsl - bsr));
3728 if (y < bst) y = (y * bt) / bst;
3729 else if (y > (h - bsb)) y = ih - (((h - y) * bb) / bsb);
3730 else if ((bst + bsb) < h) y = bt + (((y - bst) * (ih - bt - bb)) / (h - bst - bsb));
3736 if (x >= iw) x = iw - 1;
3737 if (y >= ih) y = ih - 1;
3739 stride = o->cur.image.stride;
3741 o->engine_data = obj->layer->evas->engine.func->image_data_get
3742 (obj->layer->evas->engine.data.output,
3754 switch (o->cur.cspace)
3756 case EVAS_COLORSPACE_ARGB8888:
3757 data = ((DATA32*)(data) + ((y * (stride >> 2)) + x));
3758 a = (*((DATA32*)(data)) >> 24) & 0xff;
3760 case EVAS_COLORSPACE_RGB565_A5P:
3761 data = (void*) ((DATA16*)(data) + (h * (stride >> 1)));
3762 data = (void*) ((DATA8*)(data) + ((y * (stride >> 1)) + x));
3763 a = (*((DATA8*)(data))) & 0x1f;
3771 return_value = (a != 0);
3776 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
3779 return return_value;
3783 evas_object_image_has_opaque_rect(Evas_Object *obj)
3785 Evas_Object_Image *o;
3787 o = (Evas_Object_Image *)(obj->object_data);
3788 if ((obj->cur.map) && (obj->cur.usemap)) return 0;
3789 if (((o->cur.border.l | o->cur.border.r | o->cur.border.t | o->cur.border.b) != 0) &&
3790 (o->cur.border.fill == EVAS_BORDER_FILL_SOLID) &&
3791 (obj->cur.render_op == EVAS_RENDER_BLEND) &&
3792 (obj->cur.cache.clip.a == 255) &&
3793 (o->cur.fill.x == 0) &&
3794 (o->cur.fill.y == 0) &&
3795 (o->cur.fill.w == obj->cur.geometry.w) &&
3796 (o->cur.fill.h == obj->cur.geometry.h)
3802 evas_object_image_get_opaque_rect(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
3804 Evas_Object_Image *o;
3806 o = (Evas_Object_Image *)(obj->object_data);
3807 if (o->cur.border.scale == 1.0)
3809 *x = obj->cur.geometry.x + o->cur.border.l;
3810 *y = obj->cur.geometry.y + o->cur.border.t;
3811 *w = obj->cur.geometry.w - (o->cur.border.l + o->cur.border.r);
3813 *h = obj->cur.geometry.h - (o->cur.border.t + o->cur.border.b);
3818 *x = obj->cur.geometry.x + (o->cur.border.l * o->cur.border.scale);
3819 *y = obj->cur.geometry.y + (o->cur.border.t * o->cur.border.scale);
3820 *w = obj->cur.geometry.w - ((o->cur.border.l * o->cur.border.scale) + (o->cur.border.r * o->cur.border.scale));
3822 *h = obj->cur.geometry.h - ((o->cur.border.t * o->cur.border.scale) + (o->cur.border.b * o->cur.border.scale));
3829 evas_object_image_can_map(Evas_Object *obj __UNUSED__)
3835 evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_Colorspace to_cspace)
3842 switch (o->cur.cspace)
3844 case EVAS_COLORSPACE_ARGB8888:
3845 out = evas_common_convert_argb8888_to(data,
3848 o->cur.image.stride >> 2,
3852 case EVAS_COLORSPACE_RGB565_A5P:
3853 out = evas_common_convert_rgb565_a5p_to(data,
3856 o->cur.image.stride >> 1,
3860 case EVAS_COLORSPACE_YCBCR422601_PL:
3861 out = evas_common_convert_yuv_422_601_to(data,
3866 case EVAS_COLORSPACE_YCBCR422P601_PL:
3867 out = evas_common_convert_yuv_422P_601_to(data,
3872 case EVAS_COLORSPACE_YCBCR420NV12601_PL:
3873 out = evas_common_convert_yuv_420_601_to(data,
3878 case EVAS_COLORSPACE_YCBCR420TM12601_PL:
3879 out = evas_common_convert_yuv_420T_601_to(data,
3885 WRN("unknow colorspace: %i\n", o->cur.cspace);
3893 evas_object_image_filled_resize_listener(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *einfo __UNUSED__)
3897 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3898 evas_object_image_fill_set(obj, 0, 0, w, h);
3903 _evas_object_image_preloading_get(const Evas_Object *obj)
3905 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3906 if (!o) return EINA_FALSE;
3907 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
3910 return o->preloading;
3914 _evas_object_image_preloading_set(Evas_Object *obj, Eina_Bool preloading)
3916 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3917 o->preloading = preloading;
3921 _evas_object_image_preloading_check(Evas_Object *obj)
3923 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3924 if (obj->layer->evas->engine.func->image_load_error_get)
3925 o->load_error = obj->layer->evas->engine.func->image_load_error_get
3926 (obj->layer->evas->engine.data.output, o->engine_data);
3930 _evas_object_image_video_parent_get(Evas_Object *obj)
3932 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3934 return o->video_surface ? o->video.parent : NULL;
3938 _evas_object_image_video_overlay_show(Evas_Object *obj)
3940 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3942 if (obj->cur.cache.clip.x != obj->prev.cache.clip.x ||
3943 obj->cur.cache.clip.y != obj->prev.cache.clip.y ||
3944 o->created || !o->video_visible)
3945 o->video.move(o->video.data, obj, &o->video, obj->cur.cache.clip.x, obj->cur.cache.clip.y);
3946 if (obj->cur.cache.clip.w != obj->prev.cache.clip.w ||
3947 obj->cur.cache.clip.h != obj->prev.cache.clip.h ||
3948 o->created || !o->video_visible)
3949 o->video.resize(o->video.data, obj, &o->video, obj->cur.cache.clip.w, obj->cur.cache.clip.h);
3950 if (!o->video_visible || o->created)
3952 o->video.show(o->video.data, obj, &o->video);
3956 /* Cancel dirty on the image */
3959 o->dirty_pixels = 0;
3960 EINA_LIST_FREE(o->pixel_updates, r)
3961 eina_rectangle_free(r);
3963 o->video_visible = EINA_TRUE;
3964 o->created = EINA_FALSE;
3968 _evas_object_image_video_overlay_hide(Evas_Object *obj)
3970 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3972 if (o->video_visible || o->created)
3973 o->video.hide(o->video.data, obj, &o->video);
3974 if (evas_object_is_visible(obj))
3975 o->video.update_pixels(o->video.data, obj, &o->video);
3976 o->video_visible = EINA_FALSE;
3977 o->created = EINA_FALSE;
3980 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/