diff --git a/src/lib/evas/canvas/efl_canvas_vg_object.c b/src/lib/evas/canvas/efl_canvas_vg_object.c index abff8069aa..9fc2d5e6f8 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_object.c +++ b/src/lib/evas/canvas/efl_canvas_vg_object.c @@ -244,26 +244,55 @@ _efl_canvas_vg_object_viewbox_align_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Vg if (align_y) *align_y = pd->align_y; } +EOLIAN static Eina_Error +_efl_canvas_vg_object_efl_file_file_set(Eo *eo_obj, Efl_Canvas_Vg_Object_Data *pd EINA_UNUSED, const char *file) +{ + /* Careful: delete previous vg entry. + When a new efl file is set, ex-file will be invalid. + Since vg cache hashes all file entries, + we must remove it from vg cache before we lost file handle. */ + if (efl_file_loaded_get(eo_obj)) + { + const char *pname = efl_file_get(eo_obj); + int pl = pname ? strlen(pname) : 0; + int cl = file ? strlen(file) : 0; + + if ((pl != cl) || strcmp(pname, file)) + { + Evas_Object_Protected_Data *obj; + obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); + evas_cache_vg_entry_del(pd->vg_entry); + evas_object_change(eo_obj, obj); + pd->vg_entry = NULL; + evas_object_change(eo_obj, obj); + } + } + + Eina_Error err; + err = efl_file_set(efl_super(eo_obj, MY_CLASS), file); + if (err) return err; + + return 0; +} + EOLIAN static Eina_Error _efl_canvas_vg_object_efl_file_load(Eo *eo_obj, Efl_Canvas_Vg_Object_Data *pd) { - Vg_Cache_Entry *old_entry; - const char *file; + Eina_Error err; + if (efl_file_loaded_get(eo_obj)) return 0; - file = efl_file_get(eo_obj); - if (!file) return ENOENT; - - old_entry = pd->vg_entry; + err = efl_file_load(efl_super(eo_obj, MY_CLASS)); + if (err) return err; + const Eina_File *file = efl_file_mmap_get(eo_obj); + const char *key = efl_file_key_get(eo_obj); Evas_Object_Protected_Data *obj; - obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); - pd->vg_entry = evas_cache_vg_entry_create(file, efl_file_key_get(eo_obj), + obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); + pd->vg_entry = evas_cache_vg_entry_create(file, key, obj->cur->geometry.w, obj->cur->geometry.h); - evas_object_change(eo_obj, obj); - evas_cache_vg_entry_del(old_entry); return 0; } @@ -271,18 +300,13 @@ _efl_canvas_vg_object_efl_file_load(Eo *eo_obj, Efl_Canvas_Vg_Object_Data *pd) EOLIAN static void _efl_canvas_vg_object_efl_file_unload(Eo *eo_obj, Efl_Canvas_Vg_Object_Data *pd) { - Vg_Cache_Entry *old_entry; - if (!efl_file_loaded_get(eo_obj)) return; - old_entry = pd->vg_entry; Evas_Object_Protected_Data *obj; obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); - - pd->vg_entry = NULL; - + evas_cache_vg_entry_del(pd->vg_entry); evas_object_change(eo_obj, obj); - evas_cache_vg_entry_del(old_entry); + pd->vg_entry = NULL; } EOLIAN static Eina_Bool diff --git a/src/lib/evas/canvas/efl_canvas_vg_object.eo b/src/lib/evas/canvas/efl_canvas_vg_object.eo index f46f32e20c..02562a4f56 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_object.eo +++ b/src/lib/evas/canvas/efl_canvas_vg_object.eo @@ -74,6 +74,7 @@ class @beta Efl.Canvas.Vg.Object extends Efl.Canvas.Object implements Efl.File, Efl.Object.destructor; Efl.File.load; Efl.File.unload; + Efl.File.file { set; } Efl.File_Save.save; } } diff --git a/src/lib/evas/canvas/evas_vg_private.h b/src/lib/evas/canvas/evas_vg_private.h index 7fb62d4827..f4c47de4bb 100644 --- a/src/lib/evas/canvas/evas_vg_private.h +++ b/src/lib/evas/canvas/evas_vg_private.h @@ -19,14 +19,13 @@ typedef struct _Vg_Cache typedef struct _Vg_Cache_Entry { char *hash_key; - Eina_Stringshare *file; + const Eina_File *file; Eina_Stringshare *key; int w; int h; Efl_VG *root; int ref; Vg_File_Data *vfd; - } Vg_Cache_Entry; // holds the vg tree info set by the user @@ -119,10 +118,10 @@ struct _Efl_Canvas_Vg_Interpolation void evas_cache_vg_init(void); void evas_cache_vg_shutdown(void); Vg_Cache_Entry* evas_cache_vg_entry_resize(Vg_Cache_Entry *entry, int w, int h); -Vg_Cache_Entry* evas_cache_vg_entry_create(const char *file, const char *key, int w, int h); +Vg_Cache_Entry* evas_cache_vg_entry_create(const Eina_File *file, const char *key, int w, int h); Efl_VG* evas_cache_vg_tree_get(Vg_Cache_Entry *vg_entry); void evas_cache_vg_entry_del(Vg_Cache_Entry *vg_entry); -Vg_File_Data * evas_cache_vg_file_open(const char *file, const char *key); +Vg_File_Data * evas_cache_vg_file_open(const Eina_File *file, const char *key); Eina_Bool evas_cache_vg_file_save(Efl_VG *root, int w, int h, const char *file, const char *key, const Efl_File_Save_Info *info); Eina_Bool evas_cache_vg_entry_file_save(Vg_Cache_Entry *vg_entry, const char *file, const char *key, const Efl_File_Save_Info *info); void efl_canvas_vg_node_vg_obj_set(Efl_VG *node, Efl_VG *vg_obj, Efl_Canvas_Vg_Object_Data *vd); diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index e9b9dc0c57..5a4bd9cc5e 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1523,7 +1523,7 @@ struct _Vg_File_Data struct _Evas_Vg_Load_Func { - Vg_File_Data *(*file_open) (const char *file, const char *key, int *error); + Vg_File_Data *(*file_open) (Eina_File *file, const char *key, int *error); Eina_Bool (*file_close) (Vg_File_Data *vfd); Eina_Bool (*file_data) (Vg_File_Data *vfd); }; diff --git a/src/lib/evas/vg/evas_vg_cache.c b/src/lib/evas/vg/evas_vg_cache.c index 6022982557..534dca2748 100644 --- a/src/lib/evas/vg/evas_vg_cache.c +++ b/src/lib/evas/vg/evas_vg_cache.c @@ -70,7 +70,7 @@ _find_loader_module(const char *file) } static Vg_File_Data * -_vg_load_from_file(const char *file, const char *key) +_vg_load_from_file(const Eina_File *file, const char *key) { Evas_Module *em; Evas_Vg_Load_Func *loader; @@ -78,11 +78,12 @@ _vg_load_from_file(const char *file, const char *key) Vg_File_Data *vfd; unsigned int i; - em = _find_loader_module(file); + const char *file_name = eina_file_filename_get(file); + em = _find_loader_module(file_name); if (em) { loader = em->functions; - vfd = loader->file_open(file, key, &error); + vfd = loader->file_open((Eina_File *) file, key, &error); if (vfd) { vfd->loader = loader; @@ -97,7 +98,8 @@ _vg_load_from_file(const char *file, const char *key) if (em) { loader = em->functions; - vfd = loader->file_open(file, key, &error); + vfd = loader->file_open((Eina_File *) file, key, &error); + if (vfd) { vfd->loader = loader; return vfd; @@ -105,7 +107,7 @@ _vg_load_from_file(const char *file, const char *key) } } } - WRN("Exhausted all means to load vector file = %s", file); + WRN("Exhausted all means to load vector file = %s", file_name); return NULL; } @@ -148,11 +150,12 @@ _evas_cache_vg_entry_free_cb(void *data) if (vg_entry->vfd) { vg_entry->vfd->ref--; + if (vg_entry->vfd->ref <= 0) { Eina_Strbuf *hash_key = eina_strbuf_new(); eina_strbuf_append_printf(hash_key, "%s/%s", - vg_entry->file, + eina_file_filename_get(vg_entry->file), vg_entry->key); if (!eina_hash_del(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key), vg_entry->vfd)) ERR("Failed to delete vfd = (%p) from hash", vg_entry->vfd); @@ -283,13 +286,13 @@ evas_cache_vg_shutdown(void) } Vg_File_Data * -evas_cache_vg_file_open(const char *file, const char *key) +evas_cache_vg_file_open(const Eina_File *file, const char *key) { Vg_File_Data *vfd; Eina_Strbuf *hash_key; hash_key = eina_strbuf_new(); - eina_strbuf_append_printf(hash_key, "%s/%s", file, key); + eina_strbuf_append_printf(hash_key, "%s/%s", eina_file_filename_get(file), key); vfd = eina_hash_find(vg_cache->vfd_hash, eina_strbuf_string_get(hash_key)); if (!vfd) { @@ -308,7 +311,7 @@ evas_cache_vg_entry_resize(Vg_Cache_Entry *vg_entry, int w, int h) } Vg_Cache_Entry* -evas_cache_vg_entry_create(const char *file, +evas_cache_vg_entry_create(const Eina_File *file, const char *key, int w, int h) { @@ -320,7 +323,7 @@ evas_cache_vg_entry_create(const char *file, //TODO: zero-sized entry is useless. how to skip it? hash_key = eina_strbuf_new(); - eina_strbuf_append_printf(hash_key, "%s/%s/%d/%d", file, key, w, h); + eina_strbuf_append_printf(hash_key, "%p/%s/%d/%d", file, key, w, h); vg_entry = eina_hash_find(vg_cache->vg_entry_hash, eina_strbuf_string_get(hash_key)); if (!vg_entry) { @@ -331,7 +334,7 @@ evas_cache_vg_entry_create(const char *file, eina_strbuf_free(hash_key); return NULL; } - vg_entry->file = eina_stringshare_add(file); + vg_entry->file = file; vg_entry->key = eina_stringshare_add(key); vg_entry->w = w; vg_entry->h = h; diff --git a/src/modules/evas/vg_loaders/eet/evas_vg_load_eet.c b/src/modules/evas/vg_loaders/eet/evas_vg_load_eet.c index 3b83b2f541..f0bde2e5ca 100644 --- a/src/modules/evas/vg_loaders/eet/evas_vg_load_eet.c +++ b/src/modules/evas/vg_loaders/eet/evas_vg_load_eet.c @@ -13,13 +13,11 @@ static int _evas_vg_loader_eet_log_dom = -1; #define INF(...) EINA_LOG_DOM_INFO(_evas_vg_loader_eet_log_dom, __VA_ARGS__) static Vg_File_Data* -evas_vg_load_file_open_eet(const char *file, const char *key, int *error EINA_UNUSED) +evas_vg_load_file_open_eet(Eina_File *file, const char *key, int *error EINA_UNUSED) { Eet_Data_Descriptor *svg_node_eet; Svg_Node *node; - Eet_File *ef; - - ef = eet_open(file, EET_FILE_MODE_READ); + Eet_File *ef = eet_mmap(file); if (!ef) { *error = EVAS_LOAD_ERROR_CORRUPT_FILE; diff --git a/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c b/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c index 25e72feb87..243eb548de 100644 --- a/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c +++ b/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c @@ -2339,7 +2339,9 @@ evas_vg_load_file_close_svg(Vg_File_Data *vfd) } static Vg_File_Data* -evas_vg_load_file_open_svg(const char *file, const char *key EINA_UNUSED, int *error EINA_UNUSED) +evas_vg_load_file_open_svg(Eina_File *file, + const char *key EINA_UNUSED, + int *error EINA_UNUSED) { Evas_SVG_Loader loader = { NULL, NULL, NULL, NULL, NULL, 0, EINA_FALSE @@ -2347,18 +2349,10 @@ evas_vg_load_file_open_svg(const char *file, const char *key EINA_UNUSED, int *e const char *content; unsigned int length; Svg_Node *defs; - Eina_File *f; - - f = eina_file_open(file, EINA_FALSE); - if (!f) - { - *error = EVAS_LOAD_ERROR_CORRUPT_FILE; - return NULL; - } loader.svg_parse = calloc(1, sizeof(Evas_SVG_Parser)); - length = eina_file_size_get(f); - content = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); + length = eina_file_size_get(file); + content = eina_file_map_all(file, EINA_FILE_SEQUENTIAL); if (content) { loader.stack = eina_array_new(8); @@ -2366,7 +2360,7 @@ evas_vg_load_file_open_svg(const char *file, const char *key EINA_UNUSED, int *e _evas_svg_loader_parser, &loader); eina_array_free(loader.stack); - eina_file_map_free(f, (void*) content); + eina_file_map_free(file, (void*) content); } if (loader.doc) @@ -2383,7 +2377,7 @@ evas_vg_load_file_open_svg(const char *file, const char *key EINA_UNUSED, int *e *error = EVAS_LOAD_ERROR_GENERIC; } free(loader.svg_parse); - eina_file_close(f); + return vg_common_svg_create_vg_node(loader.doc); }