1 #include "evas_image_private.h"
2 #include "efl_canvas_image.eo.h"
3
4 #define MY_CLASS EFL_CANVAS_IMAGE_CLASS
5 #define MY_CLASS_NAME efl_class_name_get(MY_CLASS)
6
7 void
_evas_image_file_unload(Eo * eo_obj)8 _evas_image_file_unload(Eo *eo_obj)
9 {
10 Evas_Object_Protected_Data *obj;
11 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
12
13 if (!o->cur->f) return;
14
15 obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
16 evas_object_async_block(obj);
17 _evas_image_init_set(NULL, NULL, eo_obj, obj, o, NULL);
18 o->buffer_data_set = EINA_FALSE;
19 _evas_image_done_set(eo_obj, obj, o);
20 o->load_error = EFL_GFX_IMAGE_LOAD_ERROR_NONE;
21 }
22
23 void
_evas_image_preload_update(Eo * eo_obj,Eina_File * f)24 _evas_image_preload_update(Eo *eo_obj, Eina_File *f)
25 {
26 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
27 if (o->cur->f) return;
28 EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, cur)
29 {
30 cur->f = eina_file_dup(f);
31 }
32 EINA_COW_IMAGE_STATE_WRITE_END(o, cur)
33 }
34
35 Eina_Bool
_evas_image_file_load(Eo * eo_obj,Evas_Image_Data * o)36 _evas_image_file_load(Eo *eo_obj, Evas_Image_Data *o)
37 {
38 Evas_Object_Protected_Data *obj;
39 Evas_Image_Load_Opts lo;
40 const Eina_File *f = efl_file_mmap_get(eo_obj);
41 const char *key = efl_file_key_get(eo_obj);
42 int load_error;
43 int frame_index;
44
45 if (!o->skip_head)
46 EINA_SAFETY_ON_NULL_RETURN_VAL(f, EINA_FALSE);
47
48 if (f && (o->cur->f == f))
49 {
50 if ((!o->cur->key) && (!key))
51 return EINA_TRUE;
52 if ((o->cur->key) && (key) && (!strcmp(o->cur->key, key)))
53 return EINA_TRUE;
54 }
55
56 obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
57 evas_object_async_block(obj);
58 _evas_image_init_set(f, key, eo_obj, obj, o, &lo);
59 if (f)
60 o->engine_data = ENFN->image_mmap(ENC, o->cur->f, o->cur->key, &load_error, &lo);
61 else
62 o->engine_data = ENFN->image_load(ENC, efl_file_get(eo_obj), o->cur->key, &load_error, &lo);
63
64 if (_evas_image_animated_get(eo_obj))
65 {
66 frame_index = ENFN->image_animated_frame_get(ENC, o->engine_data);
67 _evas_image_animated_frame_set(eo_obj, frame_index);
68 }
69
70 o->load_error = _evas_load_error_to_efl_gfx_image_load_error(load_error);
71 o->buffer_data_set = EINA_FALSE;
72 _evas_image_done_set(eo_obj, obj, o);
73 o->file_size.w = o->cur->image.w;
74 o->file_size.h = o->cur->image.h;
75
76 return EINA_TRUE;
77 }
78
79 EOLIAN static Eina_Bool
_efl_canvas_image_efl_file_loaded_get(const Eo * eo_obj,void * _pd EINA_UNUSED)80 _efl_canvas_image_efl_file_loaded_get(const Eo *eo_obj, void *_pd EINA_UNUSED)
81 {
82 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
83 if (!o->skip_head)
84 return efl_file_loaded_get(efl_super(eo_obj, MY_CLASS));
85 return !!o->cur->f;
86 }
87
88 EOLIAN static const Eina_File *
_efl_canvas_image_efl_file_mmap_get(const Eo * eo_obj,void * _pd EINA_UNUSED)89 _efl_canvas_image_efl_file_mmap_get(const Eo *eo_obj, void *_pd EINA_UNUSED)
90 {
91 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
92 if (!o->skip_head)
93 return efl_file_mmap_get(efl_super(eo_obj, MY_CLASS));
94 return o->cur->f;
95 }
96
97 EOLIAN static Eina_Error
_efl_canvas_image_efl_file_load(Eo * eo_obj,void * _pd EINA_UNUSED)98 _efl_canvas_image_efl_file_load(Eo *eo_obj, void *_pd EINA_UNUSED)
99 {
100 if (efl_file_loaded_get(eo_obj)) return 0;
101 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
102 Eina_Error err = 0;
103
104 if (!o->skip_head)
105 err = efl_file_load(efl_super(eo_obj, MY_CLASS));
106 if (err) return err;
107 if (_evas_image_file_load(eo_obj, o))
108 return 0;
109 return EFL_GFX_IMAGE_LOAD_ERROR_DOES_NOT_EXIST;
110 }
111
112 EOLIAN static void
_efl_canvas_image_efl_file_unload(Eo * eo_obj,void * _pd EINA_UNUSED)113 _efl_canvas_image_efl_file_unload(Eo *eo_obj, void *_pd EINA_UNUSED)
114 {
115 efl_file_unload(efl_super(eo_obj, MY_CLASS));
116 _evas_image_file_unload(eo_obj);
117 }
118
119 const Eina_File *
_evas_image_mmap_get(const Eo * eo_obj)120 _evas_image_mmap_get(const Eo *eo_obj)
121 {
122 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
123
124 return o->cur->f;
125 }
126
127 const char *
_evas_image_key_get(const Eo * eo_obj)128 _evas_image_key_get(const Eo *eo_obj)
129 {
130 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
131
132 return o->cur->key;
133 }
134
135 void
_efl_canvas_image_load_error_set(Eo * eo_obj EINA_UNUSED,Eina_Error err)136 _efl_canvas_image_load_error_set(Eo *eo_obj EINA_UNUSED, Eina_Error err)
137 {
138 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
139 o->load_error = err;
140 }
141
142 static void
_image_preload_internal(Eo * eo_obj,Evas_Image_Data * o,Eina_Bool cancel)143 _image_preload_internal(Eo *eo_obj, Evas_Image_Data *o, Eina_Bool cancel)
144 {
145 if (!o->engine_data)
146 {
147 o->preload = EVAS_IMAGE_PRELOADING;
148 evas_object_inform_call_image_preloaded(eo_obj);
149 return;
150 }
151 // FIXME: if already busy preloading, then dont request again until
152 // preload done
153 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
154 if (cancel)
155 {
156 if (o->preload & EVAS_IMAGE_PRELOADING)
157 {
158 o->preload |= EVAS_IMAGE_PRELOAD_CANCEL;
159 ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj, EINA_TRUE);
160 }
161 }
162 else
163 {
164 if (o->preload != EVAS_IMAGE_PRELOADING)
165 {
166 o->preload = EVAS_IMAGE_PRELOADING;
167 ENFN->image_data_preload_request(ENC, o->engine_data, eo_obj);
168 }
169 }
170 }
171
172 void
_evas_image_load_async_start(Eo * eo_obj)173 _evas_image_load_async_start(Eo *eo_obj)
174 {
175 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
176 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
177
178 evas_object_async_block(obj);
179 _image_preload_internal(eo_obj, o, EINA_FALSE);
180 }
181
182 EOLIAN static void
_efl_canvas_image_efl_gfx_image_load_controller_load_async_start(Eo * eo_obj,void * _pd EINA_UNUSED)183 _efl_canvas_image_efl_gfx_image_load_controller_load_async_start(Eo *eo_obj, void *_pd EINA_UNUSED)
184 {
185 _evas_image_load_async_start(eo_obj);
186 }
187
188 void
_evas_image_load_async_cancel(Eo * eo_obj)189 _evas_image_load_async_cancel(Eo *eo_obj)
190 {
191 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
192 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
193
194 evas_object_async_block(obj);
195 _image_preload_internal(eo_obj, o, EINA_TRUE);
196 }
197
198 EOLIAN static void
_efl_canvas_image_efl_gfx_image_load_controller_load_async_cancel(Eo * eo_obj,void * _pd EINA_UNUSED)199 _efl_canvas_image_efl_gfx_image_load_controller_load_async_cancel(Eo *eo_obj, void *_pd EINA_UNUSED)
200 {
201 _evas_image_load_async_cancel(eo_obj);
202 }
203
204 void
_evas_image_load_dpi_set(Eo * eo_obj,double dpi)205 _evas_image_load_dpi_set(Eo *eo_obj, double dpi)
206 {
207 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
208 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
209
210 if (EINA_DBL_EQ(dpi, o->load_opts->dpi)) return;
211 evas_object_async_block(obj);
212 EINA_COW_LOAD_OPTS_WRITE_BEGIN(o, low)
213 low->dpi = dpi;
214 EINA_COW_LOAD_OPTS_WRITE_END(o, low);
215
216 if (o->cur->f)
217 {
218 _evas_image_unload(eo_obj, obj, 0);
219 evas_object_inform_call_image_unloaded(eo_obj);
220 _evas_image_load(eo_obj, obj, o);
221 o->changed = EINA_TRUE;
222 evas_object_change(eo_obj, obj);
223 }
224 }
225
226 EOLIAN static void
_efl_canvas_image_efl_gfx_image_load_controller_load_dpi_set(Eo * eo_obj,void * _pd EINA_UNUSED,double dpi)227 _efl_canvas_image_efl_gfx_image_load_controller_load_dpi_set(Eo *eo_obj, void *_pd EINA_UNUSED, double dpi)
228 {
229 _evas_image_load_dpi_set(eo_obj, dpi);
230 }
231
232 double
_evas_image_load_dpi_get(const Eo * eo_obj)233 _evas_image_load_dpi_get(const Eo *eo_obj)
234 {
235 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
236
237 return o->load_opts->dpi;
238 }
239
240 EOLIAN static double
_efl_canvas_image_efl_gfx_image_load_controller_load_dpi_get(const Eo * eo_obj,void * _pd EINA_UNUSED)241 _efl_canvas_image_efl_gfx_image_load_controller_load_dpi_get(const Eo *eo_obj, void *_pd EINA_UNUSED)
242 {
243 return _evas_image_load_dpi_get(eo_obj);
244 }
245
246 void
_evas_image_load_size_set(Eo * eo_obj,int w,int h)247 _evas_image_load_size_set(Eo *eo_obj, int w, int h)
248 {
249 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
250 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
251
252 if ((o->load_opts->w == w) && (o->load_opts->h == h)) return;
253 evas_object_async_block(obj);
254 EINA_COW_LOAD_OPTS_WRITE_BEGIN(o, low)
255 {
256 low->w = w;
257 low->h = h;
258 }
259 EINA_COW_LOAD_OPTS_WRITE_END(o, low);
260
261 if (o->cur->f)
262 {
263 _evas_image_unload(eo_obj, obj, 0);
264 evas_object_inform_call_image_unloaded(eo_obj);
265 _evas_image_load(eo_obj, obj, o);
266 o->changed = EINA_TRUE;
267 evas_object_change(eo_obj, obj);
268 }
269 o->proxyerror = 0;
270 }
271
272 EOLIAN static void
_efl_canvas_image_efl_gfx_image_load_controller_load_size_set(Eo * eo_obj,void * _pd EINA_UNUSED,Eina_Size2D sz)273 _efl_canvas_image_efl_gfx_image_load_controller_load_size_set(Eo *eo_obj, void *_pd EINA_UNUSED, Eina_Size2D sz)
274 {
275 _evas_image_load_size_set(eo_obj, sz.w, sz.h);
276 }
277
278 void
_evas_image_load_size_get(const Eo * eo_obj,int * w,int * h)279 _evas_image_load_size_get(const Eo *eo_obj, int *w, int *h)
280 {
281 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
282
283 if (w) *w = o->load_opts->w;
284 if (h) *h = o->load_opts->h;
285 }
286
287 EOLIAN static Eina_Size2D
_efl_canvas_image_efl_gfx_image_load_controller_load_size_get(const Eo * eo_obj,void * _pd EINA_UNUSED)288 _efl_canvas_image_efl_gfx_image_load_controller_load_size_get(const Eo *eo_obj, void *_pd EINA_UNUSED)
289 {
290 Eina_Size2D sz;
291 _evas_image_load_size_get(eo_obj, &sz.w, &sz.h);
292 return sz;
293 }
294
295 void
_evas_image_load_scale_down_set(Eo * eo_obj,int scale_down)296 _evas_image_load_scale_down_set(Eo *eo_obj, int scale_down)
297 {
298 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
299 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
300
301 if (o->load_opts->scale_down_by == scale_down) return;
302 evas_object_async_block(obj);
303 EINA_COW_LOAD_OPTS_WRITE_BEGIN(o, low)
304 low->scale_down_by = scale_down;
305 EINA_COW_LOAD_OPTS_WRITE_END(o, low);
306
307 if (o->cur->f)
308 {
309 _evas_image_unload(eo_obj, obj, 0);
310 evas_object_inform_call_image_unloaded(eo_obj);
311 _evas_image_load(eo_obj, obj, o);
312 o->changed = EINA_TRUE;
313 evas_object_change(eo_obj, obj);
314 }
315 }
316
317 EOLIAN static void
_efl_canvas_image_efl_gfx_image_load_controller_load_scale_down_set(Eo * eo_obj,void * _pd EINA_UNUSED,int scale_down)318 _efl_canvas_image_efl_gfx_image_load_controller_load_scale_down_set(Eo *eo_obj, void *_pd EINA_UNUSED, int scale_down)
319 {
320 _evas_image_load_scale_down_set(eo_obj, scale_down);
321 }
322
323 int
_evas_image_load_scale_down_get(const Eo * eo_obj)324 _evas_image_load_scale_down_get(const Eo *eo_obj)
325 {
326 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
327
328 return o->load_opts->scale_down_by;
329 }
330
331 EOLIAN static int
_efl_canvas_image_efl_gfx_image_load_controller_load_scale_down_get(const Eo * eo_obj,void * _pd EINA_UNUSED)332 _efl_canvas_image_efl_gfx_image_load_controller_load_scale_down_get(const Eo *eo_obj, void *_pd EINA_UNUSED)
333 {
334 return _evas_image_load_scale_down_get(eo_obj);
335 }
336
337 void
_evas_image_load_head_skip_set(const Eo * eo_obj,Eina_Bool skip)338 _evas_image_load_head_skip_set(const Eo *eo_obj, Eina_Bool skip)
339 {
340 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
341 o->skip_head = skip;
342 }
343
344 EOLIAN static void
_efl_canvas_image_efl_gfx_image_load_controller_load_skip_header_set(Eo * eo_obj,void * _pd EINA_UNUSED,Eina_Bool skip)345 _efl_canvas_image_efl_gfx_image_load_controller_load_skip_header_set(Eo *eo_obj, void *_pd EINA_UNUSED, Eina_Bool skip)
346 {
347 _evas_image_load_head_skip_set(eo_obj, skip);
348 }
349
350 Eina_Bool
_evas_image_load_head_skip_get(const Eo * eo_obj)351 _evas_image_load_head_skip_get(const Eo *eo_obj)
352 {
353 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
354 return o->skip_head;
355 }
356
357 EOLIAN static Eina_Bool
_efl_canvas_image_efl_gfx_image_load_controller_load_skip_header_get(const Eo * eo_obj,void * _pd EINA_UNUSED)358 _efl_canvas_image_efl_gfx_image_load_controller_load_skip_header_get(const Eo *eo_obj, void *_pd EINA_UNUSED)
359 {
360 return _evas_image_load_head_skip_get(eo_obj);
361 }
362
363 void
_evas_image_load_region_set(Eo * eo_obj,int x,int y,int w,int h)364 _evas_image_load_region_set(Eo *eo_obj, int x, int y, int w, int h)
365 {
366 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
367 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
368
369 if ((o->load_opts->region.x == x) && (o->load_opts->region.y == y) &&
370 (o->load_opts->region.w == w) && (o->load_opts->region.h == h)) return;
371 evas_object_async_block(obj);
372 EINA_COW_LOAD_OPTS_WRITE_BEGIN(o, low)
373 {
374 low->region.x = x;
375 low->region.y = y;
376 low->region.w = w;
377 low->region.h = h;
378 }
379 EINA_COW_LOAD_OPTS_WRITE_END(o, low);
380
381 if (o->cur->f)
382 {
383 _evas_image_unload(eo_obj, obj, 0);
384 evas_object_inform_call_image_unloaded(eo_obj);
385 _evas_image_load(eo_obj, obj, o);
386 o->changed = EINA_TRUE;
387 evas_object_change(eo_obj, obj);
388 }
389 }
390
391 EOLIAN static void
_efl_canvas_image_efl_gfx_image_load_controller_load_region_set(Eo * eo_obj,void * _pd EINA_UNUSED,Eina_Rect region)392 _efl_canvas_image_efl_gfx_image_load_controller_load_region_set(Eo *eo_obj, void *_pd EINA_UNUSED, Eina_Rect region)
393 {
394 _evas_image_load_region_set(eo_obj, region.x, region.y, region.w, region.h);
395 }
396
397 void
_evas_image_load_region_get(const Eo * eo_obj,int * x,int * y,int * w,int * h)398 _evas_image_load_region_get(const Eo *eo_obj, int *x, int *y, int *w, int *h)
399 {
400 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
401
402 if (x) *x = o->load_opts->region.x;
403 if (y) *y = o->load_opts->region.y;
404 if (w) *w = o->load_opts->region.w;
405 if (h) *h = o->load_opts->region.h;
406 }
407
408 EOLIAN static Eina_Rect
_efl_canvas_image_efl_gfx_image_load_controller_load_region_get(const Eo * eo_obj,void * _pd EINA_UNUSED)409 _efl_canvas_image_efl_gfx_image_load_controller_load_region_get(const Eo *eo_obj, void *_pd EINA_UNUSED)
410 {
411 Eina_Rect r;
412 _evas_image_load_region_get(eo_obj, &r.x, &r.y, &r.w, &r.h);
413 return r;
414 }
415
416 void
_evas_image_load_orientation_set(Eo * eo_obj,Eina_Bool enable)417 _evas_image_load_orientation_set(Eo *eo_obj, Eina_Bool enable)
418 {
419 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
420 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
421
422 if (o->load_opts->orientation == !!enable) return;
423 evas_object_async_block(obj);
424
425 EINA_COW_LOAD_OPTS_WRITE_BEGIN(o, low)
426 low->orientation = !!enable;
427 EINA_COW_LOAD_OPTS_WRITE_END(o, low);
428 }
429
430 EOLIAN static void
_efl_canvas_image_efl_gfx_image_load_controller_load_orientation_set(Eo * eo_obj,void * _pd EINA_UNUSED,Eina_Bool enable)431 _efl_canvas_image_efl_gfx_image_load_controller_load_orientation_set(Eo *eo_obj, void *_pd EINA_UNUSED, Eina_Bool enable)
432 {
433 _evas_image_load_orientation_set(eo_obj, enable);
434 }
435
436 Eina_Bool
_evas_image_load_orientation_get(const Eo * eo_obj)437 _evas_image_load_orientation_get(const Eo *eo_obj)
438 {
439 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
440
441 return o->load_opts->orientation;
442 }
443
444 EOLIAN static Eina_Bool
_efl_canvas_image_efl_gfx_image_load_controller_load_orientation_get(const Eo * eo_obj,void * _pd EINA_UNUSED)445 _efl_canvas_image_efl_gfx_image_load_controller_load_orientation_get(const Eo *eo_obj, void *_pd EINA_UNUSED)
446 {
447 return _evas_image_load_orientation_get(eo_obj);
448 }
449
450 Eina_Bool
_evas_image_load_region_support_get(const Eo * eo_obj)451 _evas_image_load_region_support_get(const Eo *eo_obj)
452 {
453 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
454 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
455
456 return ENFN->image_can_region_get(ENC, o->engine_data);
457 }
458
459 EOLIAN static Eina_Bool
_efl_canvas_image_efl_gfx_image_load_controller_load_region_support_get(const Eo * eo_obj,void * _pd EINA_UNUSED)460 _efl_canvas_image_efl_gfx_image_load_controller_load_region_support_get(const Eo *eo_obj, void *_pd EINA_UNUSED)
461 {
462 return _evas_image_load_region_support_get(eo_obj);
463 }
464
465 /* animated feature */
466 Eina_Bool
_evas_image_animated_get(const Eo * eo_obj)467 _evas_image_animated_get(const Eo *eo_obj)
468 {
469 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
470 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
471
472 if (!ENFN->image_animated_get)
473 return EINA_FALSE;
474
475 return ENFN->image_animated_get(ENC, o->engine_data);
476 }
477
478 EOLIAN static Eina_Bool
_efl_canvas_image_efl_gfx_frame_controller_animated_get(const Eo * eo_obj,void * _pd EINA_UNUSED)479 _efl_canvas_image_efl_gfx_frame_controller_animated_get(const Eo *eo_obj, void *_pd EINA_UNUSED)
480 {
481 return _evas_image_animated_get(eo_obj);
482 }
483
484 int
_evas_image_animated_frame_count_get(const Eo * eo_obj)485 _evas_image_animated_frame_count_get(const Eo *eo_obj)
486 {
487 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
488 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
489
490 if (!ENFN->image_animated_frame_count_get ||
491 !evas_object_image_animated_get(eo_obj))
492 return -1;
493
494 obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
495 return ENFN->image_animated_frame_count_get(ENC, o->engine_data);
496 }
497
498 EOLIAN static int
_efl_canvas_image_efl_gfx_frame_controller_frame_count_get(const Eo * eo_obj,void * _pd EINA_UNUSED)499 _efl_canvas_image_efl_gfx_frame_controller_frame_count_get(const Eo *eo_obj, void *_pd EINA_UNUSED)
500 {
501 return _evas_image_animated_frame_count_get(eo_obj);
502 }
503
504 Efl_Gfx_Frame_Controller_Loop_Hint
_evas_image_animated_loop_type_get(const Eo * eo_obj)505 _evas_image_animated_loop_type_get(const Eo *eo_obj)
506 {
507 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
508 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
509
510 if (!ENFN->image_animated_loop_type_get ||
511 !evas_object_image_animated_get(eo_obj))
512 return EFL_GFX_FRAME_CONTROLLER_LOOP_HINT_NONE;
513
514 return (Efl_Gfx_Frame_Controller_Loop_Hint) ENFN->image_animated_loop_type_get(ENC, o->engine_data);
515 }
516
517 EOLIAN static Efl_Gfx_Frame_Controller_Loop_Hint
_efl_canvas_image_efl_gfx_frame_controller_loop_type_get(const Eo * eo_obj,void * _pd EINA_UNUSED)518 _efl_canvas_image_efl_gfx_frame_controller_loop_type_get(const Eo *eo_obj, void *_pd EINA_UNUSED)
519 {
520 return _evas_image_animated_loop_type_get(eo_obj);
521 }
522
523 int
_evas_image_animated_loop_count_get(const Eo * eo_obj)524 _evas_image_animated_loop_count_get(const Eo *eo_obj)
525 {
526 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
527 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
528
529 if (!ENFN->image_animated_loop_count_get ||
530 !evas_object_image_animated_get(eo_obj))
531 return -1;
532
533 return ENFN->image_animated_loop_count_get(ENC, o->engine_data);
534 }
535
536 EOLIAN static int
_efl_canvas_image_efl_gfx_frame_controller_loop_count_get(const Eo * eo_obj,void * _pd EINA_UNUSED)537 _efl_canvas_image_efl_gfx_frame_controller_loop_count_get(const Eo *eo_obj, void *_pd EINA_UNUSED)
538 {
539 return _evas_image_animated_loop_count_get(eo_obj);
540 }
541
542 double
_evas_image_animated_frame_duration_get(const Eo * eo_obj,int start_frame,int frame_num)543 _evas_image_animated_frame_duration_get(const Eo *eo_obj, int start_frame, int frame_num)
544 {
545 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
546 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
547 int frame_count = 0;
548
549 if (!ENFN->image_animated_frame_count_get ||
550 !ENFN->image_animated_frame_duration_get)
551 return -1.0;
552
553 frame_count = ENFN->image_animated_frame_count_get(ENC, o->engine_data);
554 if ((start_frame + frame_num) > frame_count)
555 return -1.0;
556
557 return ENFN->image_animated_frame_duration_get(ENC, o->engine_data, start_frame, frame_num);
558 }
559
560 EOLIAN static double
_efl_canvas_image_efl_gfx_frame_controller_frame_duration_get(const Eo * eo_obj,void * _pd EINA_UNUSED,int start_frame,int frame_num)561 _efl_canvas_image_efl_gfx_frame_controller_frame_duration_get(const Eo *eo_obj, void *_pd EINA_UNUSED, int start_frame, int frame_num)
562 {
563 return _evas_image_animated_frame_duration_get(eo_obj, start_frame, frame_num);
564 }
565
_efl_canvas_image_efl_gfx_frame_controller_sector_set(Eo * obj EINA_UNUSED,void * _pd EINA_UNUSED,const char * name EINA_UNUSED,int startframe EINA_UNUSED,int endframe EINA_UNUSED)566 Eina_Bool _efl_canvas_image_efl_gfx_frame_controller_sector_set(Eo *obj EINA_UNUSED,
567 void *_pd EINA_UNUSED,
568 const char *name EINA_UNUSED,
569 int startframe EINA_UNUSED,
570 int endframe EINA_UNUSED)
571 {
572 // TODO: We need to implement the feature to section playback of image animation.
573 ERR("efl_gfx_frame_controller_sector_set not implemented for efl_canvas_image yet.");
574 return EINA_FALSE;
575 }
576
_efl_canvas_image_efl_gfx_frame_controller_sector_get(const Eo * obj EINA_UNUSED,void * _pd EINA_UNUSED,const char * name EINA_UNUSED,int * startframe EINA_UNUSED,int * endframe EINA_UNUSED)577 Eina_Bool _efl_canvas_image_efl_gfx_frame_controller_sector_get(const Eo *obj EINA_UNUSED,
578 void *_pd EINA_UNUSED,
579 const char *name EINA_UNUSED,
580 int *startframe EINA_UNUSED,
581 int *endframe EINA_UNUSED)
582 {
583 // TODO: We need to implement the feature to section playback of image animation.
584 ERR("efl_gfx_frame_controller_sector_get not implemented for efl_canvas_image yet.");
585 return EINA_FALSE;
586 }
587
588 Eina_Bool
_evas_image_animated_frame_set(Eo * eo_obj,int frame_index)589 _evas_image_animated_frame_set(Eo *eo_obj, int frame_index)
590 {
591 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
592 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
593 int frame_count = 0;
594
595 if (!o->cur->f) return EINA_FALSE;
596 if (o->cur->frame == frame_index) return EINA_TRUE;
597
598 if (!evas_object_image_animated_get(eo_obj)) return EINA_FALSE;
599 evas_object_async_block(obj);
600 frame_count = evas_object_image_animated_frame_count_get(eo_obj);
601
602 /* limit the size of frame to FRAME_MAX */
603 if ((frame_count > FRAME_MAX) || (frame_count < 0) || (frame_index > frame_count))
604 return EINA_FALSE;
605
606 if (!ENFN->image_animated_frame_set) return EINA_FALSE;
607 ENFN->image_animated_frame_set(ENC, o->engine_data, frame_index);
608 // if (!ENFN->image_animated_frame_set(ENC, o->engine_data, frame_index)) return;
609
610 EINA_COW_WRITE_BEGIN(evas_object_image_state_cow, o->prev, Evas_Object_Image_State, prev_write)
611 prev_write->frame = o->cur->frame;
612 EINA_COW_WRITE_END(evas_object_image_state_cow, o->prev, prev_write);
613
614 EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
615 state_write->frame = frame_index;
616 EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
617
618 o->changed = EINA_TRUE;
619 evas_object_change(eo_obj, obj);
620
621 return EINA_TRUE;
622 }
623
624 EOLIAN static Eina_Bool
_efl_canvas_image_efl_gfx_frame_controller_frame_set(Eo * eo_obj,void * _pd EINA_UNUSED,int frame_index)625 _efl_canvas_image_efl_gfx_frame_controller_frame_set(Eo *eo_obj, void *_pd EINA_UNUSED, int frame_index)
626 {
627 return _evas_image_animated_frame_set(eo_obj, frame_index);
628 }
629
630 int
_evas_image_animated_frame_get(const Eo * eo_obj)631 _evas_image_animated_frame_get(const Eo *eo_obj)
632 {
633 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
634
635 if (!o->cur->f) return EINA_FALSE;
636 if (!evas_object_image_animated_get(eo_obj)) return EINA_FALSE;
637 return o->cur->frame;
638 }
639
640 EOLIAN static int
_efl_canvas_image_efl_gfx_frame_controller_frame_get(const Eo * eo_obj,void * _pd EINA_UNUSED)641 _efl_canvas_image_efl_gfx_frame_controller_frame_get(const Eo *eo_obj, void *_pd EINA_UNUSED)
642 {
643 return _evas_image_animated_frame_get(eo_obj);
644 }
645
646 EOLIAN static Eina_Size2D
_efl_canvas_image_efl_gfx_buffer_buffer_size_get(const Eo * eo_obj,void * _pd EINA_UNUSED)647 _efl_canvas_image_efl_gfx_buffer_buffer_size_get(const Eo *eo_obj, void *_pd EINA_UNUSED)
648 {
649 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
650
651 return EINA_SIZE2D(o->cur->image.w, o->cur->image.h);
652 }
653
654 static Eina_Bool
_image_pixels_set(Evas_Object_Protected_Data * obj,Evas_Image_Data * o,const Eina_Slice * slice,int w,int h,int stride,Efl_Gfx_Colorspace cspace,int plane,Eina_Bool copy)655 _image_pixels_set(Evas_Object_Protected_Data *obj,
656 Evas_Image_Data *o, const Eina_Slice *slice,
657 int w, int h, int stride, Efl_Gfx_Colorspace cspace, int plane,
658 Eina_Bool copy)
659 {
660 Eina_Bool resized = EINA_FALSE, ret = EINA_FALSE;
661 int int_stride = 0;
662
663 // FIXME: buffer border support is not implemented
664
665 if (ENFN->image_data_maps_get)
666 {
667 if (ENFN->image_data_maps_get(ENC, o->engine_data, NULL) > 0)
668 {
669 ERR("can not set pixels when there are open memory maps");
670 return EINA_FALSE;
671 }
672 }
673
674 if (o->pixels_checked_out)
675 {
676 // is there anything to do?
677 ERR("Calling efl_gfx_buffer_%s_set after evas_object_image_data_get is "
678 "not valid.", copy ? "copy" : "managed");
679 return EINA_FALSE;
680 }
681
682 if (o->engine_data)
683 {
684 Evas_Colorspace ics;
685 int iw = 0, ih = 0;
686 Eina_Bool alpha;
687
688 ENFN->image_size_get(ENC, o->engine_data, &iw, &ih);
689 ics = ENFN->image_colorspace_get(ENC, o->engine_data);
690 alpha = ENFN->image_alpha_get(ENC, o->engine_data);
691 if ((w != iw) || (h != ih) || (ics != (Evas_Colorspace)cspace) || (alpha != o->cur->has_alpha))
692 {
693 ENFN->image_free(ENC, o->engine_data);
694 o->engine_data = NULL;
695 }
696 }
697
698 if (!slice || !slice->mem)
699 {
700 // note: we release all planes at once
701 if (o->engine_data)
702 ENFN->image_free(ENC, o->engine_data);
703 o->engine_data = ENFN->image_new_from_copied_data(ENC, w, h, NULL, o->cur->has_alpha, (Evas_Colorspace)cspace);
704 }
705 else
706 {
707 o->buffer_data_set = EINA_TRUE;
708 o->engine_data = ENFN->image_data_slice_add(ENC, o->engine_data,
709 slice, copy, w, h, stride,
710 (Evas_Colorspace)cspace, plane, o->cur->has_alpha);
711 }
712
713 if (!o->engine_data)
714 {
715 ERR("Failed to create internal image");
716 goto end;
717 }
718
719 if ((o->cur->image.w != w) || (o->cur->image.h != h))
720 resized = EINA_TRUE;
721
722 if (ENFN->image_scale_hint_set)
723 ENFN->image_scale_hint_set(ENC, o->engine_data, o->scale_hint);
724
725 if (ENFN->image_content_hint_set)
726 ENFN->image_content_hint_set(ENC, o->engine_data, o->content_hint);
727
728 if (ENFN->image_stride_get)
729 ENFN->image_stride_get(ENC, o->engine_data, &int_stride);
730
731 if (resized || o->cur->f || o->cur->key ||
732 (o->cur->image.stride != int_stride) || (cspace != (Efl_Gfx_Colorspace)o->cur->cspace))
733 {
734 EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, cur)
735 {
736 cur->f = NULL;
737 cur->key = NULL;
738 cur->cspace = (Evas_Colorspace)cspace;
739 cur->image.w = w;
740 cur->image.h = h;
741 cur->image.stride = int_stride;
742 }
743 EINA_COW_IMAGE_STATE_WRITE_END(o, cur)
744 }
745
746 ret = EINA_TRUE;
747
748 end:
749 o->written = EINA_TRUE;
750 if (resized)
751 evas_object_inform_call_image_resize(obj->object);
752
753 efl_gfx_buffer_update_add(obj->object, NULL);
754 return ret;
755 }
756
757 EOLIAN static Eina_Bool
_efl_canvas_image_efl_gfx_buffer_buffer_managed_set(Eo * eo_obj,void * _pd EINA_UNUSED,const Eina_Slice * slice,Eina_Size2D size,int stride,Efl_Gfx_Colorspace cspace,int plane)758 _efl_canvas_image_efl_gfx_buffer_buffer_managed_set(Eo *eo_obj, void *_pd EINA_UNUSED,
759 const Eina_Slice *slice,
760 Eina_Size2D size, int stride,
761 Efl_Gfx_Colorspace cspace,
762 int plane)
763 {
764 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
765 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
766
767 return _image_pixels_set(obj, o, slice, size.w, size.h, stride, cspace, plane, EINA_FALSE);
768 }
769
770 EOLIAN static Eina_Bool
_efl_canvas_image_efl_gfx_buffer_buffer_copy_set(Eo * eo_obj,void * _pd EINA_UNUSED,const Eina_Slice * slice,Eina_Size2D size,int stride,Efl_Gfx_Colorspace cspace,int plane)771 _efl_canvas_image_efl_gfx_buffer_buffer_copy_set(Eo *eo_obj, void *_pd EINA_UNUSED,
772 const Eina_Slice *slice, Eina_Size2D size, int stride,
773 Efl_Gfx_Colorspace cspace, int plane)
774 {
775 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
776 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
777
778 return _image_pixels_set(obj, o, slice, size.w, size.h, stride, cspace, plane, EINA_TRUE);
779 }
780
781 EOLIAN static Eina_Slice
_efl_canvas_image_efl_gfx_buffer_buffer_managed_get(Eo * eo_obj,void * _pd EINA_UNUSED,int plane)782 _efl_canvas_image_efl_gfx_buffer_buffer_managed_get(Eo *eo_obj, void *_pd EINA_UNUSED,
783 int plane)
784 {
785 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
786 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
787 Evas_Colorspace cspace = EVAS_COLORSPACE_ARGB8888;
788 Eina_Slice slice = {};
789
790 if (!o->buffer_data_set || !o->engine_data || !ENFN->image_data_direct_get)
791 return slice;
792
793 ENFN->image_data_direct_get(ENC, o->engine_data, plane, &slice, &cspace, EINA_FALSE, NULL);
794
795 return slice;
796 }
797
798 EOLIAN static Eina_Rw_Slice
_efl_canvas_image_efl_gfx_buffer_buffer_map(Eo * eo_obj,void * _pd EINA_UNUSED,Efl_Gfx_Buffer_Access_Mode mode,const Eina_Rect * region,Efl_Gfx_Colorspace cspace,int plane,int * stride)799 _efl_canvas_image_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED,
800 Efl_Gfx_Buffer_Access_Mode mode,
801 const Eina_Rect *region,
802 Efl_Gfx_Colorspace cspace,
803 int plane, int *stride)
804 {
805 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
806 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
807 int s = 0, width = 0, height = 0;
808 Eina_Rw_Slice slice = {};
809 int x, y, w, h;
810
811 if (!ENFN->image_data_map)
812 goto end; // not implemented
813
814 if (o->engine_data)
815 ENFN->image_size_get(ENC, o->engine_data, &width, &height);
816
817 if (!o->engine_data || !width || !height)
818 {
819 // TODO: Create a map_surface and draw there. Maybe. This could
820 // depend on the flags (eg. add a "force render" flag).
821 WRN("This image image has no data available");
822 goto end;
823 }
824
825 if (region)
826 {
827 x = region->x;
828 y = region->y;
829 w = region->w;
830 h = region->h;
831 }
832 else
833 {
834 x = y = 0;
835 w = width;
836 h = height;
837 }
838
839 if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || ((x + w) > width) || ((y + h) > height))
840 {
841 ERR("Invalid map dimensions: %dx%d +%d,%d. Image is %dx%d.",
842 w, h, x, y, width, height);
843 goto end;
844 }
845
846 if (ENFN->image_data_map(ENC, &o->engine_data, &slice, &s, x, y, w, h, (Evas_Colorspace)cspace, mode, plane))
847 {
848 DBG("map(%p, %d,%d %dx%d plane:%d) -> " EINA_SLICE_FMT,
849 eo_obj, x, y, w, h, plane, EINA_SLICE_PRINT(slice));
850 }
851 else DBG("map(%p, %d,%d %dx%d plane:%d) -> (null)", eo_obj, x, y, w, h, plane);
852
853 end:
854 if (stride) *stride = s;
855 return slice;
856 }
857
858 EOLIAN static Eina_Bool
_efl_canvas_image_efl_gfx_buffer_buffer_unmap(Eo * eo_obj,void * _pd EINA_UNUSED,Eina_Rw_Slice slice)859 _efl_canvas_image_efl_gfx_buffer_buffer_unmap(Eo *eo_obj, void *_pd EINA_UNUSED,
860 Eina_Rw_Slice slice)
861 {
862 Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
863 Evas_Image_Data *o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
864
865 if (!slice.mem || !ENFN->image_data_unmap || !o->engine_data)
866 return EINA_FALSE;
867
868 if (!ENFN->image_data_unmap(ENC, o->engine_data, &slice))
869 return EINA_FALSE;
870
871 return EINA_TRUE;
872 }
873
874 EOLIAN static void
_efl_canvas_image_efl_object_dbg_info_get(Eo * obj,void * pd EINA_UNUSED,Efl_Dbg_Info * root)875 _efl_canvas_image_efl_object_dbg_info_get(Eo *obj, void *pd EINA_UNUSED, Efl_Dbg_Info *root)
876 {
877 efl_dbg_info_get(efl_super(obj, MY_CLASS), root);
878
879 if ((efl_gfx_image_load_error_get(obj) != EFL_GFX_IMAGE_LOAD_ERROR_NONE) &&
880 (root))
881 {
882 Efl_Dbg_Info *group = EFL_DBG_INFO_LIST_APPEND(root, MY_CLASS_NAME);
883 Eina_Error error = EFL_GFX_IMAGE_LOAD_ERROR_GENERIC;
884
885 error = efl_gfx_image_load_error_get(obj);
886 EFL_DBG_INFO_APPEND(group, "Load Error", EINA_VALUE_TYPE_STRING,
887 eina_error_msg_get(error));
888 }
889 }
890
891 #define EFL_CANVAS_IMAGE_EXTRA_OPS \
892 EFL_OBJECT_OP_FUNC(efl_dbg_info_get, _efl_canvas_image_efl_object_dbg_info_get)
893
894 #include "efl_canvas_image.eo.c"
895