Evas textblock: Save memory space reducing unused hyphen dictionary loads

Summary:
Commonly, only few hyphenation dictionaries are used at a application.
So, loading all of dictionary files could cause waste of memory.
Evas textblock has to load hyphenation dictionaries only when it is
really needed.

Test Plan: N/A

Reviewers: woohyun, tasn, herdsman

Subscribers: cedric, jpeg

Differential Revision: https://phab.enlightenment.org/D3626
This commit is contained in:
Youngbok Shin 2016-02-04 11:29:03 +02:00 committed by Daniel Hirt
parent 497a287f07
commit 931b225895
2 changed files with 22 additions and 16 deletions

View File

@ -1900,7 +1900,7 @@ _format_command(Evas_Object *eo_obj, Evas_Object_Textblock_Format *fmt, const ch
* the hyphenation dictionaries on-demand. */ * the hyphenation dictionaries on-demand. */
if (fmt->wrap_hyphenation) if (fmt->wrap_hyphenation)
{ {
_dicts_hyphen_update(eo_obj); _dicts_hyphen_init(eo_obj);
} }
#endif #endif
@ -11976,7 +11976,7 @@ evas_object_textblock_free(Evas_Object *eo_obj)
/* Hyphenation */ /* Hyphenation */
if (o->hyphenating) if (o->hyphenating)
{ {
_dicts_hyphen_detach(); _dicts_hyphen_detach(eo_obj);
} }
#endif #endif
} }

View File

@ -11,16 +11,12 @@ typedef struct
/* Hyphenation dictionaries */ /* Hyphenation dictionaries */
static Dict_Hyphen _dicts_hyphen[64]; static Dict_Hyphen _dicts_hyphen[64];
static Eina_Bool _dicts_hyphen_init = EINA_FALSE;
static size_t _hyphens_num = 0; static size_t _hyphens_num = 0;
static size_t _hyphen_clients = 0; static size_t _hyphen_clients = 0;
static void static void
_dicts_hyphen_update(Eo *eo_obj) _dicts_hyphen_init(Eo *eo_obj)
{ {
Eina_Iterator *it;
Eina_File_Direct_Info *dir;
Evas_Textblock_Data *o = eo_data_scope_get(eo_obj, MY_CLASS); Evas_Textblock_Data *o = eo_data_scope_get(eo_obj, MY_CLASS);
if (!o->hyphenating) if (!o->hyphenating)
@ -28,18 +24,22 @@ _dicts_hyphen_update(Eo *eo_obj)
_hyphen_clients++; _hyphen_clients++;
o->hyphenating = EINA_TRUE; o->hyphenating = EINA_TRUE;
} }
}
if (_dicts_hyphen_init) return; static void *
_dict_hyphen_load(const char *lang)
{
Eina_Iterator *it;
Eina_File_Direct_Info *dir;
void *dict;
it = eina_file_direct_ls(EVAS_DICTS_HYPHEN_DIR); it = eina_file_direct_ls(EVAS_DICTS_HYPHEN_DIR);
if (!it) if (!it)
{ {
ERR("Couldn't list files in hyphens path: %s\n", EVAS_DICTS_HYPHEN_DIR); ERR("Couldn't list files in hyphens path: %s\n", EVAS_DICTS_HYPHEN_DIR);
return; return NULL;
} }
_dicts_hyphen_init = EINA_TRUE;
/* The following is based on how files are installed in arch linux: /* The following is based on how files are installed in arch linux:
* the files are in the pattern of "hyph_xx_XX.dic" (e.g. hyph_en_US.dic). * the files are in the pattern of "hyph_xx_XX.dic" (e.g. hyph_en_US.dic).
* We are actually trying a bit more in case these are installed in another * We are actually trying a bit more in case these are installed in another
@ -49,7 +49,6 @@ _dicts_hyphen_update(Eo *eo_obj)
const char *file = dir->path + dir->name_start; const char *file = dir->path + dir->name_start;
char *prefix_off; /* 'hyph_' prefix (may be in some distros) */ char *prefix_off; /* 'hyph_' prefix (may be in some distros) */
char *dic_off; /* '.dic' file extension offset */ char *dic_off; /* '.dic' file extension offset */
void *dict;
/* Check a few assumptions and reject if aren't met. */ /* Check a few assumptions and reject if aren't met. */
prefix_off = strstr(file, "hyph_"); prefix_off = strstr(file, "hyph_");
@ -57,7 +56,7 @@ _dicts_hyphen_update(Eo *eo_obj)
if (!dic_off || ((size_t) (dic_off - file) + 4 != dir->name_length) || if (!dic_off || ((size_t) (dic_off - file) + 4 != dir->name_length) ||
(dic_off - file < 5) || (dic_off - file < 5) ||
((dic_off - file > 0) && !prefix_off) || ((dic_off - file > 0) && !prefix_off) ||
strncmp(dic_off, ".dic", 4)) strncmp(dic_off, ".dic", 4) || strncmp((dic_off - 5), lang, strlen(lang)))
{ {
continue; continue;
} }
@ -70,9 +69,12 @@ _dicts_hyphen_update(Eo *eo_obj)
} }
_dicts_hyphen[_hyphens_num].lang = strndup(dic_off - 5, 5); _dicts_hyphen[_hyphens_num].lang = strndup(dic_off - 5, 5);
_dicts_hyphen[_hyphens_num++].dict = dict; _dicts_hyphen[_hyphens_num++].dict = dict;
break;
} }
if (it) eina_iterator_free(it); if (it) eina_iterator_free(it);
return dict;
} }
static void static void
@ -86,12 +88,15 @@ _dicts_hyphen_free(void)
} }
_hyphens_num = 0; _hyphens_num = 0;
_dicts_hyphen_init = EINA_FALSE;
} }
static inline void static inline void
_dicts_hyphen_detach(void) _dicts_hyphen_detach(Eo *eo_obj)
{ {
Evas_Textblock_Data *o = eo_data_scope_get(eo_obj, MY_CLASS);
if (!o->hyphenating) return;
o->hyphenating = EINA_FALSE;
_hyphen_clients--; _hyphen_clients--;
if (_hyphen_clients == 0) _dicts_hyphen_free(); if (_hyphen_clients == 0) _dicts_hyphen_free();
} }
@ -114,7 +119,8 @@ _hyphen_dict_get_from_lang(const char *lang)
return _dicts_hyphen[i].dict; return _dicts_hyphen[i].dict;
} }
} }
return NULL;
return _dict_hyphen_load(lang);
} }
static char * static char *