aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/lib/canvas/evas_object_image.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/evas/src/lib/canvas/evas_object_image.c3895
1 files changed, 3895 insertions, 0 deletions
diff --git a/libraries/evas/src/lib/canvas/evas_object_image.c b/libraries/evas/src/lib/canvas/evas_object_image.c
new file mode 100644
index 0000000..7f757a6
--- /dev/null
+++ b/libraries/evas/src/lib/canvas/evas_object_image.c
@@ -0,0 +1,3895 @@
1#include <sys/types.h>
2#include <unistd.h>
3#include <stdlib.h>
4#include <sys/mman.h>
5#include <math.h>
6
7#include "evas_common.h"
8#include "evas_private.h"
9#include "../engines/common/evas_convert_color.h"
10#include "../engines/common/evas_convert_colorspace.h"
11#include "../engines/common/evas_convert_yuv.h"
12
13#define VERBOSE_PROXY_ERROR 1
14
15/* private magic number for image objects */
16static const char o_type[] = "image";
17
18/* private struct for rectangle object internal data */
19typedef struct _Evas_Object_Image Evas_Object_Image;
20
21struct _Evas_Object_Image
22{
23 DATA32 magic;
24
25 struct {
26 int spread;
27 Evas_Coord_Rectangle fill;
28 struct {
29 short w, h, stride;
30 } image;
31 struct {
32 short l, r, t, b;
33 unsigned char fill;
34 double scale;
35 } border;
36
37 Evas_Object *source;
38 Evas_Map *defmap;
39 const char *file;
40 const char *key;
41 int frame;
42 Evas_Colorspace cspace;
43
44 unsigned char smooth_scale : 1;
45 unsigned char has_alpha :1;
46 unsigned char opaque :1;
47 unsigned char opaque_valid :1;
48 } cur, prev;
49
50 int pixels_checked_out;
51 int load_error;
52 Eina_List *pixel_updates;
53
54 struct {
55 unsigned char scale_down_by;
56 double dpi;
57 short w, h;
58 struct {
59 short x, y, w, h;
60 } region;
61 Eina_Bool orientation : 1;
62 } load_opts;
63
64 struct {
65 Evas_Object_Image_Pixels_Get_Cb get_pixels;
66 void *get_pixels_data;
67 } func;
68
69 Evas_Video_Surface video;
70
71 const char *tmpf;
72 int tmpf_fd;
73
74 Evas_Image_Scale_Hint scale_hint;
75 Evas_Image_Content_Hint content_hint;
76
77 void *engine_data;
78
79 unsigned char changed : 1;
80 unsigned char dirty_pixels : 1;
81 unsigned char filled : 1;
82 unsigned char proxyrendering : 1;
83 unsigned char preloading : 1;
84 unsigned char video_rendering : 1;
85 unsigned char video_surface : 1;
86 unsigned char video_visible : 1;
87 unsigned char created : 1;
88};
89
90/* private methods for image objects */
91static void evas_object_image_unload(Evas_Object *obj, Eina_Bool dirty);
92static void evas_object_image_load(Evas_Object *obj);
93static Evas_Coord evas_object_image_figure_x_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret);
94static Evas_Coord evas_object_image_figure_y_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret);
95
96static void evas_object_image_init(Evas_Object *obj);
97static void *evas_object_image_new(void);
98static void evas_object_image_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y);
99static void evas_object_image_free(Evas_Object *obj);
100static void evas_object_image_render_pre(Evas_Object *obj);
101static void evas_object_image_render_post(Evas_Object *obj);
102
103static unsigned int evas_object_image_id_get(Evas_Object *obj);
104static unsigned int evas_object_image_visual_id_get(Evas_Object *obj);
105static void *evas_object_image_engine_data_get(Evas_Object *obj);
106
107static int evas_object_image_is_opaque(Evas_Object *obj);
108static int evas_object_image_was_opaque(Evas_Object *obj);
109static int evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
110static int evas_object_image_has_opaque_rect(Evas_Object *obj);
111static int evas_object_image_get_opaque_rect(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
112static int evas_object_image_can_map(Evas_Object *obj);
113
114static void *evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_Colorspace to_cspace);
115static void evas_object_image_filled_resize_listener(void *data, Evas *e, Evas_Object *obj, void *einfo);
116
117static void _proxy_unset(Evas_Object *proxy);
118static void _proxy_set(Evas_Object *proxy, Evas_Object *src);
119static void _proxy_error(Evas_Object *proxy, void *context, void *output, void *surface, int x, int y);
120
121static void _cleanup_tmpf(Evas_Object *obj);
122
123static const Evas_Object_Func object_func =
124{
125 /* methods (compulsory) */
126 evas_object_image_free,
127 evas_object_image_render,
128 evas_object_image_render_pre,
129 evas_object_image_render_post,
130 evas_object_image_id_get,
131 evas_object_image_visual_id_get,
132 evas_object_image_engine_data_get,
133 /* these are optional. NULL = nothing */
134 NULL,
135 NULL,
136 NULL,
137 NULL,
138 evas_object_image_is_opaque,
139 evas_object_image_was_opaque,
140 evas_object_image_is_inside,
141 NULL,
142 NULL,
143 NULL,
144 evas_object_image_has_opaque_rect,
145 evas_object_image_get_opaque_rect,
146 evas_object_image_can_map
147};
148
149EVAS_MEMPOOL(_mp_obj);
150
151static void
152_evas_object_image_cleanup(Evas_Object *obj, Evas_Object_Image *o)
153{
154 if ((o->preloading) && (o->engine_data))
155 {
156 o->preloading = 0;
157 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
158 o->engine_data,
159 obj);
160 }
161 if (o->tmpf) _cleanup_tmpf(obj);
162 if (o->cur.source) _proxy_unset(obj);
163}
164
165EAPI Evas_Object *
166evas_object_image_add(Evas *e)
167{
168 Evas_Object *obj;
169 Evas_Object_Image *o;
170
171 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
172 return NULL;
173 MAGIC_CHECK_END();
174 obj = evas_object_new(e);
175 evas_object_image_init(obj);
176 evas_object_inject(obj, e);
177 o = (Evas_Object_Image *)(obj->object_data);
178 o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output,
179 o->engine_data);
180 return obj;
181}
182
183EAPI Evas_Object *
184evas_object_image_filled_add(Evas *e)
185{
186 Evas_Object *obj;
187 obj = evas_object_image_add(e);
188 evas_object_image_filled_set(obj, 1);
189 return obj;
190}
191
192static void
193_cleanup_tmpf(Evas_Object *obj)
194{
195 Evas_Object_Image *o;
196
197 o = (Evas_Object_Image *)(obj->object_data);
198 if (!o->tmpf) return;
199#ifdef __linux__
200#else
201 unlink(o->tmpf);
202#endif
203 if (o->tmpf_fd >= 0) close(o->tmpf_fd);
204 eina_stringshare_del(o->tmpf);
205 o->tmpf_fd = -1;
206 o->tmpf = NULL;
207}
208
209static void
210_create_tmpf(Evas_Object *obj, void *data, int size, char *format __UNUSED__)
211{
212 Evas_Object_Image *o;
213 char buf[4096];
214 void *dst;
215 int fd = -1;
216
217 o = (Evas_Object_Image *)(obj->object_data);
218#ifdef __linux__
219 snprintf(buf, sizeof(buf), "/dev/shm/.evas-tmpf-%i-%p-%i-XXXXXX",
220 (int)getpid(), data, (int)size);
221 fd = mkstemp(buf);
222#endif
223 if (fd < 0)
224 {
225 snprintf(buf, sizeof(buf), "/tmp/.evas-tmpf-%i-%p-%i-XXXXXX",
226 (int)getpid(), data, (int)size);
227 fd = mkstemp(buf);
228 }
229 if (fd < 0) return;
230 if (ftruncate(fd, size) < 0)
231 {
232 unlink(buf);
233 close(fd);
234 return;
235 }
236 unlink(buf);
237
238 eina_mmap_safety_enabled_set(EINA_TRUE);
239
240 dst = mmap(NULL, size,
241 PROT_READ | PROT_WRITE,
242 MAP_SHARED,
243 fd, 0);
244 if (dst == MAP_FAILED)
245 {
246 close(fd);
247 return;
248 }
249 o->tmpf_fd = fd;
250#ifdef __linux__
251 snprintf(buf, sizeof(buf), "/proc/%li/fd/%i", (long)getpid(), fd);
252#endif
253 o->tmpf = eina_stringshare_add(buf);
254 memcpy(dst, data, size);
255 munmap(dst, size);
256}
257
258EAPI void
259evas_object_image_memfile_set(Evas_Object *obj, void *data, int size, char *format, char *key)
260{
261 Evas_Object_Image *o;
262
263 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
264 return;
265 MAGIC_CHECK_END();
266 o = (Evas_Object_Image *)(obj->object_data);
267 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
268 return;
269 MAGIC_CHECK_END();
270 _cleanup_tmpf(obj);
271 evas_object_image_file_set(obj, NULL, NULL);
272 // invalidate the cache effectively
273 evas_object_image_alpha_set(obj, !o->cur.has_alpha);
274 evas_object_image_alpha_set(obj, !o->cur.has_alpha);
275
276 if ((size < 1) || (!data)) return;
277
278 _create_tmpf(obj, data, size, format);
279 evas_object_image_file_set(obj, o->tmpf, key);
280 if (!o->engine_data)
281 {
282 ERR("unable to load '%s' from memory", o->tmpf);
283 _cleanup_tmpf(obj);
284 return;
285 }
286}
287
288EAPI void
289evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key)
290{
291 Evas_Object_Image *o;
292 Evas_Image_Load_Opts lo;
293
294 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
295 return;
296 MAGIC_CHECK_END();
297 o = (Evas_Object_Image *)(obj->object_data);
298 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
299 return;
300 MAGIC_CHECK_END();
301 if ((o->tmpf) && (file != o->tmpf)) _cleanup_tmpf(obj);
302 if ((o->cur.file) && (file) && (!strcmp(o->cur.file, file)))
303 {
304 if ((!o->cur.key) && (!key))
305 return;
306 if ((o->cur.key) && (key) && (!strcmp(o->cur.key, key)))
307 return;
308 }
309/*
310 * WTF? why cancel a null image preload? this is just silly (tm)
311 if (!o->engine_data)
312 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
313 o->engine_data,
314 obj);
315 */
316 if (o->cur.source) _proxy_unset(obj);
317 if (o->cur.file) eina_stringshare_del(o->cur.file);
318 if (o->cur.key) eina_stringshare_del(o->cur.key);
319 if (file) o->cur.file = eina_stringshare_add(file);
320 else o->cur.file = NULL;
321 if (key) o->cur.key = eina_stringshare_add(key);
322 else o->cur.key = NULL;
323 o->prev.file = NULL;
324 o->prev.key = NULL;
325 if (o->engine_data)
326 {
327 if (o->preloading)
328 {
329 o->preloading = 0;
330 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
331 o->engine_data,
332 obj);
333 }
334 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
335 o->engine_data);
336 }
337 o->load_error = EVAS_LOAD_ERROR_NONE;
338 lo.scale_down_by = o->load_opts.scale_down_by;
339 lo.dpi = o->load_opts.dpi;
340 lo.w = o->load_opts.w;
341 lo.h = o->load_opts.h;
342 lo.region.x = o->load_opts.region.x;
343 lo.region.y = o->load_opts.region.y;
344 lo.region.w = o->load_opts.region.w;
345 lo.region.h = o->load_opts.region.h;
346 lo.orientation = o->load_opts.orientation;
347 o->engine_data = obj->layer->evas->engine.func->image_load(obj->layer->evas->engine.data.output,
348 o->cur.file,
349 o->cur.key,
350 &o->load_error,
351 &lo);
352 if (o->engine_data)
353 {
354 int w, h;
355 int stride;
356
357 obj->layer->evas->engine.func->image_size_get(obj->layer->evas->engine.data.output,
358 o->engine_data, &w, &h);
359 if (obj->layer->evas->engine.func->image_stride_get)
360 obj->layer->evas->engine.func->image_stride_get(obj->layer->evas->engine.data.output,
361 o->engine_data, &stride);
362 else
363 stride = w * 4;
364 o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get(obj->layer->evas->engine.data.output,
365 o->engine_data);
366 o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output,
367 o->engine_data);
368 o->cur.image.w = w;
369 o->cur.image.h = h;
370 o->cur.image.stride = stride;
371 }
372 else
373 {
374 if (o->load_error == EVAS_LOAD_ERROR_NONE)
375 o->load_error = EVAS_LOAD_ERROR_GENERIC;
376 o->cur.has_alpha = 1;
377 o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
378 o->cur.image.w = 0;
379 o->cur.image.h = 0;
380 o->cur.image.stride = 0;
381 }
382 o->changed = 1;
383 evas_object_change(obj);
384}
385
386EAPI void
387evas_object_image_file_get(const Evas_Object *obj, const char **file, const char **key)
388{
389 Evas_Object_Image *o;
390
391 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
392 if (file) *file = NULL;
393 if (key) *key = NULL;
394 return;
395 MAGIC_CHECK_END();
396 o = (Evas_Object_Image *)(obj->object_data);
397 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
398 if (file) *file = NULL;
399 if (key) *key = NULL;
400 return;
401 MAGIC_CHECK_END();
402 if (file) *file = o->cur.file;
403 if (key) *key = o->cur.key;
404}
405
406EAPI Eina_Bool
407evas_object_image_source_set(Evas_Object *obj, Evas_Object *src)
408{
409 Evas_Object_Image *o;
410
411 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
412 return EINA_FALSE;
413 MAGIC_CHECK_END();
414 o = obj->object_data;
415 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
416 return EINA_FALSE;
417 MAGIC_CHECK_END();
418
419 if (src == obj) return EINA_FALSE;
420 if (o->cur.source == src) return EINA_TRUE;
421
422 _evas_object_image_cleanup(obj, o);
423 /* Kill the image if any */
424 if (o->cur.file || o->cur.key)
425 evas_object_image_file_set(obj, NULL, NULL);
426
427 if (src)
428 {
429 _proxy_set(obj, src);
430 }
431
432 return EINA_TRUE;
433}
434
435
436EAPI Evas_Object *
437evas_object_image_source_get(Evas_Object *obj)
438{
439 Evas_Object_Image *o;
440
441 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
442 return NULL;
443 MAGIC_CHECK_END();
444 o = obj->object_data;
445 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
446 return NULL;
447 MAGIC_CHECK_END();
448
449 return o->cur.source;
450}
451
452EAPI Eina_Bool
453evas_object_image_source_unset(Evas_Object *obj)
454{
455 return evas_object_image_source_set(obj, NULL);
456}
457
458EAPI void
459evas_object_image_border_set(Evas_Object *obj, int l, int r, int t, int b)
460{
461 Evas_Object_Image *o;
462
463 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
464 return;
465 MAGIC_CHECK_END();
466 o = (Evas_Object_Image *)(obj->object_data);
467 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
468 return;
469 MAGIC_CHECK_END();
470 if (l < 0) l = 0;
471 if (r < 0) r = 0;
472 if (t < 0) t = 0;
473 if (b < 0) b = 0;
474 if ((o->cur.border.l == l) &&
475 (o->cur.border.r == r) &&
476 (o->cur.border.t == t) &&
477 (o->cur.border.b == b)) return;
478 o->cur.border.l = l;
479 o->cur.border.r = r;
480 o->cur.border.t = t;
481 o->cur.border.b = b;
482 o->cur.opaque_valid = 0;
483 o->changed = 1;
484 evas_object_change(obj);
485}
486
487EAPI void
488evas_object_image_border_get(const Evas_Object *obj, int *l, int *r, int *t, int *b)
489{
490 Evas_Object_Image *o;
491
492 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
493 if (l) *l = 0;
494 if (r) *r = 0;
495 if (t) *t = 0;
496 if (b) *b = 0;
497 return;
498 MAGIC_CHECK_END();
499 o = (Evas_Object_Image *)(obj->object_data);
500 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
501 if (l) *l = 0;
502 if (r) *r = 0;
503 if (t) *t = 0;
504 if (b) *b = 0;
505 return;
506 MAGIC_CHECK_END();
507 if (l) *l = o->cur.border.l;
508 if (r) *r = o->cur.border.r;
509 if (t) *t = o->cur.border.t;
510 if (b) *b = o->cur.border.b;
511}
512
513EAPI void
514evas_object_image_border_center_fill_set(Evas_Object *obj, Evas_Border_Fill_Mode fill)
515{
516 Evas_Object_Image *o;
517
518 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
519 return;
520 MAGIC_CHECK_END();
521 o = (Evas_Object_Image *)(obj->object_data);
522 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
523 return;
524 MAGIC_CHECK_END();
525 if (fill == o->cur.border.fill) return;
526 o->cur.border.fill = fill;
527 o->changed = 1;
528 evas_object_change(obj);
529}
530
531EAPI Evas_Border_Fill_Mode
532evas_object_image_border_center_fill_get(const Evas_Object *obj)
533{
534 Evas_Object_Image *o;
535
536 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
537 return 0;
538 MAGIC_CHECK_END();
539 o = (Evas_Object_Image *)(obj->object_data);
540 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
541 return 0;
542 MAGIC_CHECK_END();
543 return o->cur.border.fill;
544}
545
546EAPI void
547evas_object_image_filled_set(Evas_Object *obj, Eina_Bool setting)
548{
549 Evas_Object_Image *o;
550
551 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
552 return;
553 MAGIC_CHECK_END();
554 o = (Evas_Object_Image *)(obj->object_data);
555 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
556 return;
557 MAGIC_CHECK_END();
558
559 setting = !!setting;
560 if (o->filled == setting) return;
561
562 o->filled = setting;
563 if (!o->filled)
564 evas_object_event_callback_del(obj, EVAS_CALLBACK_RESIZE, evas_object_image_filled_resize_listener);
565 else
566 {
567 Evas_Coord w, h;
568
569 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
570 evas_object_image_fill_set(obj, 0, 0, w, h);
571
572 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, evas_object_image_filled_resize_listener, NULL);
573 }
574}
575
576EAPI Eina_Bool
577evas_object_image_filled_get(const Evas_Object *obj)
578{
579 Evas_Object_Image *o;
580
581 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
582 return 0;
583 MAGIC_CHECK_END();
584 o = (Evas_Object_Image *)(obj->object_data);
585 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
586 return 0;
587 MAGIC_CHECK_END();
588
589 return o->filled;
590}
591
592EAPI void
593evas_object_image_border_scale_set(Evas_Object *obj, double scale)
594{
595 Evas_Object_Image *o;
596
597 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
598 return;
599 MAGIC_CHECK_END();
600 o = (Evas_Object_Image *)(obj->object_data);
601 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
602 return;
603 MAGIC_CHECK_END();
604 if (scale == o->cur.border.scale) return;
605 o->cur.border.scale = scale;
606 o->changed = 1;
607 evas_object_change(obj);
608}
609
610EAPI double
611evas_object_image_border_scale_get(const Evas_Object *obj)
612{
613 Evas_Object_Image *o;
614
615 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
616 return 1.0;
617 MAGIC_CHECK_END();
618 o = (Evas_Object_Image *)(obj->object_data);
619 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
620 return 1.0;
621 MAGIC_CHECK_END();
622 return o->cur.border.scale;
623}
624
625EAPI void
626evas_object_image_fill_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
627{
628 Evas_Object_Image *o;
629
630 if (w < 0) w = -w;
631 if (h < 0) h = -h;
632 if (w == 0) return;
633 if (h == 0) return;
634 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
635 return;
636 MAGIC_CHECK_END();
637 o = (Evas_Object_Image *)(obj->object_data);
638 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
639 return;
640 MAGIC_CHECK_END();
641 if ((o->cur.fill.x == x) &&
642 (o->cur.fill.y == y) &&
643 (o->cur.fill.w == w) &&
644 (o->cur.fill.h == h)) return;
645 o->cur.fill.x = x;
646 o->cur.fill.y = y;
647 o->cur.fill.w = w;
648 o->cur.fill.h = h;
649 o->cur.opaque_valid = 0;
650 o->changed = 1;
651 evas_object_change(obj);
652}
653
654EAPI void
655evas_object_image_fill_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
656{
657 Evas_Object_Image *o;
658
659 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
660 if (x) *x = 0;
661 if (y) *y = 0;
662 if (w) *w = 0;
663 if (h) *h = 0;
664 return;
665 MAGIC_CHECK_END();
666 o = (Evas_Object_Image *)(obj->object_data);
667 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
668 if (x) *x = 0;
669 if (y) *y = 0;
670 if (w) *w = 0;
671 if (h) *h = 0;
672 return;
673 MAGIC_CHECK_END();
674 if (x) *x = o->cur.fill.x;
675 if (y) *y = o->cur.fill.y;
676 if (w) *w = o->cur.fill.w;
677 if (h) *h = o->cur.fill.h;
678}
679
680
681EAPI void
682evas_object_image_fill_spread_set(Evas_Object *obj, Evas_Fill_Spread spread)
683{
684 Evas_Object_Image *o;
685
686 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
687 return;
688 MAGIC_CHECK_END();
689 o = (Evas_Object_Image *)(obj->object_data);
690 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
691 return;
692 MAGIC_CHECK_END();
693 if (spread == (Evas_Fill_Spread)o->cur.spread) return;
694 o->cur.spread = spread;
695 o->changed = 1;
696 evas_object_change(obj);
697}
698
699EAPI Evas_Fill_Spread
700evas_object_image_fill_spread_get(const Evas_Object *obj)
701{
702 Evas_Object_Image *o;
703
704 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
705 return EVAS_TEXTURE_REPEAT;
706 MAGIC_CHECK_END();
707 o = (Evas_Object_Image *)(obj->object_data);
708 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
709 return EVAS_TEXTURE_REPEAT;
710 MAGIC_CHECK_END();
711 return (Evas_Fill_Spread)o->cur.spread;
712}
713
714EAPI void
715evas_object_image_size_set(Evas_Object *obj, int w, int h)
716{
717 Evas_Object_Image *o;
718 int stride = 0;
719
720 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
721 return;
722 MAGIC_CHECK_END();
723 o = (Evas_Object_Image *)(obj->object_data);
724 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
725 return;
726 MAGIC_CHECK_END();
727 _evas_object_image_cleanup(obj, o);
728 if (w < 1) w = 1;
729 if (h < 1) h = 1;
730 if (w > 32768) return;
731 if (h > 32768) return;
732 if ((w == o->cur.image.w) &&
733 (h == o->cur.image.h)) return;
734 o->cur.image.w = w;
735 o->cur.image.h = h;
736 if (o->engine_data)
737 o->engine_data = obj->layer->evas->engine.func->image_size_set(obj->layer->evas->engine.data.output,
738 o->engine_data,
739 w, h);
740 else
741 o->engine_data = obj->layer->evas->engine.func->image_new_from_copied_data
742 (obj->layer->evas->engine.data.output, w, h, NULL, o->cur.has_alpha,
743 o->cur.cspace);
744
745 if (o->engine_data)
746 {
747 if (obj->layer->evas->engine.func->image_scale_hint_set)
748 obj->layer->evas->engine.func->image_scale_hint_set
749 (obj->layer->evas->engine.data.output,
750 o->engine_data, o->scale_hint);
751 if (obj->layer->evas->engine.func->image_content_hint_set)
752 obj->layer->evas->engine.func->image_content_hint_set
753 (obj->layer->evas->engine.data.output,
754 o->engine_data, o->content_hint);
755 if (obj->layer->evas->engine.func->image_stride_get)
756 obj->layer->evas->engine.func->image_stride_get
757 (obj->layer->evas->engine.data.output,
758 o->engine_data, &stride);
759 else
760 stride = w * 4;
761 }
762 else
763 stride = w * 4;
764 o->cur.image.stride = stride;
765
766/* FIXME - in engine call above
767 if (o->engine_data)
768 o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
769 o->engine_data,
770 o->cur.has_alpha);
771*/
772 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
773 o->changed = 1;
774 evas_object_change(obj);
775}
776
777EAPI void
778evas_object_image_size_get(const Evas_Object *obj, int *w, int *h)
779{
780 Evas_Object_Image *o;
781
782 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
783 if (w) *w = 0;
784 if (h) *h = 0;
785 return;
786 MAGIC_CHECK_END();
787 o = (Evas_Object_Image *)(obj->object_data);
788 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
789 if (w) *w = 0;
790 if (h) *h = 0;
791 return;
792 MAGIC_CHECK_END();
793 if (w) *w = o->cur.image.w;
794 if (h) *h = o->cur.image.h;
795}
796
797EAPI int
798evas_object_image_stride_get(const Evas_Object *obj)
799{
800 Evas_Object_Image *o;
801
802 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
803 return 0;
804 MAGIC_CHECK_END();
805 o = (Evas_Object_Image *)(obj->object_data);
806 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
807 return 0;
808 MAGIC_CHECK_END();
809 return o->cur.image.stride;
810}
811
812EAPI Evas_Load_Error
813evas_object_image_load_error_get(const Evas_Object *obj)
814{
815 Evas_Object_Image *o;
816
817 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
818 return 0;
819 MAGIC_CHECK_END();
820 o = (Evas_Object_Image *)(obj->object_data);
821 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
822 return 0;
823 MAGIC_CHECK_END();
824 return o->load_error;
825}
826
827EAPI void *
828evas_object_image_data_convert(Evas_Object *obj, Evas_Colorspace to_cspace)
829{
830 Evas_Object_Image *o;
831 DATA32 *data;
832
833 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
834 return NULL;
835 MAGIC_CHECK_END();
836 o = (Evas_Object_Image *)(obj->object_data);
837 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
838 return NULL;
839 MAGIC_CHECK_END();
840 if ((o->preloading) && (o->engine_data))
841 {
842 o->preloading = 0;
843 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
844 o->engine_data,
845 obj);
846 }
847 if (!o->engine_data) return NULL;
848 if (o->video_surface)
849 o->video.update_pixels(o->video.data, obj, &o->video);
850 if (o->cur.cspace == to_cspace) return NULL;
851 data = NULL;
852 o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
853 o->engine_data,
854 0,
855 &data,
856 &o->load_error);
857 return evas_object_image_data_convert_internal(o, data, to_cspace);
858}
859
860EAPI void
861evas_object_image_data_set(Evas_Object *obj, void *data)
862{
863 Evas_Object_Image *o;
864 void *p_data;
865
866 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
867 return;
868 MAGIC_CHECK_END();
869 o = (Evas_Object_Image *)(obj->object_data);
870 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
871 return;
872 MAGIC_CHECK_END();
873 _evas_object_image_cleanup(obj, o);
874#ifdef EVAS_FRAME_QUEUING
875 if (o->engine_data)
876 evas_common_pipe_op_image_flush(o->engine_data);
877#endif
878 p_data = o->engine_data;
879 if (data)
880 {
881 if (o->engine_data)
882 o->engine_data = obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
883 o->engine_data,
884 data);
885 else
886 o->engine_data = obj->layer->evas->engine.func->image_new_from_data(obj->layer->evas->engine.data.output,
887 o->cur.image.w,
888 o->cur.image.h,
889 data,
890 o->cur.has_alpha,
891 o->cur.cspace);
892 if (o->engine_data)
893 {
894 int stride = 0;
895
896 if (obj->layer->evas->engine.func->image_scale_hint_set)
897 obj->layer->evas->engine.func->image_scale_hint_set
898 (obj->layer->evas->engine.data.output,
899 o->engine_data, o->scale_hint);
900 if (obj->layer->evas->engine.func->image_content_hint_set)
901 obj->layer->evas->engine.func->image_content_hint_set
902 (obj->layer->evas->engine.data.output,
903 o->engine_data, o->content_hint);
904 if (obj->layer->evas->engine.func->image_stride_get)
905 obj->layer->evas->engine.func->image_stride_get
906 (obj->layer->evas->engine.data.output,
907 o->engine_data, &stride);
908 else
909 stride = o->cur.image.w * 4;
910 o->cur.image.stride = stride;
911 }
912 }
913 else
914 {
915 if (o->engine_data)
916 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
917 o->engine_data);
918 o->load_error = EVAS_LOAD_ERROR_NONE;
919 o->cur.image.w = 0;
920 o->cur.image.h = 0;
921 o->cur.image.stride = 0;
922 o->engine_data = NULL;
923 }
924/* FIXME - in engine call above
925 if (o->engine_data)
926 o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
927 o->engine_data,
928 o->cur.has_alpha);
929*/
930 if (o->pixels_checked_out > 0) o->pixels_checked_out--;
931 if (p_data != o->engine_data)
932 {
933 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
934 o->pixels_checked_out = 0;
935 }
936 o->changed = 1;
937 evas_object_change(obj);
938}
939
940EAPI void *
941evas_object_image_data_get(const Evas_Object *obj, Eina_Bool for_writing)
942{
943 Evas_Object_Image *o;
944 DATA32 *data;
945
946 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
947 return NULL;
948 MAGIC_CHECK_END();
949 o = (Evas_Object_Image *)(obj->object_data);
950 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
951 return NULL;
952 MAGIC_CHECK_END();
953 if (!o->engine_data) return NULL;
954#ifdef EVAS_FRAME_QUEUING
955 evas_common_pipe_op_image_flush(o->engine_data);
956#endif
957
958 data = NULL;
959 if (obj->layer->evas->engine.func->image_scale_hint_set)
960 obj->layer->evas->engine.func->image_scale_hint_set
961 (obj->layer->evas->engine.data.output,
962 o->engine_data, o->scale_hint);
963 if (obj->layer->evas->engine.func->image_content_hint_set)
964 obj->layer->evas->engine.func->image_content_hint_set
965 (obj->layer->evas->engine.data.output,
966 o->engine_data, o->content_hint);
967 o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
968 o->engine_data,
969 for_writing,
970 &data,
971 &o->load_error);
972
973 /* if we fail to get engine_data, we have to return NULL */
974 if (!o->engine_data) return NULL;
975
976 if (o->engine_data)
977 {
978 int stride = 0;
979
980 if (obj->layer->evas->engine.func->image_stride_get)
981 obj->layer->evas->engine.func->image_stride_get
982 (obj->layer->evas->engine.data.output,
983 o->engine_data, &stride);
984 else
985 stride = o->cur.image.w * 4;
986 o->cur.image.stride = stride;
987 }
988 o->pixels_checked_out++;
989 if (for_writing)
990 {
991 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
992 }
993
994 return data;
995}
996
997EAPI void
998evas_object_image_preload(Evas_Object *obj, Eina_Bool cancel)
999{
1000 Evas_Object_Image *o;
1001
1002 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1003 return ;
1004 MAGIC_CHECK_END();
1005 o = (Evas_Object_Image *)(obj->object_data);
1006 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1007 return ;
1008 MAGIC_CHECK_END();
1009 if (!o->engine_data)
1010 {
1011 o->preloading = 1;
1012 evas_object_inform_call_image_preloaded(obj);
1013 return;
1014 }
1015 // FIXME: if already busy preloading, then dont request again until
1016 // preload done
1017 if (cancel)
1018 {
1019 if (o->preloading)
1020 {
1021 o->preloading = 0;
1022 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
1023 o->engine_data,
1024 obj);
1025 }
1026 }
1027 else
1028 {
1029 if (!o->preloading)
1030 {
1031 o->preloading = 1;
1032 obj->layer->evas->engine.func->image_data_preload_request(obj->layer->evas->engine.data.output,
1033 o->engine_data,
1034 obj);
1035 }
1036 }
1037}
1038
1039EAPI void
1040evas_object_image_data_copy_set(Evas_Object *obj, void *data)
1041{
1042 Evas_Object_Image *o;
1043
1044 if (!data) return;
1045 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1046 return;
1047 MAGIC_CHECK_END();
1048 o = (Evas_Object_Image *)(obj->object_data);
1049 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1050 return;
1051 MAGIC_CHECK_END();
1052 _evas_object_image_cleanup(obj, o);
1053 if ((o->cur.image.w <= 0) ||
1054 (o->cur.image.h <= 0)) return;
1055 if (o->engine_data)
1056 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
1057 o->engine_data);
1058 o->engine_data = obj->layer->evas->engine.func->image_new_from_copied_data(obj->layer->evas->engine.data.output,
1059 o->cur.image.w,
1060 o->cur.image.h,
1061 data,
1062 o->cur.has_alpha,
1063 o->cur.cspace);
1064 if (o->engine_data)
1065 {
1066 int stride = 0;
1067
1068 o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1069 o->engine_data,
1070 o->cur.has_alpha);
1071 if (obj->layer->evas->engine.func->image_scale_hint_set)
1072 obj->layer->evas->engine.func->image_scale_hint_set
1073 (obj->layer->evas->engine.data.output,
1074 o->engine_data, o->scale_hint);
1075 if (obj->layer->evas->engine.func->image_content_hint_set)
1076 obj->layer->evas->engine.func->image_content_hint_set
1077 (obj->layer->evas->engine.data.output,
1078 o->engine_data, o->content_hint);
1079 if (obj->layer->evas->engine.func->image_stride_get)
1080 obj->layer->evas->engine.func->image_stride_get
1081 (obj->layer->evas->engine.data.output,
1082 o->engine_data, &stride);
1083 else
1084 stride = o->cur.image.w * 4;
1085 o->cur.image.stride = stride;
1086 }
1087 o->pixels_checked_out = 0;
1088 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
1089}
1090
1091EAPI void
1092evas_object_image_data_update_add(Evas_Object *obj, int x, int y, int w, int h)
1093{
1094 Evas_Object_Image *o;
1095 Eina_Rectangle *r;
1096
1097 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1098 return;
1099 MAGIC_CHECK_END();
1100 o = (Evas_Object_Image *)(obj->object_data);
1101 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1102 return;
1103 MAGIC_CHECK_END();
1104 RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, o->cur.image.w, o->cur.image.h);
1105 if ((w <= 0) || (h <= 0)) return;
1106 NEW_RECT(r, x, y, w, h);
1107 if (r) o->pixel_updates = eina_list_append(o->pixel_updates, r);
1108 o->changed = 1;
1109 evas_object_change(obj);
1110}
1111
1112EAPI void
1113evas_object_image_alpha_set(Evas_Object *obj, Eina_Bool has_alpha)
1114{
1115 Evas_Object_Image *o;
1116
1117 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1118 return;
1119 MAGIC_CHECK_END();
1120 o = (Evas_Object_Image *)(obj->object_data);
1121 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1122 return;
1123 MAGIC_CHECK_END();
1124 if ((o->preloading) && (o->engine_data))
1125 {
1126 o->preloading = 0;
1127 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
1128 o->engine_data,
1129 obj);
1130 }
1131 if (((has_alpha) && (o->cur.has_alpha)) ||
1132 ((!has_alpha) && (!o->cur.has_alpha)))
1133 return;
1134 o->cur.has_alpha = has_alpha;
1135 if (o->engine_data)
1136 {
1137 int stride = 0;
1138
1139#ifdef EVAS_FRAME_QUEUING
1140 evas_common_pipe_op_image_flush(o->engine_data);
1141#endif
1142 o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1143 o->engine_data,
1144 o->cur.has_alpha);
1145 if (obj->layer->evas->engine.func->image_scale_hint_set)
1146 obj->layer->evas->engine.func->image_scale_hint_set
1147 (obj->layer->evas->engine.data.output,
1148 o->engine_data, o->scale_hint);
1149 if (obj->layer->evas->engine.func->image_content_hint_set)
1150 obj->layer->evas->engine.func->image_content_hint_set
1151 (obj->layer->evas->engine.data.output,
1152 o->engine_data, o->content_hint);
1153 if (obj->layer->evas->engine.func->image_stride_get)
1154 obj->layer->evas->engine.func->image_stride_get
1155 (obj->layer->evas->engine.data.output,
1156 o->engine_data, &stride);
1157 else
1158 stride = o->cur.image.w * 4;
1159 o->cur.image.stride = stride;
1160 }
1161 evas_object_image_data_update_add(obj, 0, 0, o->cur.image.w, o->cur.image.h);
1162 EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
1163}
1164
1165
1166EAPI Eina_Bool
1167evas_object_image_alpha_get(const Evas_Object *obj)
1168{
1169 Evas_Object_Image *o;
1170
1171 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1172 return 0;
1173 MAGIC_CHECK_END();
1174 o = (Evas_Object_Image *)(obj->object_data);
1175 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1176 return 0;
1177 MAGIC_CHECK_END();
1178 return o->cur.has_alpha;
1179}
1180
1181EAPI void
1182evas_object_image_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth_scale)
1183{
1184 Evas_Object_Image *o;
1185
1186 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1187 return;
1188 MAGIC_CHECK_END();
1189 o = (Evas_Object_Image *)(obj->object_data);
1190 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1191 return;
1192 MAGIC_CHECK_END();
1193 if (((smooth_scale) && (o->cur.smooth_scale)) ||
1194 ((!smooth_scale) && (!o->cur.smooth_scale)))
1195 return;
1196 o->cur.smooth_scale = smooth_scale;
1197 o->changed = 1;
1198 evas_object_change(obj);
1199}
1200
1201EAPI Eina_Bool
1202evas_object_image_smooth_scale_get(const Evas_Object *obj)
1203{
1204 Evas_Object_Image *o;
1205
1206 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1207 return 0;
1208 MAGIC_CHECK_END();
1209 o = (Evas_Object_Image *)(obj->object_data);
1210 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1211 return 0;
1212 MAGIC_CHECK_END();
1213 return o->cur.smooth_scale;
1214}
1215
1216EAPI void
1217evas_object_image_reload(Evas_Object *obj)
1218{
1219 Evas_Object_Image *o;
1220
1221 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1222 return;
1223 MAGIC_CHECK_END();
1224 o = (Evas_Object_Image *)(obj->object_data);
1225 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1226 return;
1227 MAGIC_CHECK_END();
1228 if ((o->preloading) && (o->engine_data))
1229 {
1230 o->preloading = 0;
1231 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
1232 o->engine_data,
1233 obj);
1234 }
1235 if ((!o->cur.file) ||
1236 (o->pixels_checked_out > 0)) return;
1237 if (o->engine_data)
1238 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);
1239 evas_object_image_unload(obj, 1);
1240 evas_object_inform_call_image_unloaded(obj);
1241 evas_object_image_load(obj);
1242 o->prev.file = NULL;
1243 o->prev.key = NULL;
1244 o->changed = 1;
1245 evas_object_change(obj);
1246}
1247
1248EAPI Eina_Bool
1249evas_object_image_save(const Evas_Object *obj, const char *file, const char *key, const char *flags)
1250{
1251 Evas_Object_Image *o;
1252 DATA32 *data = NULL;
1253 int quality = 80, compress = 9, ok = 0;
1254 RGBA_Image *im;
1255
1256 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1257 return 0;
1258 MAGIC_CHECK_END();
1259 o = (Evas_Object_Image *)(obj->object_data);
1260 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1261 return 0;
1262 MAGIC_CHECK_END();
1263
1264 if (!o->engine_data) return 0;
1265 o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1266 o->engine_data,
1267 0,
1268 &data,
1269 &o->load_error);
1270 if (flags)
1271 {
1272 char *p, *pp;
1273 char *tflags;
1274
1275 tflags = alloca(strlen(flags) + 1);
1276 strcpy(tflags, flags);
1277 p = tflags;
1278 while (p)
1279 {
1280 pp = strchr(p, ' ');
1281 if (pp) *pp = 0;
1282 sscanf(p, "quality=%i", &quality);
1283 sscanf(p, "compress=%i", &compress);
1284 if (pp) p = pp + 1;
1285 else break;
1286 }
1287 }
1288 im = (RGBA_Image*) evas_cache_image_data(evas_common_image_cache_get(),
1289 o->cur.image.w,
1290 o->cur.image.h,
1291 data,
1292 o->cur.has_alpha,
1293 EVAS_COLORSPACE_ARGB8888);
1294 if (im)
1295 {
1296 if (o->cur.cspace == EVAS_COLORSPACE_ARGB8888)
1297 im->image.data = data;
1298 else
1299 im->image.data = evas_object_image_data_convert_internal(o,
1300 data,
1301 EVAS_COLORSPACE_ARGB8888);
1302 if (im->image.data)
1303 {
1304 ok = evas_common_save_image_to_file(im, file, key, quality, compress);
1305
1306 if (o->cur.cspace != EVAS_COLORSPACE_ARGB8888)
1307 free(im->image.data);
1308 }
1309
1310 evas_cache_image_drop(&im->cache_entry);
1311 }
1312 return ok;
1313}
1314
1315EAPI Eina_Bool
1316evas_object_image_pixels_import(Evas_Object *obj, Evas_Pixel_Import_Source *pixels)
1317{
1318 Evas_Object_Image *o;
1319
1320 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1321 return 0;
1322 MAGIC_CHECK_END();
1323 o = (Evas_Object_Image *)(obj->object_data);
1324 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1325 return 0;
1326 MAGIC_CHECK_END();
1327 _evas_object_image_cleanup(obj, o);
1328 if ((pixels->w != o->cur.image.w) || (pixels->h != o->cur.image.h)) return 0;
1329 switch (pixels->format)
1330 {
1331#if 0
1332 case EVAS_PIXEL_FORMAT_ARGB32:
1333 {
1334 if (o->engine_data)
1335 {
1336 DATA32 *image_pixels = NULL;
1337
1338 o->engine_data =
1339 obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1340 o->engine_data,
1341 1,
1342 &image_pixels,
1343 &o->load_error);
1344/* FIXME: need to actualyl support this */
1345/* memcpy(image_pixels, pixels->rows, o->cur.image.w * o->cur.image.h * 4);*/
1346 if (o->engine_data)
1347 o->engine_data =
1348 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
1349 o->engine_data,
1350 image_pixels);
1351 if (o->engine_data)
1352 o->engine_data =
1353 obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1354 o->engine_data,
1355 o->cur.has_alpha);
1356 o->changed = 1;
1357 evas_object_change(obj);
1358 }
1359 }
1360 break;
1361#endif
1362#ifdef BUILD_CONVERT_YUV
1363 case EVAS_PIXEL_FORMAT_YUV420P_601:
1364 {
1365 if (o->engine_data)
1366 {
1367 DATA32 *image_pixels = NULL;
1368
1369 o->engine_data =
1370 obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
1371 o->engine_data,
1372 1,
1373 &image_pixels,
1374 &o->load_error);
1375 if (image_pixels)
1376 evas_common_convert_yuv_420p_601_rgba((DATA8 **) pixels->rows,
1377 (DATA8 *) image_pixels,
1378 o->cur.image.w,
1379 o->cur.image.h);
1380 if (o->engine_data)
1381 o->engine_data =
1382 obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
1383 o->engine_data,
1384 image_pixels);
1385 if (o->engine_data)
1386 o->engine_data =
1387 obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
1388 o->engine_data,
1389 o->cur.has_alpha);
1390 o->changed = 1;
1391 evas_object_change(obj);
1392 }
1393 }
1394 break;
1395#endif
1396 default:
1397 return 0;
1398 break;
1399 }
1400 return 1;
1401}
1402
1403EAPI void
1404evas_object_image_pixels_get_callback_set(Evas_Object *obj, Evas_Object_Image_Pixels_Get_Cb func, void *data)
1405{
1406 Evas_Object_Image *o;
1407
1408 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1409 return;
1410 MAGIC_CHECK_END();
1411 o = (Evas_Object_Image *)(obj->object_data);
1412 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1413 return;
1414 MAGIC_CHECK_END();
1415 o->func.get_pixels = func;
1416 o->func.get_pixels_data = data;
1417}
1418
1419EAPI void
1420evas_object_image_pixels_dirty_set(Evas_Object *obj, Eina_Bool dirty)
1421{
1422 Evas_Object_Image *o;
1423
1424 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1425 return;
1426 MAGIC_CHECK_END();
1427 o = (Evas_Object_Image *)(obj->object_data);
1428 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1429 return;
1430 MAGIC_CHECK_END();
1431 if (dirty) o->dirty_pixels = 1;
1432 else o->dirty_pixels = 0;
1433 o->changed = 1;
1434 evas_object_change(obj);
1435}
1436
1437EAPI Eina_Bool
1438evas_object_image_pixels_dirty_get(const Evas_Object *obj)
1439{
1440 Evas_Object_Image *o;
1441
1442 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1443 return 0;
1444 MAGIC_CHECK_END();
1445 o = (Evas_Object_Image *)(obj->object_data);
1446 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1447 return 0;
1448 MAGIC_CHECK_END();
1449 if (o->dirty_pixels) return 1;
1450 return 0;
1451}
1452
1453EAPI void
1454evas_object_image_load_dpi_set(Evas_Object *obj, double dpi)
1455{
1456 Evas_Object_Image *o;
1457
1458 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1459 return;
1460 MAGIC_CHECK_END();
1461 o = (Evas_Object_Image *)(obj->object_data);
1462 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1463 return;
1464 MAGIC_CHECK_END();
1465 if (dpi == o->load_opts.dpi) return;
1466 o->load_opts.dpi = dpi;
1467 if (o->cur.file)
1468 {
1469 evas_object_image_unload(obj, 0);
1470 evas_object_inform_call_image_unloaded(obj);
1471 evas_object_image_load(obj);
1472 o->changed = 1;
1473 evas_object_change(obj);
1474 }
1475}
1476
1477EAPI double
1478evas_object_image_load_dpi_get(const Evas_Object *obj)
1479{
1480 Evas_Object_Image *o;
1481
1482 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1483 return 0.0;
1484 MAGIC_CHECK_END();
1485 o = (Evas_Object_Image *)(obj->object_data);
1486 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1487 return 0.0;
1488 MAGIC_CHECK_END();
1489 return o->load_opts.dpi;
1490}
1491
1492EAPI void
1493evas_object_image_load_size_set(Evas_Object *obj, int w, int h)
1494{
1495 Evas_Object_Image *o;
1496
1497 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1498 return;
1499 MAGIC_CHECK_END();
1500 o = (Evas_Object_Image *)(obj->object_data);
1501 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1502 return;
1503 MAGIC_CHECK_END();
1504 if ((o->load_opts.w == w) && (o->load_opts.h == h)) return;
1505 o->load_opts.w = w;
1506 o->load_opts.h = h;
1507 if (o->cur.file)
1508 {
1509 evas_object_image_unload(obj, 0);
1510 evas_object_inform_call_image_unloaded(obj);
1511 evas_object_image_load(obj);
1512 o->changed = 1;
1513 evas_object_change(obj);
1514 }
1515}
1516
1517EAPI void
1518evas_object_image_load_size_get(const Evas_Object *obj, int *w, int *h)
1519{
1520 Evas_Object_Image *o;
1521
1522 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1523 return;
1524 MAGIC_CHECK_END();
1525 o = (Evas_Object_Image *)(obj->object_data);
1526 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1527 return;
1528 MAGIC_CHECK_END();
1529 if (w) *w = o->load_opts.w;
1530 if (h) *h = o->load_opts.h;
1531}
1532
1533EAPI void
1534evas_object_image_load_scale_down_set(Evas_Object *obj, int scale_down)
1535{
1536 Evas_Object_Image *o;
1537
1538 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1539 return;
1540 MAGIC_CHECK_END();
1541 o = (Evas_Object_Image *)(obj->object_data);
1542 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1543 return;
1544 MAGIC_CHECK_END();
1545 if (o->load_opts.scale_down_by == scale_down) return;
1546 o->load_opts.scale_down_by = scale_down;
1547 if (o->cur.file)
1548 {
1549 evas_object_image_unload(obj, 0);
1550 evas_object_inform_call_image_unloaded(obj);
1551 evas_object_image_load(obj);
1552 o->changed = 1;
1553 evas_object_change(obj);
1554 }
1555}
1556
1557EAPI int
1558evas_object_image_load_scale_down_get(const Evas_Object *obj)
1559{
1560 Evas_Object_Image *o;
1561
1562 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1563 return 0;
1564 MAGIC_CHECK_END();
1565 o = (Evas_Object_Image *)(obj->object_data);
1566 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1567 return 0;
1568 MAGIC_CHECK_END();
1569 return o->load_opts.scale_down_by;
1570}
1571
1572EAPI void
1573evas_object_image_load_region_set(Evas_Object *obj, int x, int y, int w, int h)
1574{
1575 Evas_Object_Image *o;
1576
1577 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1578 return;
1579 MAGIC_CHECK_END();
1580 o = (Evas_Object_Image *)(obj->object_data);
1581 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1582 return;
1583 MAGIC_CHECK_END();
1584 if ((o->load_opts.region.x == x) && (o->load_opts.region.y == y) &&
1585 (o->load_opts.region.w == w) && (o->load_opts.region.h == h)) return;
1586 o->load_opts.region.x = x;
1587 o->load_opts.region.y = y;
1588 o->load_opts.region.w = w;
1589 o->load_opts.region.h = h;
1590 if (o->cur.file)
1591 {
1592 evas_object_image_unload(obj, 0);
1593 evas_object_inform_call_image_unloaded(obj);
1594 evas_object_image_load(obj);
1595 o->changed = 1;
1596 evas_object_change(obj);
1597 }
1598}
1599
1600EAPI void
1601evas_object_image_load_region_get(const Evas_Object *obj, int *x, int *y, int *w, int *h)
1602{
1603 Evas_Object_Image *o;
1604
1605 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1606 return;
1607 MAGIC_CHECK_END();
1608 o = (Evas_Object_Image *)(obj->object_data);
1609 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1610 return;
1611 MAGIC_CHECK_END();
1612 if (x) *x = o->load_opts.region.x;
1613 if (y) *y = o->load_opts.region.y;
1614 if (w) *w = o->load_opts.region.w;
1615 if (h) *h = o->load_opts.region.h;
1616}
1617
1618EAPI void
1619evas_object_image_load_orientation_set(Evas_Object *obj, Eina_Bool enable)
1620{
1621 Evas_Object_Image *o;
1622
1623 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1624 return;
1625 MAGIC_CHECK_END();
1626 o = (Evas_Object_Image *)(obj->object_data);
1627 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1628 return;
1629 MAGIC_CHECK_END();
1630 o->load_opts.orientation = !!enable;
1631}
1632
1633EAPI Eina_Bool
1634evas_object_image_load_orientation_get(const Evas_Object *obj)
1635{
1636 Evas_Object_Image *o;
1637
1638 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1639 return EINA_FALSE;
1640 MAGIC_CHECK_END();
1641 o = (Evas_Object_Image *)(obj->object_data);
1642 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1643 return EINA_FALSE;
1644 MAGIC_CHECK_END();
1645 return o->load_opts.orientation;
1646}
1647
1648EAPI void
1649evas_object_image_colorspace_set(Evas_Object *obj, Evas_Colorspace cspace)
1650{
1651 Evas_Object_Image *o;
1652
1653 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1654 return;
1655 MAGIC_CHECK_END();
1656 o = (Evas_Object_Image *)(obj->object_data);
1657 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1658 return;
1659 MAGIC_CHECK_END();
1660
1661 _evas_object_image_cleanup(obj, o);
1662#ifdef EVAS_FRAME_QUEUING
1663 if ((Evas_Colorspace)o->cur.cspace != cspace)
1664 {
1665 if (o->engine_data)
1666 evas_common_pipe_op_image_flush(o->engine_data);
1667 }
1668#endif
1669
1670 o->cur.cspace = cspace;
1671 if (o->engine_data)
1672 obj->layer->evas->engine.func->image_colorspace_set(obj->layer->evas->engine.data.output,
1673 o->engine_data,
1674 cspace);
1675}
1676
1677EAPI Evas_Colorspace
1678evas_object_image_colorspace_get(const Evas_Object *obj)
1679{
1680 Evas_Object_Image *o;
1681
1682 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1683 return EVAS_COLORSPACE_ARGB8888;
1684 MAGIC_CHECK_END();
1685 o = (Evas_Object_Image *)(obj->object_data);
1686 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1687 return EVAS_COLORSPACE_ARGB8888;
1688 MAGIC_CHECK_END();
1689 return o->cur.cspace;
1690}
1691
1692EAPI void
1693evas_object_image_video_surface_set(Evas_Object *obj, Evas_Video_Surface *surf)
1694{
1695 Evas_Object_Image *o;
1696
1697 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1698 return;
1699 MAGIC_CHECK_END();
1700 o = (Evas_Object_Image *)(obj->object_data);
1701 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1702 return;
1703 MAGIC_CHECK_END();
1704 _evas_object_image_cleanup(obj, o);
1705 if (o->video_surface)
1706 {
1707 o->video_surface = 0;
1708 obj->layer->evas->video_objects = eina_list_remove(obj->layer->evas->video_objects, obj);
1709 }
1710
1711 if (surf)
1712 {
1713 if (surf->version != EVAS_VIDEO_SURFACE_VERSION) return ;
1714
1715 if (!surf->update_pixels ||
1716 !surf->move ||
1717 !surf->resize ||
1718 !surf->hide ||
1719 !surf->show)
1720 return ;
1721
1722 o->created = EINA_TRUE;
1723 o->video_surface = 1;
1724 o->video = *surf;
1725
1726 obj->layer->evas->video_objects = eina_list_append(obj->layer->evas->video_objects, obj);
1727 }
1728 else
1729 {
1730 o->video_surface = 0;
1731 o->video.update_pixels = NULL;
1732 o->video.move = NULL;
1733 o->video.resize = NULL;
1734 o->video.hide = NULL;
1735 o->video.show = NULL;
1736 o->video.data = NULL;
1737 }
1738}
1739
1740EAPI const Evas_Video_Surface *
1741evas_object_image_video_surface_get(const Evas_Object *obj)
1742{
1743 Evas_Object_Image *o;
1744
1745 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1746 return NULL;
1747 MAGIC_CHECK_END();
1748 o = (Evas_Object_Image *)(obj->object_data);
1749 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1750 return NULL;
1751 MAGIC_CHECK_END();
1752 if (!o->video_surface) return NULL;
1753 return &o->video;
1754}
1755
1756EAPI void
1757evas_object_image_native_surface_set(Evas_Object *obj, Evas_Native_Surface *surf)
1758{
1759 Evas_Object_Image *o;
1760
1761 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1762 return;
1763 MAGIC_CHECK_END();
1764 o = (Evas_Object_Image *)(obj->object_data);
1765 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1766 return;
1767 MAGIC_CHECK_END();
1768 _evas_object_image_cleanup(obj, o);
1769 if (!obj->layer->evas->engine.func->image_native_set) return;
1770 if ((surf) &&
1771 ((surf->version < 2) ||
1772 (surf->version > EVAS_NATIVE_SURFACE_VERSION))) return;
1773 o->engine_data =
1774 obj->layer->evas->engine.func->image_native_set(obj->layer->evas->engine.data.output,
1775 o->engine_data,
1776 surf);
1777}
1778
1779EAPI Evas_Native_Surface *
1780evas_object_image_native_surface_get(const Evas_Object *obj)
1781{
1782 Evas_Object_Image *o;
1783
1784 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1785 return NULL;
1786 MAGIC_CHECK_END();
1787 o = (Evas_Object_Image *)(obj->object_data);
1788 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1789 return NULL;
1790 MAGIC_CHECK_END();
1791 if (!obj->layer->evas->engine.func->image_native_get) return NULL;
1792 return obj->layer->evas->engine.func->image_native_get(obj->layer->evas->engine.data.output,
1793 o->engine_data);
1794}
1795
1796EAPI void
1797evas_object_image_scale_hint_set(Evas_Object *obj, Evas_Image_Scale_Hint hint)
1798{
1799 Evas_Object_Image *o;
1800
1801 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1802 return;
1803 MAGIC_CHECK_END();
1804 o = (Evas_Object_Image *)(obj->object_data);
1805 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1806 return;
1807 MAGIC_CHECK_END();
1808 if (o->scale_hint == hint) return;
1809#ifdef EVAS_FRAME_QUEUING
1810 if (o->engine_data)
1811 evas_common_pipe_op_image_flush(o->engine_data);
1812#endif
1813 o->scale_hint = hint;
1814 if (o->engine_data)
1815 {
1816 int stride = 0;
1817
1818 if (obj->layer->evas->engine.func->image_scale_hint_set)
1819 obj->layer->evas->engine.func->image_scale_hint_set
1820 (obj->layer->evas->engine.data.output,
1821 o->engine_data, o->scale_hint);
1822 if (obj->layer->evas->engine.func->image_stride_get)
1823 obj->layer->evas->engine.func->image_stride_get
1824 (obj->layer->evas->engine.data.output,
1825 o->engine_data, &stride);
1826 else
1827 stride = o->cur.image.w * 4;
1828 o->cur.image.stride = stride;
1829 }
1830}
1831
1832EAPI Evas_Image_Scale_Hint
1833evas_object_image_scale_hint_get(const Evas_Object *obj)
1834{
1835 Evas_Object_Image *o;
1836
1837 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1838 return EVAS_IMAGE_SCALE_HINT_NONE;
1839 MAGIC_CHECK_END();
1840 o = (Evas_Object_Image *)(obj->object_data);
1841 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1842 return EVAS_IMAGE_SCALE_HINT_NONE;
1843 MAGIC_CHECK_END();
1844 return o->scale_hint;
1845}
1846
1847EAPI void
1848evas_object_image_content_hint_set(Evas_Object *obj, Evas_Image_Content_Hint hint)
1849{
1850 Evas_Object_Image *o;
1851
1852 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1853 return;
1854 MAGIC_CHECK_END();
1855 o = (Evas_Object_Image *)(obj->object_data);
1856 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1857 return;
1858 MAGIC_CHECK_END();
1859 if (o->content_hint == hint) return;
1860#ifdef EVAS_FRAME_QUEUING
1861 if (o->engine_data)
1862 evas_common_pipe_op_image_flush(o->engine_data);
1863#endif
1864 o->content_hint = hint;
1865 if (o->engine_data)
1866 {
1867 int stride = 0;
1868
1869 if (obj->layer->evas->engine.func->image_content_hint_set)
1870 obj->layer->evas->engine.func->image_content_hint_set
1871 (obj->layer->evas->engine.data.output,
1872 o->engine_data, o->content_hint);
1873 if (obj->layer->evas->engine.func->image_stride_get)
1874 obj->layer->evas->engine.func->image_stride_get
1875 (obj->layer->evas->engine.data.output,
1876 o->engine_data, &stride);
1877 else
1878 stride = o->cur.image.w * 4;
1879 o->cur.image.stride = stride;
1880 }
1881}
1882
1883EAPI void
1884evas_object_image_alpha_mask_set(Evas_Object *obj, Eina_Bool ismask)
1885{
1886 Evas_Object_Image *o;
1887
1888 if (!ismask) return;
1889
1890 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1891 return;
1892 MAGIC_CHECK_END();
1893 o = (Evas_Object_Image *)(obj->object_data);
1894 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1895 return;
1896 MAGIC_CHECK_END();
1897
1898 /* Convert to A8 if not already */
1899
1900 /* done */
1901
1902}
1903
1904#define FRAME_MAX 1024
1905EAPI Evas_Image_Content_Hint
1906evas_object_image_content_hint_get(const Evas_Object *obj)
1907{
1908 Evas_Object_Image *o;
1909
1910 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1911 return EVAS_IMAGE_CONTENT_HINT_NONE;
1912 MAGIC_CHECK_END();
1913 o = (Evas_Object_Image *)(obj->object_data);
1914 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1915 return EVAS_IMAGE_CONTENT_HINT_NONE;
1916 MAGIC_CHECK_END();
1917 return o->content_hint;
1918}
1919
1920/* animated feature */
1921EAPI Eina_Bool
1922evas_object_image_animated_get(const Evas_Object *obj)
1923{
1924 Evas_Object_Image *o;
1925
1926 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1927 return EINA_FALSE;
1928 MAGIC_CHECK_END();
1929 o = (Evas_Object_Image *)(obj->object_data);
1930 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1931 return EINA_FALSE;
1932 MAGIC_CHECK_END();
1933
1934 if (obj->layer->evas->engine.func->image_animated_get)
1935 return obj->layer->evas->engine.func->image_animated_get(obj->layer->evas->engine.data.output, o->engine_data);
1936 return EINA_FALSE;
1937}
1938
1939EAPI int
1940evas_object_image_animated_frame_count_get(const Evas_Object *obj)
1941{
1942 Evas_Object_Image *o;
1943
1944 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1945 return -1;
1946 MAGIC_CHECK_END();
1947 o = (Evas_Object_Image *)(obj->object_data);
1948 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1949 return -1;
1950 MAGIC_CHECK_END();
1951
1952 if (!evas_object_image_animated_get(obj)) return -1;
1953 if (obj->layer->evas->engine.func->image_animated_frame_count_get)
1954 return obj->layer->evas->engine.func->image_animated_frame_count_get(obj->layer->evas->engine.data.output, o->engine_data);
1955 return -1;
1956}
1957
1958EAPI Evas_Image_Animated_Loop_Hint
1959evas_object_image_animated_loop_type_get(const Evas_Object *obj)
1960{
1961 Evas_Object_Image *o;
1962
1963 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1964 return EVAS_IMAGE_ANIMATED_HINT_NONE;
1965 MAGIC_CHECK_END();
1966 o = (Evas_Object_Image *)(obj->object_data);
1967 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1968 return EVAS_IMAGE_ANIMATED_HINT_NONE;
1969 MAGIC_CHECK_END();
1970
1971 if (!evas_object_image_animated_get(obj)) return EVAS_IMAGE_ANIMATED_HINT_NONE;
1972
1973 if (obj->layer->evas->engine.func->image_animated_loop_type_get)
1974 return obj->layer->evas->engine.func->image_animated_loop_type_get(obj->layer->evas->engine.data.output, o->engine_data);
1975 return EVAS_IMAGE_ANIMATED_HINT_NONE;
1976}
1977
1978EAPI int
1979evas_object_image_animated_loop_count_get(const Evas_Object *obj)
1980{
1981 Evas_Object_Image *o;
1982
1983 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1984 return -1;
1985 MAGIC_CHECK_END();
1986 o = (Evas_Object_Image *)(obj->object_data);
1987 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
1988 return -1;
1989 MAGIC_CHECK_END();
1990
1991 if (!evas_object_image_animated_get(obj)) return -1;
1992
1993 if (obj->layer->evas->engine.func->image_animated_loop_count_get)
1994 return obj->layer->evas->engine.func->image_animated_loop_count_get(obj->layer->evas->engine.data.output, o->engine_data);
1995 return -1;
1996}
1997
1998EAPI double
1999evas_object_image_animated_frame_duration_get(const Evas_Object *obj, int start_frame, int frame_num)
2000{
2001 Evas_Object_Image *o;
2002 int frame_count = 0;
2003
2004 if (start_frame < 1) return -1;
2005 if (frame_num < 0) return -1;
2006
2007 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2008 return -1;
2009 MAGIC_CHECK_END();
2010 o = (Evas_Object_Image *)(obj->object_data);
2011 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2012 return -1;
2013 MAGIC_CHECK_END();
2014
2015 if (!evas_object_image_animated_get(obj)) return -1;
2016
2017 if (!obj->layer->evas->engine.func->image_animated_frame_count_get) return -1;
2018
2019 frame_count = obj->layer->evas->engine.func->image_animated_frame_count_get(obj->layer->evas->engine.data.output, o->engine_data);
2020
2021 if ((start_frame + frame_num) > frame_count) return -1;
2022 if (obj->layer->evas->engine.func->image_animated_frame_duration_get)
2023 return obj->layer->evas->engine.func->image_animated_frame_duration_get(obj->layer->evas->engine.data.output, o->engine_data, start_frame, frame_num);
2024 return -1;
2025}
2026
2027EAPI void
2028evas_object_image_animated_frame_set(Evas_Object *obj, int frame_index)
2029{
2030 Evas_Object_Image *o;
2031 int frame_count = 0;
2032
2033 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
2034 return;
2035 MAGIC_CHECK_END();
2036 o = (Evas_Object_Image *)(obj->object_data);
2037 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2038 return;
2039 MAGIC_CHECK_END();
2040
2041 if (!o->cur.file) return;
2042 if (o->cur.frame == frame_index) return;
2043
2044 if (!evas_object_image_animated_get(obj)) return;
2045
2046 frame_count = evas_object_image_animated_frame_count_get(obj);
2047
2048 /* limit the size of frame to FRAME_MAX */
2049 if ((frame_count > FRAME_MAX) || (frame_count < 0) || (frame_index > frame_count))
2050 return;
2051
2052 if (!obj->layer->evas->engine.func->image_animated_frame_set) return;
2053 if (!obj->layer->evas->engine.func->image_animated_frame_set(obj->layer->evas->engine.data.output, o->engine_data, frame_index))
2054 return;
2055
2056 o->prev.frame = o->cur.frame;
2057 o->cur.frame = frame_index;
2058
2059 o->changed = 1;
2060 evas_object_change(obj);
2061
2062}
2063
2064EAPI void
2065evas_image_cache_flush(Evas *e)
2066{
2067 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2068 return;
2069 MAGIC_CHECK_END();
2070
2071 e->engine.func->image_cache_flush(e->engine.data.output);
2072}
2073
2074EAPI void
2075evas_image_cache_reload(Evas *e)
2076{
2077 Evas_Layer *layer;
2078
2079 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2080 return;
2081 MAGIC_CHECK_END();
2082
2083 evas_image_cache_flush(e);
2084 EINA_INLIST_FOREACH(e->layers, layer)
2085 {
2086 Evas_Object *obj;
2087
2088 EINA_INLIST_FOREACH(layer->objects, obj)
2089 {
2090 Evas_Object_Image *o;
2091
2092 o = (Evas_Object_Image *)(obj->object_data);
2093 if (o->magic == MAGIC_OBJ_IMAGE)
2094 {
2095 evas_object_image_unload(obj, 1);
2096 evas_object_inform_call_image_unloaded(obj);
2097 }
2098 }
2099 }
2100 evas_image_cache_flush(e);
2101 EINA_INLIST_FOREACH(e->layers, layer)
2102 {
2103 Evas_Object *obj;
2104
2105 EINA_INLIST_FOREACH(layer->objects, obj)
2106 {
2107 Evas_Object_Image *o;
2108
2109 o = (Evas_Object_Image *)(obj->object_data);
2110 if (o->magic == MAGIC_OBJ_IMAGE)
2111 {
2112 evas_object_image_load(obj);
2113 o->changed = 1;
2114 evas_object_change(obj);
2115 }
2116 }
2117 }
2118 evas_image_cache_flush(e);
2119}
2120
2121EAPI void
2122evas_image_cache_set(Evas *e, int size)
2123{
2124 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2125 return;
2126 MAGIC_CHECK_END();
2127
2128 if (size < 0) size = 0;
2129 e->engine.func->image_cache_set(e->engine.data.output, size);
2130}
2131
2132EAPI int
2133evas_image_cache_get(const Evas *e)
2134{
2135 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2136 return 0;
2137 MAGIC_CHECK_END();
2138
2139 return e->engine.func->image_cache_get(e->engine.data.output);
2140}
2141
2142EAPI Eina_Bool
2143evas_image_max_size_get(const Evas *e, int *maxw, int *maxh)
2144{
2145 int w = 0, h = 0;
2146 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
2147 return EINA_FALSE;
2148 MAGIC_CHECK_END();
2149
2150 if (maxw) *maxw = 0xffff;
2151 if (maxh) *maxh = 0xffff;
2152 if (!e->engine.func->image_max_size_get) return EINA_FALSE;
2153 e->engine.func->image_max_size_get(e->engine.data.output, &w, &h);
2154 if (maxw) *maxw = w;
2155 if (maxh) *maxh = h;
2156 return EINA_TRUE;
2157}
2158
2159/* all nice and private */
2160static void
2161_proxy_unset(Evas_Object *proxy)
2162{
2163 Evas_Object_Image *o;
2164
2165 o = proxy->object_data;
2166 if (!o->cur.source) return;
2167
2168 o->cur.source->proxy.proxies = eina_list_remove(o->cur.source->proxy.proxies, proxy);
2169
2170 o->cur.source = NULL;
2171 if (o->cur.defmap)
2172 {
2173 evas_map_free(o->cur.defmap);
2174 o->cur.defmap = NULL;
2175 }
2176}
2177
2178
2179static void
2180_proxy_set(Evas_Object *proxy, Evas_Object *src)
2181{
2182 Evas_Object_Image *o;
2183
2184 o = proxy->object_data;
2185
2186 evas_object_image_file_set(proxy, NULL, NULL);
2187
2188 o->cur.source = src;
2189
2190 src->proxy.proxies = eina_list_append(src->proxy.proxies, proxy);
2191 src->proxy.redraw = EINA_TRUE;
2192}
2193
2194/* Some moron just set a proxy on a proxy.
2195 * Give them some pixels. A random color
2196 */
2197static void
2198_proxy_error(Evas_Object *proxy, void *context, void *output, void *surface,
2199 int x, int y)
2200{
2201 Evas_Func *func;
2202 int r = rand() % 255;
2203 int g = rand() % 255;
2204 int b = rand() % 255;
2205
2206 /* XXX: Eina log error or something I'm sure
2207 * If it bugs you, just fix it. Don't tell me */
2208 if (VERBOSE_PROXY_ERROR) printf("Err: Argh! Recursive proxies.\n");
2209
2210 func = proxy->layer->evas->engine.func;
2211 func->context_color_set(output, context, r, g, b, 255);
2212 func->context_multiplier_unset(output, context);
2213 func->context_render_op_set(output, context, proxy->cur.render_op);
2214 func->rectangle_draw(output, context, surface, proxy->cur.geometry.x + x,
2215 proxy->cur.geometry.y + y,
2216 proxy->cur.geometry.w,
2217 proxy->cur.geometry.h);
2218 return;
2219}
2220
2221/*
2222static void
2223_proxy_subrender_recurse(Evas_Object *obj, Evas_Object *clip, void *output, void *surface, void *ctx, int x, int y)
2224{
2225 Evas_Object *obj2;
2226 Evas *e = obj->layer->evas;
2227
2228 if (obj->clip.clipees) return;
2229 if (!obj->cur.visible) return;
2230 if ((!clip) || (clip != obj->cur.clipper))
2231 {
2232 if (!obj->cur.cache.clip.visible) return;
2233 if ((obj->cur.cache.clip.a == 0) &&
2234 (obj->cur.render_op == EVAS_RENDER_BLEND)) return;
2235 }
2236 if ((obj->func->is_visible) && (!obj->func->is_visible(obj))) return;
2237
2238 if (!obj->pre_render_done)
2239 obj->func->render_pre(obj);
2240 ctx = e->engine.func->context_new(output);
2241 if (obj->smart.smart)
2242 {
2243 EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
2244 {
2245 _proxy_subrender_recurse(obj2, clip, output, surface, ctx, x, y);
2246 }
2247 }
2248 else
2249 {
2250 obj->func->render(obj, output, ctx, surface, x, y);
2251 }
2252 e->engine.func->context_free(output, ctx);
2253}
2254*/
2255
2256/**
2257 * Render the source object when a proxy is set.
2258 *
2259 * Used to force a draw if necessary, else just makes sures it's available.
2260 */
2261static void
2262_proxy_subrender(Evas *e, Evas_Object *source)
2263{
2264 void *ctx;
2265/* Evas_Object *obj2, *clip;*/
2266 int w, h;
2267
2268 if (!source) return;
2269
2270 w = source->cur.geometry.w;
2271 h = source->cur.geometry.h;
2272
2273 source->proxy.redraw = EINA_FALSE;
2274
2275 /* We need to redraw surface then */
2276 if ((source->proxy.surface) &&
2277 ((source->proxy.w != w) || (source->proxy.h != h)))
2278 {
2279 e->engine.func->image_map_surface_free(e->engine.data.output,
2280 source->proxy.surface);
2281 source->proxy.surface = NULL;
2282 }
2283
2284 /* FIXME: Hardcoded alpha 'on' */
2285 /* FIXME (cont): Should see if the object has alpha */
2286 if (!source->proxy.surface)
2287 {
2288 source->proxy.surface = e->engine.func->image_map_surface_new
2289 (e->engine.data.output, w, h, 1);
2290 source->proxy.w = w;
2291 source->proxy.h = h;
2292 }
2293
2294 ctx = e->engine.func->context_new(e->engine.data.output);
2295 e->engine.func->context_color_set(e->engine.data.output, ctx, 0, 0, 0, 0);
2296 e->engine.func->context_render_op_set(e->engine.data.output, ctx, EVAS_RENDER_COPY);
2297 e->engine.func->rectangle_draw(e->engine.data.output, ctx,
2298 source->proxy.surface, 0, 0, w, h);
2299 e->engine.func->context_free(e->engine.data.output, ctx);
2300
2301 ctx = e->engine.func->context_new(e->engine.data.output);
2302 evas_render_mapped(e, source, ctx, source->proxy.surface,
2303 -source->cur.geometry.x,
2304 -source->cur.geometry.y,
2305 1, 0, 0, e->output.w, e->output.h);
2306 e->engine.func->context_free(e->engine.data.output, ctx);
2307 source->proxy.surface = e->engine.func->image_dirty_region
2308 (e->engine.data.output, source->proxy.surface, 0, 0, w, h);
2309/*
2310 ctx = e->engine.func->context_new(e->engine.data.output);
2311 if (source->smart.smart)
2312 {
2313 clip = evas_object_smart_clipped_clipper_get(source);
2314 EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(source), obj2)
2315 {
2316 _proxy_subrender_recurse(obj2, clip, e->engine.data.output,
2317 source->proxy.surface,
2318 ctx,
2319 -source->cur.geometry.x,
2320 -source->cur.geometry.y);
2321 }
2322 }
2323 else
2324 {
2325 if (!source->pre_render_done)
2326 source->func->render_pre(source);
2327 source->func->render(source, e->engine.data.output, ctx,
2328 source->proxy.surface,
2329 -source->cur.geometry.x,
2330 -source->cur.geometry.y);
2331 }
2332
2333 e->engine.func->context_free(e->engine.data.output, ctx);
2334 source->proxy.surface = e->engine.func->image_dirty_region
2335 (e->engine.data.output, source->proxy.surface, 0, 0, w, h);
2336 */
2337}
2338
2339#if 0 // filtering disabled
2340/*
2341 *
2342 * Note that this is similar to proxy_subrender_recurse. It should be
2343 * possible to merge I guess
2344 */
2345static void
2346image_filter_draw_under_recurse(Evas *e, Evas_Object *obj, Evas_Object *stop,
2347 void *output, void *ctx, void *surface,
2348 int x, int y)
2349{
2350 Evas_Object *obj2;
2351
2352 if (obj->clip.clipees) return;
2353 /* FIXME: Doing bounding box test */
2354 if (!evas_object_is_in_output_rect(obj, stop->cur.geometry.x,
2355 stop->cur.geometry.y,
2356 stop->cur.geometry.w,
2357 stop->cur.geometry.h))
2358 return;
2359
2360 if (!evas_object_is_visible(obj)) return;
2361 obj->pre_render_done = 1;
2362 ctx = e->engine.func->context_new(output);
2363
2364 if (obj->smart.smart)
2365 {
2366 EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
2367 {
2368 if (obj2 == stop) return;
2369 image_filter_draw_under_recurse(e, obj2, stop, output, surface,
2370 ctx, x, y);
2371 }
2372 }
2373 else
2374 obj->func->render(obj, output, ctx, surface, x ,y);
2375 e->engine.func->context_free(output, ctx);
2376}
2377
2378/*
2379 * Draw all visible objects intersecting an object which are _beneath_ it.
2380 */
2381static void
2382image_filter_draw_under(Evas *e, Evas_Object *stop, void *output, void *ctx, void *surface, int dx, int dy)
2383{
2384 Evas_Layer *lay;
2385 int x, y;
2386
2387 x = stop->cur.geometry.x - dx;
2388 y = stop->cur.geometry.y - dy;
2389
2390 EINA_INLIST_FOREACH(e->layers, lay)
2391 {
2392 Evas_Object *obj;
2393 EINA_INLIST_FOREACH(lay->objects, obj)
2394 {
2395 if (obj->delete_me) continue;
2396 if (obj == stop) return;
2397 /* FIXME: Do bounding box check */
2398 image_filter_draw_under_recurse(e, obj, stop, output, ctx,
2399 surface, -x, -y);
2400 }
2401 }
2402 e->engine.func->image_dirty_region(output, surface, 0, 0, 300, 300);
2403 e->engine.func->output_flush(output);
2404}
2405
2406/*
2407 * Update the filtered object.
2408 *
2409 * Creates a new context, and renders stuff (filtered) onto that.
2410 */
2411Filtered_Image *
2412image_filter_update(Evas *e, Evas_Object *obj, void *src, int imagew, int imageh, int *outw, int *outh)
2413{
2414 int w, h;
2415 void *ctx;
2416 Evas_Filter_Info *info;
2417 void *surface;
2418 Eina_Bool alpha;
2419
2420 info = obj->filter;
2421
2422 if (info->mode == EVAS_FILTER_MODE_BELOW)
2423 {
2424 w = obj->cur.geometry.w;
2425 h = obj->cur.geometry.h;
2426 evas_filter_get_size(info, w, h, &imagew, &imageh, EINA_TRUE);
2427 alpha = EINA_FALSE;
2428 }
2429 else
2430 {
2431 evas_filter_get_size(info, imagew, imageh, &w, &h, EINA_FALSE);
2432 alpha = e->engine.func->image_alpha_get(e->engine.data.output, src);
2433 }
2434
2435 /* Certain filters may make alpha images anyway */
2436 if (alpha == EINA_FALSE) alpha = evas_filter_always_alpha(info);
2437
2438 surface = e->engine.func->image_map_surface_new(e->engine.data.output, w, h,
2439 alpha);
2440
2441 if (info->mode == EVAS_FILTER_MODE_BELOW)
2442 {
2443 void *subsurface;
2444 int disw, dish;
2445 int dx, dy;
2446 disw = obj->cur.geometry.w;
2447 dish = obj->cur.geometry.h;
2448 dx = (imagew - w) >> 1;
2449 dy = (imageh - h) >> 1;
2450 subsurface = e->engine.func->image_map_surface_new
2451 (e->engine.data.output, imagew, imageh, 1);
2452 ctx = e->engine.func->context_new(e->engine.data.output);
2453 e->engine.func->context_color_set(e->engine.data.output, ctx, 0, 255, 0, 255);
2454 e->engine.func->context_render_op_set(e->engine.data.output, ctx, EVAS_RENDER_COPY);
2455 e->engine.func->rectangle_draw(e->engine.data.output, ctx,
2456 subsurface, 0, 0, imagew, imageh);
2457
2458 image_filter_draw_under(e, obj, e->engine.data.output, ctx,
2459 subsurface, dx, dy);
2460
2461 e->engine.func->context_free(e->engine.data.output, ctx);
2462
2463 ctx = e->engine.func->context_new(e->engine.data.output);
2464
2465 e->engine.func->image_draw_filtered(e->engine.data.output,
2466 ctx, surface, subsurface, info);
2467
2468 e->engine.func->context_free(e->engine.data.output, ctx);
2469
2470 e->engine.func->image_map_surface_free(e->engine.data.output,
2471 subsurface);
2472 }
2473 else
2474 {
2475 ctx = e->engine.func->context_new(e->engine.data.output);
2476 e->engine.func->image_draw_filtered(e->engine.data.output,
2477 ctx, surface, src, info);
2478 e->engine.func->context_free(e->engine.data.output, ctx);
2479 }
2480
2481 e->engine.func->image_dirty_region(e->engine.data.output, surface,
2482 0, 0, w, h);
2483 if (outw) *outw = w;
2484 if (outh) *outh = h;
2485 return e->engine.func->image_filtered_save(src, surface,
2486 obj->filter->key,
2487 obj->filter->len);
2488}
2489#endif
2490
2491static void
2492evas_object_image_unload(Evas_Object *obj, Eina_Bool dirty)
2493{
2494 Evas_Object_Image *o;
2495
2496 o = (Evas_Object_Image *)(obj->object_data);
2497
2498 if ((!o->cur.file) ||
2499 (o->pixels_checked_out > 0)) return;
2500 if (dirty)
2501 {
2502 if (o->engine_data)
2503 o->engine_data = obj->layer->evas->engine.func->image_dirty_region
2504 (obj->layer->evas->engine.data.output,
2505 o->engine_data,
2506 0, 0,
2507 o->cur.image.w, o->cur.image.h);
2508 }
2509 if (o->engine_data)
2510 {
2511 if (o->preloading)
2512 {
2513 o->preloading = 0;
2514 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
2515 o->engine_data,
2516 obj);
2517 }
2518 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
2519 o->engine_data);
2520 }
2521 o->engine_data = NULL;
2522 o->load_error = EVAS_LOAD_ERROR_NONE;
2523 o->cur.has_alpha = 1;
2524 o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
2525 o->cur.image.w = 0;
2526 o->cur.image.h = 0;
2527 o->cur.image.stride = 0;
2528}
2529
2530static void
2531evas_object_image_load(Evas_Object *obj)
2532{
2533 Evas_Object_Image *o;
2534 Evas_Image_Load_Opts lo;
2535
2536 o = (Evas_Object_Image *)(obj->object_data);
2537 if (o->engine_data) return;
2538
2539 lo.scale_down_by = o->load_opts.scale_down_by;
2540 lo.dpi = o->load_opts.dpi;
2541 lo.w = o->load_opts.w;
2542 lo.h = o->load_opts.h;
2543 lo.region.x = o->load_opts.region.x;
2544 lo.region.y = o->load_opts.region.y;
2545 lo.region.w = o->load_opts.region.w;
2546 lo.region.h = o->load_opts.region.h;
2547 lo.orientation = o->load_opts.orientation;
2548 o->engine_data = obj->layer->evas->engine.func->image_load
2549 (obj->layer->evas->engine.data.output,
2550 o->cur.file,
2551 o->cur.key,
2552 &o->load_error,
2553 &lo);
2554 if (o->engine_data)
2555 {
2556 int w, h;
2557 int stride = 0;
2558
2559 obj->layer->evas->engine.func->image_size_get
2560 (obj->layer->evas->engine.data.output,
2561 o->engine_data, &w, &h);
2562 if (obj->layer->evas->engine.func->image_stride_get)
2563 obj->layer->evas->engine.func->image_stride_get
2564 (obj->layer->evas->engine.data.output,
2565 o->engine_data, &stride);
2566 else
2567 stride = w * 4;
2568 o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get
2569 (obj->layer->evas->engine.data.output,
2570 o->engine_data);
2571 o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get
2572 (obj->layer->evas->engine.data.output,
2573 o->engine_data);
2574 o->cur.image.w = w;
2575 o->cur.image.h = h;
2576 o->cur.image.stride = stride;
2577 }
2578 else
2579 {
2580 o->load_error = EVAS_LOAD_ERROR_GENERIC;
2581 }
2582}
2583
2584static Evas_Coord
2585evas_object_image_figure_x_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret)
2586{
2587 Evas_Coord w;
2588
2589 w = ((size * obj->layer->evas->output.w) /
2590 (Evas_Coord)obj->layer->evas->viewport.w);
2591 if (size <= 0) size = 1;
2592 if (start > 0)
2593 {
2594 while (start - size > 0) start -= size;
2595 }
2596 else if (start < 0)
2597 {
2598 while (start < 0) start += size;
2599 }
2600 start = ((start * obj->layer->evas->output.w) /
2601 (Evas_Coord)obj->layer->evas->viewport.w);
2602 *size_ret = w;
2603 return start;
2604}
2605
2606static Evas_Coord
2607evas_object_image_figure_y_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret)
2608{
2609 Evas_Coord h;
2610
2611 h = ((size * obj->layer->evas->output.h) /
2612 (Evas_Coord)obj->layer->evas->viewport.h);
2613 if (size <= 0) size = 1;
2614 if (start > 0)
2615 {
2616 while (start - size > 0) start -= size;
2617 }
2618 else if (start < 0)
2619 {
2620 while (start < 0) start += size;
2621 }
2622 start = ((start * obj->layer->evas->output.h) /
2623 (Evas_Coord)obj->layer->evas->viewport.h);
2624 *size_ret = h;
2625 return start;
2626}
2627
2628static void
2629evas_object_image_init(Evas_Object *obj)
2630{
2631 /* alloc image ob, setup methods and default values */
2632 obj->object_data = evas_object_image_new();
2633 /* set up default settings for this kind of object */
2634 obj->cur.color.r = 255;
2635 obj->cur.color.g = 255;
2636 obj->cur.color.b = 255;
2637 obj->cur.color.a = 255;
2638 obj->cur.geometry.x = 0;
2639 obj->cur.geometry.y = 0;
2640 obj->cur.geometry.w = 0;
2641 obj->cur.geometry.h = 0;
2642 obj->cur.layer = 0;
2643 obj->cur.anti_alias = 0;
2644 obj->cur.render_op = EVAS_RENDER_BLEND;
2645 /* set up object-specific settings */
2646 obj->prev = obj->cur;
2647 /* set up methods (compulsory) */
2648 obj->func = &object_func;
2649 obj->type = o_type;
2650}
2651
2652static void *
2653evas_object_image_new(void)
2654{
2655 Evas_Object_Image *o;
2656
2657 /* alloc obj private data */
2658 EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_image", Evas_Object_Image, 256, NULL);
2659 o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Image);
2660 if (!o) return NULL;
2661 EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Image);
2662 o->magic = MAGIC_OBJ_IMAGE;
2663 o->cur.fill.w = 0;
2664 o->cur.fill.h = 0;
2665 o->cur.smooth_scale = 1;
2666 o->cur.border.fill = 1;
2667 o->cur.border.scale = 1.0;
2668 o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
2669 o->cur.spread = EVAS_TEXTURE_REPEAT;
2670 o->cur.opaque_valid = 0;
2671 o->cur.source = NULL;
2672 o->prev = o->cur;
2673 o->tmpf_fd = -1;
2674 return o;
2675}
2676
2677static void
2678evas_object_image_free(Evas_Object *obj)
2679{
2680 Evas_Object_Image *o;
2681 Eina_Rectangle *r;
2682
2683 /* frees private object data. very simple here */
2684 o = (Evas_Object_Image *)(obj->object_data);
2685 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
2686 return;
2687 MAGIC_CHECK_END();
2688 /* free obj */
2689 _cleanup_tmpf(obj);
2690 if (o->cur.file) eina_stringshare_del(o->cur.file);
2691 if (o->cur.key) eina_stringshare_del(o->cur.key);
2692 if (o->cur.source) _proxy_unset(obj);
2693 if (o->engine_data)
2694 {
2695 if (o->preloading)
2696 {
2697 o->preloading = 0;
2698 obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
2699 o->engine_data,
2700 obj);
2701 }
2702 obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
2703 o->engine_data);
2704 }
2705 if (o->video_surface)
2706 {
2707 o->video_surface = 0;
2708 obj->layer->evas->video_objects = eina_list_remove(obj->layer->evas->video_objects, obj);
2709 }
2710 o->engine_data = NULL;
2711 o->magic = 0;
2712 EINA_LIST_FREE(o->pixel_updates, r)
2713 eina_rectangle_free(r);
2714 EVAS_MEMPOOL_FREE(_mp_obj, o);
2715}
2716
2717static void
2718evas_object_image_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
2719{
2720 Evas_Object_Image *o;
2721 int imagew, imageh, uvw, uvh;
2722 void *pixels;
2723
2724 /* render object to surface with context, and offset by x,y */
2725 o = (Evas_Object_Image *)(obj->object_data);
2726
2727 if ((o->cur.fill.w < 1) || (o->cur.fill.h < 1))
2728 return; /* no error message, already printed in pre_render */
2729
2730 /* Proxy sanity */
2731 if (o->proxyrendering)
2732 {
2733 _proxy_error(obj, context, output, surface, x, y);
2734 return;
2735 }
2736
2737 /* We are displaying the overlay */
2738 if (o->video_visible)
2739 {
2740 /* Create a transparent rectangle */
2741 obj->layer->evas->engine.func->context_color_set(output,
2742 context,
2743 0, 0, 0, 0);
2744 obj->layer->evas->engine.func->context_multiplier_unset(output,
2745 context);
2746 obj->layer->evas->engine.func->context_render_op_set(output, context,
2747 EVAS_RENDER_COPY);
2748 obj->layer->evas->engine.func->rectangle_draw(output,
2749 context,
2750 surface,
2751 obj->cur.geometry.x + x,
2752 obj->cur.geometry.y + y,
2753 obj->cur.geometry.w,
2754 obj->cur.geometry.h);
2755
2756 return ;
2757 }
2758
2759 obj->layer->evas->engine.func->context_color_set(output,
2760 context,
2761 255, 255, 255, 255);
2762
2763 if ((obj->cur.cache.clip.r == 255) &&
2764 (obj->cur.cache.clip.g == 255) &&
2765 (obj->cur.cache.clip.b == 255) &&
2766 (obj->cur.cache.clip.a == 255))
2767 {
2768 obj->layer->evas->engine.func->context_multiplier_unset(output,
2769 context);
2770 }
2771 else
2772 obj->layer->evas->engine.func->context_multiplier_set(output,
2773 context,
2774 obj->cur.cache.clip.r,
2775 obj->cur.cache.clip.g,
2776 obj->cur.cache.clip.b,
2777 obj->cur.cache.clip.a);
2778
2779 obj->layer->evas->engine.func->context_render_op_set(output, context,
2780 obj->cur.render_op);
2781
2782 if (!o->cur.source)
2783 {
2784 pixels = o->engine_data;
2785 imagew = o->cur.image.w;
2786 imageh = o->cur.image.h;
2787 uvw = imagew;
2788 uvh = imageh;
2789 }
2790 else if (o->cur.source->proxy.surface && !o->cur.source->proxy.redraw)
2791 {
2792 pixels = o->cur.source->proxy.surface;
2793 imagew = o->cur.source->proxy.w;
2794 imageh = o->cur.source->proxy.h;
2795 uvw = imagew;
2796 uvh = imageh;
2797 }
2798 else if (o->cur.source->type == o_type &&
2799 ((Evas_Object_Image *)o->cur.source->object_data)->engine_data)
2800 {
2801 Evas_Object_Image *oi;
2802 oi = o->cur.source->object_data;
2803 pixels = oi->engine_data;
2804 imagew = oi->cur.image.w;
2805 imageh = oi->cur.image.h;
2806 uvw = o->cur.source->cur.geometry.w;
2807 uvh = o->cur.source->cur.geometry.h;
2808 }
2809 else
2810 {
2811 o->proxyrendering = 1;
2812 _proxy_subrender(obj->layer->evas, o->cur.source);
2813 pixels = o->cur.source->proxy.surface;
2814 imagew = o->cur.source->proxy.w;
2815 imageh = o->cur.source->proxy.h;
2816 uvw = imagew;
2817 uvh = imageh;
2818 o->proxyrendering = 0;
2819 }
2820
2821#if 0 // filtering disabled
2822 /* Now check/update filter */
2823 if (obj->filter && obj->filter->filter)
2824 {
2825 Filtered_Image *fi = NULL;
2826 //printf("%p has filter: %s\n", obj,obj->filter->dirty?"dirty":"clean");
2827 if (obj->filter->dirty)
2828 {
2829 if (obj->filter->mode != EVAS_FILTER_MODE_BELOW)
2830 {
2831 uint32_t len;
2832 uint8_t *key;
2833
2834 if (obj->filter->key) free(obj->filter->key);
2835 obj->filter->key = NULL;
2836 obj->filter->len = 0;
2837 key = evas_filter_key_get(obj->filter, &len);
2838 if (key)
2839 {
2840 obj->filter->key = key;
2841 obj->filter->len = len;
2842 fi = obj->layer->evas->engine.func->image_filtered_get
2843 (o->engine_data, key, len);
2844 if (obj->filter->cached && fi != obj->filter->cached)
2845 {
2846 obj->layer->evas->engine.func->image_filtered_free
2847 (o->engine_data, obj->filter->cached);
2848 obj->filter->cached = NULL;
2849 }
2850 }
2851 }
2852 else if (obj->filter->cached)
2853 {
2854 obj->layer->evas->engine.func->image_filtered_free
2855 (o->engine_data, obj->filter->cached);
2856 }
2857 if (!fi)
2858 fi = image_filter_update(obj->layer->evas, obj, pixels,
2859 imagew, imageh, &imagew, &imageh);
2860 pixels = fi->image;
2861 obj->filter->dirty = 0;
2862 obj->filter->cached = fi;
2863 }
2864 else
2865 {
2866 fi = obj->filter->cached;
2867 pixels = fi->image;
2868 }
2869 }
2870#endif
2871
2872 if (pixels)
2873 {
2874 Evas_Coord idw, idh, idx, idy;
2875 int ix, iy, iw, ih;
2876
2877 if (o->dirty_pixels)
2878 {
2879 if (o->func.get_pixels)
2880 {
2881 o->func.get_pixels(o->func.get_pixels_data, obj);
2882 if (o->engine_data != pixels)
2883 pixels = o->engine_data;
2884 o->engine_data = obj->layer->evas->engine.func->image_dirty_region
2885 (obj->layer->evas->engine.data.output, o->engine_data,
2886 0, 0, o->cur.image.w, o->cur.image.h);
2887 }
2888 o->dirty_pixels = 0;
2889 }
2890 if ((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap))
2891 {
2892 const Evas_Map_Point *p, *p_end;
2893 RGBA_Map_Point pts[obj->cur.map->count], *pt;
2894
2895 p = obj->cur.map->points;
2896 p_end = p + obj->cur.map->count;
2897 pt = pts;
2898
2899 pts[0].px = obj->cur.map->persp.px << FP;
2900 pts[0].py = obj->cur.map->persp.py << FP;
2901 pts[0].foc = obj->cur.map->persp.foc << FP;
2902 pts[0].z0 = obj->cur.map->persp.z0 << FP;
2903 // draw geom +x +y
2904 for (; p < p_end; p++, pt++)
2905 {
2906 pt->x = (lround(p->x) + x) * FP1;
2907 pt->y = (lround(p->y) + y) * FP1;
2908 pt->z = (lround(p->z) ) * FP1;
2909 pt->fx = p->px;
2910 pt->fy = p->py;
2911 pt->fz = p->z;
2912 pt->u = ((lround(p->u) * imagew) / uvw) * FP1;
2913 pt->v = ((lround(p->v) * imageh) / uvh) * FP1;
2914 if (pt->u < 0) pt->u = 0;
2915 else if (pt->u > (imagew * FP1)) pt->u = (imagew * FP1);
2916 if (pt->v < 0) pt->v = 0;
2917 else if (pt->v > (imageh * FP1)) pt->v = (imageh * FP1);
2918 pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b);
2919 }
2920 if (obj->cur.map->count & 0x1)
2921 {
2922 pts[obj->cur.map->count] = pts[obj->cur.map->count -1];
2923 }
2924
2925 obj->layer->evas->engine.func->image_map_draw
2926 (output, context, surface, pixels, obj->cur.map->count,
2927 pts, o->cur.smooth_scale | obj->cur.map->smooth, 0);
2928 }
2929 else
2930 {
2931 obj->layer->evas->engine.func->image_scale_hint_set(output,
2932 pixels,
2933 o->scale_hint);
2934 /* This is technically a bug here: If the value is recreated
2935 * (which is returned)it may be a new object, however exactly 0
2936 * of all the evas engines do this. */
2937 obj->layer->evas->engine.func->image_border_set(output, pixels,
2938 o->cur.border.l, o->cur.border.r,
2939 o->cur.border.t, o->cur.border.b);
2940 idx = evas_object_image_figure_x_fill(obj, o->cur.fill.x, o->cur.fill.w, &idw);
2941 idy = evas_object_image_figure_y_fill(obj, o->cur.fill.y, o->cur.fill.h, &idh);
2942 if (idw < 1) idw = 1;
2943 if (idh < 1) idh = 1;
2944 if (idx > 0) idx -= idw;
2945 if (idy > 0) idy -= idh;
2946 while ((int)idx < obj->cur.geometry.w)
2947 {
2948 Evas_Coord ydy;
2949 int dobreak_w = 0;
2950
2951 ydy = idy;
2952 ix = idx;
2953 if ((o->cur.fill.w == obj->cur.geometry.w) &&
2954 (o->cur.fill.x == 0))
2955 {
2956 dobreak_w = 1;
2957 iw = obj->cur.geometry.w;
2958 }
2959 else
2960 iw = ((int)(idx + idw)) - ix;
2961 while ((int)idy < obj->cur.geometry.h)
2962 {
2963 int dobreak_h = 0;
2964
2965 iy = idy;
2966 if ((o->cur.fill.h == obj->cur.geometry.h) &&
2967 (o->cur.fill.y == 0))
2968 {
2969 ih = obj->cur.geometry.h;
2970 dobreak_h = 1;
2971 }
2972 else
2973 ih = ((int)(idy + idh)) - iy;
2974 if ((o->cur.border.l == 0) &&
2975 (o->cur.border.r == 0) &&
2976 (o->cur.border.t == 0) &&
2977 (o->cur.border.b == 0) &&
2978 (o->cur.border.fill != 0))
2979 obj->layer->evas->engine.func->image_draw(output,
2980 context,
2981 surface,
2982 pixels,
2983 0, 0,
2984 imagew,
2985 imageh,
2986 obj->cur.geometry.x + ix + x,
2987 obj->cur.geometry.y + iy + y,
2988 iw, ih,
2989 o->cur.smooth_scale);
2990 else
2991 {
2992 int inx, iny, inw, inh, outx, outy, outw, outh;
2993 int bl, br, bt, bb, bsl, bsr, bst, bsb;
2994 int imw, imh, ox, oy;
2995
2996 ox = obj->cur.geometry.x + ix + x;
2997 oy = obj->cur.geometry.y + iy + y;
2998 imw = imagew;
2999 imh = imageh;
3000 bl = o->cur.border.l;
3001 br = o->cur.border.r;
3002 bt = o->cur.border.t;
3003 bb = o->cur.border.b;
3004 if ((bl + br) > iw)
3005 {
3006 bl = iw / 2;
3007 br = iw - bl;
3008 }
3009 if ((bl + br) > imw)
3010 {
3011 bl = imw / 2;
3012 br = imw - bl;
3013 }
3014 if ((bt + bb) > ih)
3015 {
3016 bt = ih / 2;
3017 bb = ih - bt;
3018 }
3019 if ((bt + bb) > imh)
3020 {
3021 bt = imh / 2;
3022 bb = imh - bt;
3023 }
3024 if (o->cur.border.scale != 1.0)
3025 {
3026 bsl = ((double)bl * o->cur.border.scale);
3027 bsr = ((double)br * o->cur.border.scale);
3028 bst = ((double)bt * o->cur.border.scale);
3029 bsb = ((double)bb * o->cur.border.scale);
3030 }
3031 else
3032 {
3033 bsl = bl; bsr = br; bst = bt; bsb = bb;
3034 }
3035 // #--
3036 // |
3037 inx = 0; iny = 0;
3038 inw = bl; inh = bt;
3039 outx = ox; outy = oy;
3040 outw = bsl; outh = bst;
3041 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3042 // .##
3043 // |
3044 inx = bl; iny = 0;
3045 inw = imw - bl - br; inh = bt;
3046 outx = ox + bsl; outy = oy;
3047 outw = iw - bsl - bsr; outh = bst;
3048 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3049 // --#
3050 // |
3051 inx = imw - br; iny = 0;
3052 inw = br; inh = bt;
3053 outx = ox + iw - bsr; outy = oy;
3054 outw = bsr; outh = bst;
3055 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3056 // .--
3057 // #
3058 inx = 0; iny = bt;
3059 inw = bl; inh = imh - bt - bb;
3060 outx = ox; outy = oy + bst;
3061 outw = bsl; outh = ih - bst - bsb;
3062 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3063 // .--.
3064 // |##|
3065 if (o->cur.border.fill > EVAS_BORDER_FILL_NONE)
3066 {
3067 inx = bl; iny = bt;
3068 inw = imw - bl - br; inh = imh - bt - bb;
3069 outx = ox + bsl; outy = oy + bst;
3070 outw = iw - bsl - bsr; outh = ih - bst - bsb;
3071 if ((o->cur.border.fill == EVAS_BORDER_FILL_SOLID) &&
3072 (obj->cur.cache.clip.a == 255) &&
3073 (obj->cur.render_op == EVAS_RENDER_BLEND))
3074 {
3075 obj->layer->evas->engine.func->context_render_op_set(output, context,
3076 EVAS_RENDER_COPY);
3077 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3078 obj->layer->evas->engine.func->context_render_op_set(output, context,
3079 obj->cur.render_op);
3080 }
3081 else
3082 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3083 }
3084 // --.
3085 // #
3086 inx = imw - br; iny = bt;
3087 inw = br; inh = imh - bt - bb;
3088 outx = ox + iw - bsr; outy = oy + bst;
3089 outw = bsr; outh = ih - bst - bsb;
3090 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3091 // |
3092 // #--
3093 inx = 0; iny = imh - bb;
3094 inw = bl; inh = bb;
3095 outx = ox; outy = oy + ih - bsb;
3096 outw = bsl; outh = bsb;
3097 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3098 // |
3099 // .##
3100 inx = bl; iny = imh - bb;
3101 inw = imw - bl - br; inh = bb;
3102 outx = ox + bsl; outy = oy + ih - bsb;
3103 outw = iw - bsl - bsr; outh = bsb;
3104 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3105 // |
3106 // --#
3107 inx = imw - br; iny = imh - bb;
3108 inw = br; inh = bb;
3109 outx = ox + iw - bsr; outy = oy + ih - bsb;
3110 outw = bsr; outh = bsb;
3111 obj->layer->evas->engine.func->image_draw(output, context, surface, pixels, inx, iny, inw, inh, outx, outy, outw, outh, o->cur.smooth_scale);
3112 }
3113 idy += idh;
3114 if (dobreak_h) break;
3115 }
3116 idx += idw;
3117 idy = ydy;
3118 if (dobreak_w) break;
3119 }
3120 }
3121 }
3122}
3123
3124static void
3125evas_object_image_render_pre(Evas_Object *obj)
3126{
3127 Evas_Object_Image *o;
3128 int is_v = 0, was_v = 0;
3129 Evas *e;
3130
3131 /* dont pre-render the obj twice! */
3132 if (obj->pre_render_done) return;
3133 obj->pre_render_done = 1;
3134 /* pre-render phase. this does anything an object needs to do just before */
3135 /* rendering. this could mean loading the image data, retrieving it from */
3136 /* elsewhere, decoding video etc. */
3137 /* then when this is done the object needs to figure if it changed and */
3138 /* if so what and where and add the appropriate redraw rectangles */
3139 o = (Evas_Object_Image *)(obj->object_data);
3140 e = obj->layer->evas;
3141
3142 if ((o->cur.fill.w < 1) || (o->cur.fill.h < 1))
3143 {
3144 ERR("%p has invalid fill size: %dx%d. Ignored",
3145 obj, o->cur.fill.w, o->cur.fill.h);
3146 return;
3147 }
3148
3149 /* if someone is clipping this obj - go calculate the clipper */
3150 if (obj->cur.clipper)
3151 {
3152 if (obj->cur.cache.clip.dirty)
3153 evas_object_clip_recalc(obj->cur.clipper);
3154 obj->cur.clipper->func->render_pre(obj->cur.clipper);
3155 }
3156 /* Proxy: Do it early */
3157 if (o->cur.source &&
3158 (o->cur.source->proxy.redraw || o->cur.source->changed))
3159 {
3160 /* XXX: Do I need to sort out the map here? */
3161 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3162 goto done;
3163 }
3164
3165 /* now figure what changed and add draw rects */
3166 /* if it just became visible or invisible */
3167 is_v = evas_object_is_visible(obj);
3168 was_v = evas_object_was_visible(obj);
3169 if (is_v != was_v)
3170 {
3171 evas_object_render_pre_visible_change(&e->clip_changes, obj, is_v, was_v);
3172 if (!o->pixel_updates) goto done;
3173 }
3174 if ((obj->cur.map != obj->prev.map) ||
3175 (obj->cur.usemap != obj->prev.usemap))
3176 {
3177 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3178 goto done;
3179 }
3180 /* it's not visible - we accounted for it appearing or not so just abort */
3181 if (!is_v) goto done;
3182 /* clipper changed this is in addition to anything else for obj */
3183 evas_object_render_pre_clipper_change(&e->clip_changes, obj);
3184 /* if we restacked (layer or just within a layer) and don't clip anyone */
3185 if (obj->restack)
3186 {
3187 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3188 if (!o->pixel_updates) goto done;
3189 }
3190 /* if it changed color */
3191 if ((obj->cur.color.r != obj->prev.color.r) ||
3192 (obj->cur.color.g != obj->prev.color.g) ||
3193 (obj->cur.color.b != obj->prev.color.b) ||
3194 (obj->cur.color.a != obj->prev.color.a))
3195 {
3196 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3197 if (!o->pixel_updates) goto done;
3198 }
3199 /* if it changed render op */
3200 if (obj->cur.render_op != obj->prev.render_op)
3201 {
3202 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3203 if (!o->pixel_updates) goto done;
3204 }
3205 /* if it changed anti_alias */
3206 if (obj->cur.anti_alias != obj->prev.anti_alias)
3207 {
3208 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3209 if (!o->pixel_updates) goto done;
3210 }
3211 if (o->changed)
3212 {
3213 if (((o->cur.file) && (!o->prev.file)) ||
3214 ((!o->cur.file) && (o->prev.file)) ||
3215 ((o->cur.key) && (!o->prev.key)) ||
3216 ((!o->cur.key) && (o->prev.key))
3217 )
3218 {
3219 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3220 if (!o->pixel_updates) goto done;
3221 }
3222 if ((o->cur.image.w != o->prev.image.w) ||
3223 (o->cur.image.h != o->prev.image.h) ||
3224 (o->cur.has_alpha != o->prev.has_alpha) ||
3225 (o->cur.cspace != o->prev.cspace) ||
3226 (o->cur.smooth_scale != o->prev.smooth_scale))
3227 {
3228 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3229 if (!o->pixel_updates) goto done;
3230 }
3231 if ((o->cur.border.l != o->prev.border.l) ||
3232 (o->cur.border.r != o->prev.border.r) ||
3233 (o->cur.border.t != o->prev.border.t) ||
3234 (o->cur.border.b != o->prev.border.b) ||
3235 (o->cur.border.fill != o->prev.border.fill) ||
3236 (o->cur.border.scale != o->prev.border.scale))
3237 {
3238 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3239 if (!o->pixel_updates) goto done;
3240 }
3241 if (o->dirty_pixels)
3242 {
3243 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3244 if (!o->pixel_updates) goto done;
3245 }
3246 if (o->cur.frame != o->prev.frame)
3247 {
3248 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3249 if (!o->pixel_updates) goto done;
3250 }
3251
3252 }
3253 /* if it changed geometry - and obviously not visibility or color */
3254 /* calculate differences since we have a constant color fill */
3255 /* we really only need to update the differences */
3256#if 0 // XXX: maybe buggy?
3257 if (((obj->cur.geometry.x != obj->prev.geometry.x) ||
3258 (obj->cur.geometry.y != obj->prev.geometry.y) ||
3259 (obj->cur.geometry.w != obj->prev.geometry.w) ||
3260 (obj->cur.geometry.h != obj->prev.geometry.h)) &&
3261 (o->cur.fill.w == o->prev.fill.w) &&
3262 (o->cur.fill.h == o->prev.fill.h) &&
3263 ((o->cur.fill.x + obj->cur.geometry.x) == (o->prev.fill.x + obj->prev.geometry.x)) &&
3264 ((o->cur.fill.y + obj->cur.geometry.y) == (o->prev.fill.y + obj->prev.geometry.y)) &&
3265 (!o->pixel_updates)
3266 )
3267 {
3268 evas_rects_return_difference_rects(&e->clip_changes,
3269 obj->cur.geometry.x,
3270 obj->cur.geometry.y,
3271 obj->cur.geometry.w,
3272 obj->cur.geometry.h,
3273 obj->prev.geometry.x,
3274 obj->prev.geometry.y,
3275 obj->prev.geometry.w,
3276 obj->prev.geometry.h);
3277 if (!o->pixel_updates) goto done;
3278 }
3279#endif
3280 if (((obj->cur.geometry.x != obj->prev.geometry.x) ||
3281 (obj->cur.geometry.y != obj->prev.geometry.y) ||
3282 (obj->cur.geometry.w != obj->prev.geometry.w) ||
3283 (obj->cur.geometry.h != obj->prev.geometry.h))
3284 )
3285 {
3286 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3287 if (!o->pixel_updates) goto done;
3288 }
3289 if (o->changed)
3290 {
3291 if ((o->cur.fill.x != o->prev.fill.x) ||
3292 (o->cur.fill.y != o->prev.fill.y) ||
3293 (o->cur.fill.w != o->prev.fill.w) ||
3294 (o->cur.fill.h != o->prev.fill.h))
3295 {
3296 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3297 if (!o->pixel_updates) goto done;
3298 }
3299 if (o->pixel_updates)
3300 {
3301 if ((o->cur.border.l == 0) &&
3302 (o->cur.border.r == 0) &&
3303 (o->cur.border.t == 0) &&
3304 (o->cur.border.b == 0) &&
3305 (o->cur.image.w > 0) &&
3306 (o->cur.image.h > 0) &&
3307 (!((obj->cur.map) && (obj->cur.usemap))))
3308 {
3309 Eina_Rectangle *rr;
3310
3311 EINA_LIST_FREE(o->pixel_updates, rr)
3312 {
3313 Evas_Coord idw, idh, idx, idy;
3314 int x, y, w, h;
3315
3316 e->engine.func->image_dirty_region(e->engine.data.output, o->engine_data, rr->x, rr->y, rr->w, rr->h);
3317
3318 idx = evas_object_image_figure_x_fill(obj, o->cur.fill.x, o->cur.fill.w, &idw);
3319 idy = evas_object_image_figure_y_fill(obj, o->cur.fill.y, o->cur.fill.h, &idh);
3320
3321 if (idw < 1) idw = 1;
3322 if (idh < 1) idh = 1;
3323 if (idx > 0) idx -= idw;
3324 if (idy > 0) idy -= idh;
3325 while (idx < obj->cur.geometry.w)
3326 {
3327 Evas_Coord ydy;
3328
3329 ydy = idy;
3330 x = idx;
3331 w = ((int)(idx + idw)) - x;
3332 while (idy < obj->cur.geometry.h)
3333 {
3334 Eina_Rectangle r;
3335
3336 y = idy;
3337 h = ((int)(idy + idh)) - y;
3338
3339 r.x = ((rr->x - 1) * w) / o->cur.image.w;
3340 r.y = ((rr->y - 1) * h) / o->cur.image.h;
3341 r.w = ((rr->w + 2) * w) / o->cur.image.w;
3342 r.h = ((rr->h + 2) * h) / o->cur.image.h;
3343 r.x += obj->cur.geometry.x + x;
3344 r.y += obj->cur.geometry.y + y;
3345 RECTS_CLIP_TO_RECT(r.x, r.y, r.w, r.h,
3346 obj->cur.cache.clip.x, obj->cur.cache.clip.y,
3347 obj->cur.cache.clip.w, obj->cur.cache.clip.h);
3348 evas_add_rect(&e->clip_changes, r.x, r.y, r.w, r.h);
3349 idy += h;
3350 }
3351 idx += idw;
3352 idy = ydy;
3353 }
3354 eina_rectangle_free(rr);
3355 }
3356 goto done;
3357 }
3358 else
3359 {
3360 Eina_Rectangle *r;
3361
3362 EINA_LIST_FREE(o->pixel_updates, r)
3363 eina_rectangle_free(r);
3364 e->engine.func->image_dirty_region(e->engine.data.output, o->engine_data, 0, 0, o->cur.image.w, o->cur.image.h);
3365 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3366 goto done;
3367 }
3368 }
3369 }
3370#if 0 // filtering disabled
3371 if (obj->filter && obj->filter->dirty)
3372 {
3373 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
3374 }
3375#endif
3376 /* it obviously didn't change - add a NO obscure - this "unupdates" this */
3377 /* area so if there were updates for it they get wiped. don't do it if we */
3378 /* aren't fully opaque and we are visible */
3379 if (evas_object_is_visible(obj) &&
3380 evas_object_is_opaque(obj))
3381 {
3382 Evas_Coord x, y, w, h;
3383
3384 x = obj->cur.cache.clip.x;
3385 y = obj->cur.cache.clip.y;
3386 w = obj->cur.cache.clip.w;
3387 h = obj->cur.cache.clip.h;
3388 if (obj->cur.clipper)
3389 {
3390 RECTS_CLIP_TO_RECT(x, y, w, h,
3391 obj->cur.clipper->cur.cache.clip.x,
3392 obj->cur.clipper->cur.cache.clip.y,
3393 obj->cur.clipper->cur.cache.clip.w,
3394 obj->cur.clipper->cur.cache.clip.h);
3395 }
3396 e->engine.func->output_redraws_rect_del(e->engine.data.output,
3397 x, y, w, h);
3398 }
3399 done:
3400 evas_object_render_pre_effect_updates(&e->clip_changes, obj, is_v, was_v);
3401}
3402
3403static void
3404evas_object_image_render_post(Evas_Object *obj)
3405{
3406 Evas_Object_Image *o;
3407 Eina_Rectangle *r;
3408
3409 /* this moves the current data to the previous state parts of the object */
3410 /* in whatever way is safest for the object. also if we don't need object */
3411 /* data anymore we can free it if the object deems this is a good idea */
3412 o = (Evas_Object_Image *)(obj->object_data);
3413 /* remove those pesky changes */
3414 evas_object_clip_changes_clean(obj);
3415 EINA_LIST_FREE(o->pixel_updates, r)
3416 eina_rectangle_free(r);
3417 /* move cur to prev safely for object data */
3418 obj->prev = obj->cur;
3419 o->prev = o->cur;
3420 o->changed = 0;
3421 /* FIXME: copy strings across */
3422}
3423
3424static unsigned int evas_object_image_id_get(Evas_Object *obj)
3425{
3426 Evas_Object_Image *o;
3427
3428 o = (Evas_Object_Image *)(obj->object_data);
3429 if (!o) return 0;
3430 return MAGIC_OBJ_IMAGE;
3431}
3432
3433static unsigned int evas_object_image_visual_id_get(Evas_Object *obj)
3434{
3435 Evas_Object_Image *o;
3436
3437 o = (Evas_Object_Image *)(obj->object_data);
3438 if (!o) return 0;
3439 return MAGIC_OBJ_IMAGE;
3440}
3441
3442static void *evas_object_image_engine_data_get(Evas_Object *obj)
3443{
3444 Evas_Object_Image *o;
3445
3446 o = (Evas_Object_Image *)(obj->object_data);
3447 if (!o) return NULL;
3448 return o->engine_data;
3449}
3450
3451static int
3452evas_object_image_is_opaque(Evas_Object *obj)
3453{
3454 Evas_Object_Image *o;
3455
3456 /* this returns 1 if the internal object data implies that the object is */
3457 /* currently fully opaque over the entire rectangle it occupies */
3458 o = (Evas_Object_Image *)(obj->object_data);
3459/* disable caching due tyo maps screwing with this
3460 o->cur.opaque_valid = 0;
3461 if (o->cur.opaque_valid)
3462 {
3463 if (!o->cur.opaque) return 0;
3464 }
3465 else
3466*/
3467 {
3468 o->cur.opaque = 0;
3469/* disable caching */
3470/* o->cur.opaque_valid = 1; */
3471 if ((o->cur.fill.w < 1) || (o->cur.fill.h < 1))
3472 return o->cur.opaque;
3473 if (((o->cur.border.l != 0) ||
3474 (o->cur.border.r != 0) ||
3475 (o->cur.border.t != 0) ||
3476 (o->cur.border.b != 0)) &&
3477 (!o->cur.border.fill)) return o->cur.opaque;
3478 if (!o->engine_data) return o->cur.opaque;
3479 o->cur.opaque = 1;
3480 }
3481 // FIXME: use proxy
3482 if (o->cur.source)
3483 {
3484 o->cur.opaque = evas_object_is_opaque(o->cur.source);
3485 return o->cur.opaque; /* FIXME: Should go poke at the object */
3486 }
3487 if (o->cur.has_alpha)
3488 {
3489 o->cur.opaque = 0;
3490 return o->cur.opaque;
3491 }
3492 if ((obj->cur.map) && (obj->cur.usemap))
3493 {
3494 Evas_Map *m = obj->cur.map;
3495
3496 if ((m->points[0].a == 255) &&
3497 (m->points[1].a == 255) &&
3498 (m->points[2].a == 255) &&
3499 (m->points[3].a == 255))
3500 {
3501 if (
3502 ((m->points[0].x == m->points[3].x) &&
3503 (m->points[1].x == m->points[2].x) &&
3504 (m->points[0].y == m->points[1].y) &&
3505 (m->points[2].y == m->points[3].y))
3506 ||
3507 ((m->points[0].x == m->points[1].x) &&
3508 (m->points[2].x == m->points[3].x) &&
3509 (m->points[0].y == m->points[3].y) &&
3510 (m->points[1].y == m->points[2].y))
3511 )
3512 {
3513 if ((m->points[0].x == obj->cur.geometry.x) &&
3514 (m->points[0].y == obj->cur.geometry.y) &&
3515 (m->points[2].x == (obj->cur.geometry.x + obj->cur.geometry.w)) &&
3516 (m->points[2].y == (obj->cur.geometry.y + obj->cur.geometry.h)))
3517 return o->cur.opaque;
3518 }
3519 }
3520 o->cur.opaque = 0;
3521 return o->cur.opaque;
3522 }
3523 if (obj->cur.render_op == EVAS_RENDER_COPY) return o->cur.opaque;
3524 return o->cur.opaque;
3525}
3526
3527static int
3528evas_object_image_was_opaque(Evas_Object *obj)
3529{
3530 Evas_Object_Image *o;
3531
3532 /* this returns 1 if the internal object data implies that the object was */
3533 /* previously fully opaque over the entire rectangle it occupies */
3534 o = (Evas_Object_Image *)(obj->object_data);
3535 if (o->prev.opaque_valid)
3536 {
3537 if (!o->prev.opaque) return 0;
3538 }
3539 else
3540 {
3541 o->prev.opaque = 0;
3542 o->prev.opaque_valid = 1;
3543 if ((o->prev.fill.w < 1) || (o->prev.fill.h < 1))
3544 return 0;
3545 if (((o->prev.border.l != 0) ||
3546 (o->prev.border.r != 0) ||
3547 (o->prev.border.t != 0) ||
3548 (o->prev.border.b != 0)) &&
3549 (!o->prev.border.fill)) return 0;
3550 if (!o->engine_data) return 0;
3551 o->prev.opaque = 1;
3552 }
3553 // FIXME: use proxy
3554 if (o->prev.source) return 0; /* FIXME: Should go poke at the object */
3555 if (obj->prev.usemap) return 0;
3556 if (obj->prev.render_op == EVAS_RENDER_COPY) return 1;
3557 if (o->prev.has_alpha) return 0;
3558 if (obj->prev.render_op != EVAS_RENDER_BLEND) return 0;
3559 return 1;
3560}
3561
3562static int
3563evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
3564{
3565 Evas_Object_Image *o;
3566 DATA32 *data;
3567 int w, h, stride, iw, ih;
3568 int a;
3569
3570 o = (Evas_Object_Image *)(obj->object_data);
3571
3572 x -= obj->cur.cache.clip.x;
3573 y -= obj->cur.cache.clip.y;
3574 w = obj->cur.cache.clip.w;
3575 h = obj->cur.cache.clip.h;
3576 iw = o->cur.image.w;
3577 ih = o->cur.image.h;
3578
3579 if ((x < 0) || (y < 0) || (x >= w) || (y >= h)) return 0;
3580 if (!o->cur.has_alpha) return 1;
3581
3582 // FIXME: proxy needs to be honored
3583 if (obj->cur.map)
3584 {
3585 x = obj->cur.map->mx;
3586 y = obj->cur.map->my;
3587 }
3588 else
3589 {
3590 int bl, br, bt, bb, bsl, bsr, bst, bsb;
3591
3592 bl = o->cur.border.l;
3593 br = o->cur.border.r;
3594 bt = o->cur.border.t;
3595 bb = o->cur.border.b;
3596 if ((bl + br) > iw)
3597 {
3598 bl = iw / 2;
3599 br = iw - bl;
3600 }
3601 if ((bl + br) > iw)
3602 {
3603 bl = iw / 2;
3604 br = iw - bl;
3605 }
3606 if ((bt + bb) > ih)
3607 {
3608 bt = ih / 2;
3609 bb = ih - bt;
3610 }
3611 if ((bt + bb) > ih)
3612 {
3613 bt = ih / 2;
3614 bb = ih - bt;
3615 }
3616 if (o->cur.border.scale != 1.0)
3617 {
3618 bsl = ((double)bl * o->cur.border.scale);
3619 bsr = ((double)br * o->cur.border.scale);
3620 bst = ((double)bt * o->cur.border.scale);
3621 bsb = ((double)bb * o->cur.border.scale);
3622 }
3623 else
3624 {
3625 bsl = bl; bsr = br; bst = bt; bsb = bb;
3626 }
3627
3628 w = o->cur.fill.w;
3629 h = o->cur.fill.h;
3630 x -= o->cur.fill.x;
3631 y -= o->cur.fill.y;
3632 x %= w;
3633 y %= h;
3634
3635 if (x < 0) x += w;
3636 if (y < 0) y += h;
3637
3638 if (o->cur.border.fill != EVAS_BORDER_FILL_DEFAULT)
3639 {
3640 if ((x > bsl) && (x < (w - bsr)) &&
3641 (y > bst) && (y < (h - bsb)))
3642 {
3643 if (o->cur.border.fill == EVAS_BORDER_FILL_SOLID) return 1;
3644 return 0;
3645 }
3646 }
3647
3648 if (x < bsl) x = (x * bl) / bsl;
3649 else if (x > (w - bsr)) x = iw - (((w - x) * br) / bsr);
3650 else if ((bsl + bsr) < w) x = bl + (((x - bsl) * (iw - bl - br)) / (w - bsl - bsr));
3651 else return 1;
3652
3653 if (y < bst) y = (y * bt) / bst;
3654 else if (y > (h - bsb)) y = ih - (((h - y) * bb) / bsb);
3655 else if ((bst + bsb) < h) y = bt + (((y - bst) * (ih - bt - bb)) / (h - bst - bsb));
3656 else return 1;
3657 }
3658
3659 if (x < 0) x = 0;
3660 if (y < 0) y = 0;
3661 if (x >= iw) x = iw - 1;
3662 if (y >= ih) y = ih - 1;
3663
3664 stride = o->cur.image.stride;
3665
3666 o->engine_data = obj->layer->evas->engine.func->image_data_get
3667 (obj->layer->evas->engine.data.output,
3668 o->engine_data,
3669 0,
3670 &data,
3671 &o->load_error);
3672 if (!data)
3673 return 0;
3674
3675 switch (o->cur.cspace)
3676 {
3677 case EVAS_COLORSPACE_ARGB8888:
3678 data = ((DATA32*)(data) + ((y * (stride >> 2)) + x));
3679 a = (*((DATA32*)(data)) >> 24) & 0xff;
3680 break;
3681 case EVAS_COLORSPACE_RGB565_A5P:
3682 data = (void*) ((DATA16*)(data) + (h * (stride >> 1)));
3683 data = (void*) ((DATA8*)(data) + ((y * (stride >> 1)) + x));
3684 a = (*((DATA8*)(data))) & 0x1f;
3685 break;
3686 default:
3687 return 1;
3688 break;
3689 }
3690
3691 return (a != 0);
3692}
3693
3694static int
3695evas_object_image_has_opaque_rect(Evas_Object *obj)
3696{
3697 Evas_Object_Image *o;
3698
3699 o = (Evas_Object_Image *)(obj->object_data);
3700 if ((obj->cur.map) && (obj->cur.usemap)) return 0;
3701 if (((o->cur.border.l | o->cur.border.r | o->cur.border.t | o->cur.border.b) != 0) &&
3702 (o->cur.border.fill == EVAS_BORDER_FILL_SOLID) &&
3703 (obj->cur.render_op == EVAS_RENDER_BLEND) &&
3704 (obj->cur.cache.clip.a == 255) &&
3705 (o->cur.fill.x == 0) &&
3706 (o->cur.fill.y == 0) &&
3707 (o->cur.fill.w == obj->cur.geometry.w) &&
3708 (o->cur.fill.h == obj->cur.geometry.h)
3709 ) return 1;
3710 return 0;
3711}
3712
3713static int
3714evas_object_image_get_opaque_rect(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
3715{
3716 Evas_Object_Image *o;
3717
3718 o = (Evas_Object_Image *)(obj->object_data);
3719 if (o->cur.border.scale == 1.0)
3720 {
3721 *x = obj->cur.geometry.x + o->cur.border.l;
3722 *y = obj->cur.geometry.y + o->cur.border.t;
3723 *w = obj->cur.geometry.w - (o->cur.border.l + o->cur.border.r);
3724 if (*w < 0) *w = 0;
3725 *h = obj->cur.geometry.h - (o->cur.border.t + o->cur.border.b);
3726 if (*h < 0) *h = 0;
3727 }
3728 else
3729 {
3730 *x = obj->cur.geometry.x + (o->cur.border.l * o->cur.border.scale);
3731 *y = obj->cur.geometry.y + (o->cur.border.t * o->cur.border.scale);
3732 *w = obj->cur.geometry.w - ((o->cur.border.l * o->cur.border.scale) + (o->cur.border.r * o->cur.border.scale));
3733 if (*w < 0) *w = 0;
3734 *h = obj->cur.geometry.h - ((o->cur.border.t * o->cur.border.scale) + (o->cur.border.b * o->cur.border.scale));
3735 if (*h < 0) *h = 0;
3736 }
3737 return 1;
3738}
3739
3740static int
3741evas_object_image_can_map(Evas_Object *obj __UNUSED__)
3742{
3743 return 1;
3744}
3745
3746static void *
3747evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_Colorspace to_cspace)
3748{
3749 void *out = NULL;
3750
3751 if (!data)
3752 return NULL;
3753
3754 switch (o->cur.cspace)
3755 {
3756 case EVAS_COLORSPACE_ARGB8888:
3757 out = evas_common_convert_argb8888_to(data,
3758 o->cur.image.w,
3759 o->cur.image.h,
3760 o->cur.image.stride >> 2,
3761 o->cur.has_alpha,
3762 to_cspace);
3763 break;
3764 case EVAS_COLORSPACE_RGB565_A5P:
3765 out = evas_common_convert_rgb565_a5p_to(data,
3766 o->cur.image.w,
3767 o->cur.image.h,
3768 o->cur.image.stride >> 1,
3769 o->cur.has_alpha,
3770 to_cspace);
3771 break;
3772 case EVAS_COLORSPACE_YCBCR422601_PL:
3773 fprintf(stderr, "EVAS_COLORSPACE_YCBCR422601_PL:\n");
3774 out = evas_common_convert_yuv_422_601_to(data,
3775 o->cur.image.w,
3776 o->cur.image.h,
3777 to_cspace);
3778 break;
3779 case EVAS_COLORSPACE_YCBCR422P601_PL:
3780 out = evas_common_convert_yuv_422P_601_to(data,
3781 o->cur.image.w,
3782 o->cur.image.h,
3783 to_cspace);
3784 break;
3785 case EVAS_COLORSPACE_YCBCR420NV12601_PL:
3786 out = evas_common_convert_yuv_420_601_to(data,
3787 o->cur.image.w,
3788 o->cur.image.h,
3789 to_cspace);
3790 break;
3791 case EVAS_COLORSPACE_YCBCR420TM12601_PL:
3792 out = evas_common_convert_yuv_420T_601_to(data,
3793 o->cur.image.w,
3794 o->cur.image.h,
3795 to_cspace);
3796 break;
3797 default:
3798 fprintf(stderr, "unknow colorspace: %i\n", o->cur.cspace);
3799 break;
3800 }
3801
3802 return out;
3803}
3804
3805static void
3806evas_object_image_filled_resize_listener(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *einfo __UNUSED__)
3807{
3808 Evas_Coord w, h;
3809 Evas_Object_Image *o;
3810
3811 o = obj->object_data;
3812 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3813 evas_object_image_fill_set(obj, 0, 0, w, h);
3814}
3815
3816
3817Eina_Bool
3818_evas_object_image_preloading_get(const Evas_Object *obj)
3819{
3820 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3821 if (!o) return EINA_FALSE;
3822 MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
3823 return EINA_FALSE;
3824 MAGIC_CHECK_END();
3825 return o->preloading;
3826}
3827
3828void
3829_evas_object_image_preloading_set(Evas_Object *obj, Eina_Bool preloading)
3830{
3831 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3832 o->preloading = preloading;
3833}
3834
3835void
3836_evas_object_image_preloading_check(Evas_Object *obj)
3837{
3838 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3839 if (obj->layer->evas->engine.func->image_load_error_get)
3840 o->load_error = obj->layer->evas->engine.func->image_load_error_get
3841 (obj->layer->evas->engine.data.output, o->engine_data);
3842}
3843
3844Evas_Object *
3845_evas_object_image_video_parent_get(Evas_Object *obj)
3846{
3847 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3848
3849 return o->video_surface ? o->video.parent : NULL;
3850}
3851
3852void
3853_evas_object_image_video_overlay_show(Evas_Object *obj)
3854{
3855 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3856
3857 if (obj->cur.cache.clip.x != obj->prev.cache.clip.x ||
3858 obj->cur.cache.clip.y != obj->prev.cache.clip.y ||
3859 o->created || !o->video_visible)
3860 o->video.move(o->video.data, obj, &o->video, obj->cur.cache.clip.x, obj->cur.cache.clip.y);
3861 if (obj->cur.cache.clip.w != obj->prev.cache.clip.w ||
3862 obj->cur.cache.clip.h != obj->prev.cache.clip.h ||
3863 o->created || !o->video_visible)
3864 o->video.resize(o->video.data, obj, &o->video, obj->cur.cache.clip.w, obj->cur.cache.clip.h);
3865 if (!o->video_visible || o->created)
3866 {
3867 o->video.show(o->video.data, obj, &o->video);
3868 }
3869 else
3870 {
3871 /* Cancel dirty on the image */
3872 Eina_Rectangle *r;
3873
3874 o->dirty_pixels = 0;
3875 EINA_LIST_FREE(o->pixel_updates, r)
3876 eina_rectangle_free(r);
3877 }
3878 o->video_visible = EINA_TRUE;
3879 o->created = EINA_FALSE;
3880}
3881
3882void
3883_evas_object_image_video_overlay_hide(Evas_Object *obj)
3884{
3885 Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data);
3886
3887 if (o->video_visible || o->created)
3888 o->video.hide(o->video.data, obj, &o->video);
3889 if (evas_object_is_visible(obj))
3890 o->video.update_pixels(o->video.data, obj, &o->video);
3891 o->video_visible = EINA_FALSE;
3892 o->created = EINA_FALSE;
3893}
3894
3895/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/