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