From fcb6b68b91aa4b0c9f75424ef80a9cdca4b0acef Mon Sep 17 00:00:00 2001 From: Youngbok Shin Date: Fri, 8 Apr 2016 11:17:51 +0100 Subject: [PATCH] Evas: Add API to reinit the language and use it in elementary. Summary: evas_common_language_from_locale_* functions kept static pointers inside of its functions. Once these function was called, it was never reset. It made big problems for harfbuzz and hyphenation. Also, Elementary provides elm_language_set() API. Then we need to support it fully. @fix Test Plan: Test case for hyphenation is included in Evas test suite. Reviewers: raster, tasn, herdsman, woohyun, z-wony, Blackmole, minudf Subscribers: cedric, jpeg Differential Revision: https://phab.enlightenment.org/D3864 Conflicts: src/lib/elementary/elm_main.c The change for elementary will be applied at elementary git. Change-Id: I747fc027973538c2d04180c23dce4c19c307419d --- src/lib/evas/Evas_Common.h | 10 +++++++++ src/lib/evas/canvas/evas_main.c | 6 ++++++ src/lib/evas/common/language/evas_language_utils.c | 19 ++++++++++------ src/lib/evas/common/language/evas_language_utils.h | 3 +++ src/tests/evas/evas_test_textblock.c | 25 ++++++++++++++++++++-- 5 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/lib/evas/Evas_Common.h b/src/lib/evas/Evas_Common.h index a32d674..d6cc319 100755 --- a/src/lib/evas/Evas_Common.h +++ b/src/lib/evas/Evas_Common.h @@ -5345,6 +5345,16 @@ EAPI int evas_string_char_prev_get(const char *str, int pos, int *decoded) EINA EAPI int evas_string_char_len_get(const char *str) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); /** + * Reinitialize language from the environment. + * + * The locale can change while a process is running. This call tells evas to + * reload the locale from the environment like it does on start. + * @ingroup Evas_Utils + * @since 1.18 + */ +EAPI void evas_language_reinit(void); + +/** * @defgroup Evas_Keys Key Input Functions * * Functions which feed key events to the canvas. diff --git a/src/lib/evas/canvas/evas_main.c b/src/lib/evas/canvas/evas_main.c index bdafc31..e5b184d 100644 --- a/src/lib/evas/canvas/evas_main.c +++ b/src/lib/evas/canvas/evas_main.c @@ -705,4 +705,10 @@ evas_ector_get(Evas_Public_Data *e) return e->engine.ector; } +EAPI void +evas_language_reinit(void) +{ + evas_common_language_reinit(); +} + #include "canvas/evas_canvas.eo.c" diff --git a/src/lib/evas/common/language/evas_language_utils.c b/src/lib/evas/common/language/evas_language_utils.c index 737b510..bd36e55 100644 --- a/src/lib/evas/common/language/evas_language_utils.c +++ b/src/lib/evas/common/language/evas_language_utils.c @@ -41,6 +41,9 @@ #define EXPLICIT_SCRIPT(script) \ (((script) != EVAS_SCRIPT_UNKNOWN) && ((script) > EVAS_SCRIPT_INHERITED)) +static char lang[6]; /* FIXME: Maximum length I know about */ +static char lang_full[32]; + static Evas_Script_Type _evas_common_language_char_script_search(Eina_Unicode unicode) { @@ -131,7 +134,6 @@ evas_common_language_script_type_get(const Eina_Unicode *str, size_t len) const char * evas_common_language_from_locale_get(void) { - static char lang[6]; /* FIXME: Maximum length I know about */ if (*lang) return lang; const char *locale; @@ -159,8 +161,7 @@ evas_common_language_from_locale_get(void) const char * evas_common_language_from_locale_full_get(void) { - static char lang[32]; - if (*lang) return lang; + if (*lang_full) return lang_full; const char *locale; locale = setlocale(LC_MESSAGES, NULL); @@ -173,14 +174,20 @@ evas_common_language_from_locale_full_get(void) if ((c == '.') || (c == '@') || (c == ' ')) /* Looks like en_US.UTF8 or de_DE@euro or aa_ER UTF-8*/ break; } - strncpy(lang, locale, i); - lang[i] = '\0'; - return lang; + strncpy(lang_full, locale, i); + lang_full[i] = '\0'; + return lang_full; } return ""; } +void +evas_common_language_reinit(void) +{ + *lang = *lang_full = '\0'; +} + /* * @} */ diff --git a/src/lib/evas/common/language/evas_language_utils.h b/src/lib/evas/common/language/evas_language_utils.h index 5e24912..8c7529a 100644 --- a/src/lib/evas/common/language/evas_language_utils.h +++ b/src/lib/evas/common/language/evas_language_utils.h @@ -131,5 +131,8 @@ evas_common_language_from_locale_get(void); const char * evas_common_language_from_locale_full_get(void); + +void +evas_common_language_reinit(void); #endif diff --git a/src/tests/evas/evas_test_textblock.c b/src/tests/evas/evas_test_textblock.c index 400175e..011cd49 100644 --- a/src/tests/evas/evas_test_textblock.c +++ b/src/tests/evas/evas_test_textblock.c @@ -3676,11 +3676,31 @@ _hyphenation_width_stress(Evas_Object *tb, Evas_Textblock_Cursor *cur) START_TEST(evas_textblock_hyphenation) { START_TB_TEST(); + Evas_Coord w, fw; + + const char *buf = "Automati-"; + evas_object_textblock_text_markup_set(tb, buf); + evas_object_textblock_size_formatted_get(tb, &w, NULL); + evas_object_resize(tb, w, 100); + + setlocale(LC_MESSAGES, "en_US.UTF-8"); + /* Language should be reinitialized after calling setlocale(). */ + evas_language_reinit(); + + buf = "Automatically"; + evas_object_textblock_text_markup_set(tb, buf); + evas_textblock_cursor_format_prepend(cur, ""); + evas_object_textblock_size_formatted_get(tb, &fw, NULL); + ck_assert_int_eq(w, fw); + + /* Restore locale */ + setlocale(LC_MESSAGES, "C"); + evas_language_reinit(); /* SHY-HYPHEN (­) */ /* Note: placing ­ in a ligature is errornuos, so for the sake * of this test, it was removed from the "officia" word */ - const char *buf = + buf = "Lorem ipsum dolor sit amet, cons­ectetur adipisicing elit," " sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." " Ut enim ad minim veniam, quis nostrud exer­citation ullamco" @@ -3693,7 +3713,8 @@ START_TEST(evas_textblock_hyphenation) evas_object_textblock_text_markup_set(tb, buf); /* Dictionary + locale fallback (en_US) */ - setlocale(LC_MESSAGES, "en_US.UTF8"); + setlocale(LC_MESSAGES, "en_US.UTF-8"); + evas_language_reinit(); /* Mixture of Dictionary with SHY-HYPHEN */ _hyphenation_width_stress(tb, cur); -- 2.7.4