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