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