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