From 5ff301790036d2e9a841a748c95c6f38901459a2 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sun, 11 Nov 2012 16:54:26 +0000 Subject: Replacing gettext i18n backend by boost::locale one. This commit adds a small and simplistic C wrapper around boost's locale library as intern/locale, and heavily simplifies/reduces Blender's own i18n code (under blenfont/ dir). And it adds back UI translation on windows' official builds (with msvc)! Note to platform maintainers: iconv and gettext (libintl) can now be removed from precompiled libs (not gettext binaries, under windows, of course ;) ). Note to MinGW32/64 users: boost_locale lib has not yet been uploaded for those build env, please disable WITH_INTERNATIONAL for now (hopefully will be fixed very soon, have contacted psy-fy). --- source/blender/blenfont/BLF_translation.h | 26 ++- source/blender/blenfont/CMakeLists.txt | 4 +- source/blender/blenfont/SConscript | 2 +- source/blender/blenfont/intern/blf_lang.c | 240 ++++------------------- source/blender/blenfont/intern/blf_translation.c | 86 ++------ 5 files changed, 72 insertions(+), 286 deletions(-) (limited to 'source/blender/blenfont') diff --git a/source/blender/blenfont/BLF_translation.h b/source/blender/blenfont/BLF_translation.h index b01ce93cb65..d0b5d824bb3 100644 --- a/source/blender/blenfont/BLF_translation.h +++ b/source/blender/blenfont/BLF_translation.h @@ -35,16 +35,6 @@ #define TEXT_DOMAIN_NAME "blender" -/* blf_translation.c */ - -#ifdef WITH_INTERNATIONAL -unsigned char *BLF_get_unifont(int *unifont_size); -void BLF_free_unifont(void); -#endif - -const char *BLF_gettext(const char *msgid); -const char *BLF_pgettext(const char *context, const char *message); - /* blf_lang.c */ /* Search the path directory to the locale files, this try all @@ -61,17 +51,23 @@ void BLF_lang_set(const char *); /* Get the current locale (short code, e.g. es_ES). */ const char *BLF_lang_get(void); -/* Set the current encoding name. */ -void BLF_lang_encoding(const char *str); - /* Get EnumPropertyItem's for translations menu. */ struct EnumPropertyItem *BLF_RNA_lang_enum_properties(void); +/* blf_translation.c */ + +#ifdef WITH_INTERNATIONAL +unsigned char *BLF_get_unifont(int *unifont_size); +void BLF_free_unifont(void); +#endif + +const char *BLF_pgettext(const char *msgctxt, const char *msgid); + /* translation */ int BLF_translate_iface(void); int BLF_translate_tooltips(void); -const char *BLF_translate_do_iface(const char *contex, const char *msgid); -const char *BLF_translate_do_tooltip(const char *contex, const char *msgid); +const char *BLF_translate_do_iface(const char *msgctxt, const char *msgid); +const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid); /* The "translation-marker" macro. */ diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt index 022dfd282b0..90baef14a74 100644 --- a/source/blender/blenfont/CMakeLists.txt +++ b/source/blender/blenfont/CMakeLists.txt @@ -31,6 +31,7 @@ set(INC ../makesrna ../imbuf ../../../intern/guardedalloc + ../../../intern/locale ) set(INC_SYS @@ -54,9 +55,6 @@ set(SRC ) if(WITH_INTERNATIONAL) - list(APPEND INC_SYS - ${GETTEXT_INCLUDE_DIRS} - ) add_definitions(-DWITH_INTERNATIONAL) endif() diff --git a/source/blender/blenfont/SConscript b/source/blender/blenfont/SConscript index 075da58b116..91c9c6789cf 100644 --- a/source/blender/blenfont/SConscript +++ b/source/blender/blenfont/SConscript @@ -4,7 +4,7 @@ Import ('env') sources = env.Glob('intern/*.c') -incs = '. intern #/intern/guardedalloc ../blenkernel ../blenlib ../blenloader' +incs = '. intern #/intern/guardedalloc #/intern/locale ../blenkernel ../blenlib ../blenloader' incs += ' ../makesdna ../makesrna ../imbuf ../editors/include' incs += ' #/extern/glew/include' incs += ' ' + env['BF_FREETYPE_INC'] diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index f02d4a25554..0ed48623dd5 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -28,20 +28,17 @@ */ -#include -#include -#include - -#include "BKE_global.h" - -#include "BLF_api.h" #include "BLF_translation.h" /* own include */ #ifdef WITH_INTERNATIONAL -#include +#include +#include +#include -#include "libintl.h" +#include "boost_locale_wrapper.h" + +#include "BKE_global.h" #include "DNA_userdef_types.h" @@ -49,30 +46,20 @@ #include "MEM_guardedalloc.h" -#include "BLI_string.h" -#include "BLI_utildefines.h" -#include "BLI_path_util.h" #include "BLI_fileops.h" #include "BLI_linklist.h" +#include "BLI_path_util.h" #include "BLI_string.h" - -#define SYSTEM_ENCODING_DEFAULT "UTF-8" -#define FONT_SIZE_DEFAULT 12 +#include "BLI_utildefines.h" /* Locale options. */ -static char global_messagepath[1024]; -static char global_language[32]; -static char global_encoding_name[32]; - static const char **locales = NULL; -static char **long_locales = NULL; /* XXX Temp fix until we get a final solution with modern intl lib under windows! */ static int num_locales = 0; static EnumPropertyItem *locales_menu = NULL; static int num_locales_menu = 0; #define ULANGUAGE ((U.language >= 0 && U.language < num_locales) ? U.language : 0) #define LOCALE(_id) (locales ? locales[_id] : "") -#define LONG_LOCALE(_id) (long_locales ? long_locales[_id] : "") static void free_locales(void) { @@ -84,17 +71,8 @@ static void free_locales(void) MEM_freeN((void *)locales_menu[idx].description); /* Also frees locales's relevant value! */ } - idx = num_locales; - while (idx--) { - if (long_locales[idx]) { - MEM_freeN(long_locales[idx]); - } - } - MEM_freeN(locales); locales = NULL; - MEM_freeN(long_locales); - long_locales = NULL; } if (locales_menu) { MEM_freeN(locales_menu); @@ -140,7 +118,6 @@ static void fill_locales(void) /* Do not allocate locales with zero-sized mem, as LOCALE macro uses NULL locales as invalid marker! */ if (num_locales > 0) { locales = MEM_callocN(num_locales * sizeof(char*), __func__); - long_locales = MEM_callocN(num_locales * sizeof(char*), __func__); while (line) { int id; char *loc, *sep1, *sep2, *sep3; @@ -163,26 +140,28 @@ static void fill_locales(void) sep2++; sep3 = strchr(sep2, ':'); + if (sep3) { locales_menu[idx].identifier = loc = BLI_strdupn(sep2, sep3 - sep2); + } + else { + locales_menu[idx].identifier = loc = BLI_strdup(sep2); + } - if (id == 0) { - /* The DEFAULT item... */ - if (BLI_strnlen(loc, 2)) { - locales[id] = locales_menu[idx].description = BLI_strdup(""); - long_locales[id] = BLI_strdup(""); - } - /* Menu "label", not to be stored in locales! */ - else { - locales_menu[idx].description = BLI_strdup(""); - } + if (id == 0) { + /* The DEFAULT item... */ + if (BLI_strnlen(loc, 2)) { + locales[id] = locales_menu[idx].description = BLI_strdup(""); } + /* Menu "label", not to be stored in locales! */ else { - locales[id] = locales_menu[idx].description = BLI_strdup(loc); - long_locales[id] = BLI_strdup(sep3 + 1); + locales_menu[idx].description = BLI_strdup(""); } - idx++; } + else { + locales[id] = locales_menu[idx].description = BLI_strdup(loc); + } + idx++; } } @@ -207,15 +186,12 @@ void BLF_lang_init(void) { char *messagepath = BLI_get_folder(BLENDER_DATAFILES, "locale"); - BLI_strncpy(global_encoding_name, SYSTEM_ENCODING_DEFAULT, sizeof(global_encoding_name)); - if (messagepath) { - BLI_strncpy(global_messagepath, messagepath, sizeof(global_messagepath)); + bl_locale_init(messagepath, TEXT_DOMAIN_NAME); fill_locales(); } else { printf("%s: 'locale' data path for translations not found, continuing\n", __func__); - global_messagepath[0] = '\0'; } } @@ -224,159 +200,37 @@ void BLF_lang_free(void) free_locales(); } -/* Get LANG/LANGUAGE environment variable. */ -static void get_language_variable(const char *varname, char *var, const size_t maxlen) -{ - char *env = getenv(varname); - - if (env) { - char *s; - - /* Store defaul locale. */ - BLI_strncpy(var, env, maxlen); - - /* Use first language as default. */ - s = strchr(var, ':'); - if (s) - s[0] = 0; - } -} - -/* Get language to be used based on locale (which might be empty when using default language) and - * LANG environment variable. - */ -static void get_language(const char *locale, const char *lang, char *language, const size_t maxlen) -{ - if (locale[0]) { - BLI_strncpy(language, locale, maxlen); - } - else { - char *s; - - BLI_strncpy(language, lang, maxlen); - - s = strchr(language, '.'); - if (s) - s[0] = 0; - } -} - -/* XXX WARNING!!! In osx somehow the previous function call jumps in this one??? (ton, ppc) */ void BLF_lang_set(const char *str) { - char *locreturn; - int ok = TRUE; int ulang = ULANGUAGE; + const char *short_locale = str ? str : LOCALE(ulang); + const char *short_locale_utf8 = NULL; if ((U.transopts & USER_DOTRANSLATE) == 0) return; -#if defined(_WIN32) && !defined(FREE_WINDOWS) - { - const char *long_locale = str ? str : LONG_LOCALE(ulang); - if (long_locale) { - char *envStr; - - if (ulang) - envStr = BLI_sprintfN("LANG=%s", long_locale); - else /* Use system setting. */ - envStr = BLI_sprintfN("LANG=%s", getenv("LANG")); - - gettext_putenv(envStr); - MEM_freeN(envStr); - } - - locreturn = setlocale(LC_ALL, long_locale); - - if (locreturn == NULL) { - if (G.debug & G_DEBUG) - printf("Could not change locale to %s\n", long_locale); - - ok = FALSE; - } - } -#else - { - const char *short_locale = str ? str : LOCALE(ulang); - static char default_lang[64] = "\0"; - static char default_language[64] = "\0"; - - if (default_lang[0] == 0) - get_language_variable("LANG", default_lang, sizeof(default_lang)); - - if (default_language[0] == 0) - get_language_variable("LANGUAGE", default_language, sizeof(default_language)); - - if (short_locale[0]) { - char *short_locale_utf8 = BLI_sprintfN("%s.UTF-8", short_locale); - - if (G.debug & G_DEBUG) - printf("Setting LANG and LANGUAGE to %s\n", short_locale_utf8); - - locreturn = setlocale(LC_ALL, short_locale_utf8); - - if (locreturn != NULL) { - BLI_setenv("LANG", short_locale_utf8); - BLI_setenv("LANGUAGE", short_locale_utf8); - } - else { - if (G.debug & G_DEBUG) - printf("Setting LANG and LANGUAGE to %s\n", short_locale); - - locreturn = setlocale(LC_ALL, short_locale); - - if (locreturn != NULL) { - BLI_setenv("LANG", short_locale); - BLI_setenv("LANGUAGE", short_locale); - } - } - - if (G.debug & G_DEBUG && locreturn == NULL) - printf("Could not change locale to %s nor %s\n", short_locale, short_locale_utf8); - - MEM_freeN(short_locale_utf8); + /* We want to avoid locales like '.UTF-8'! */ + if (short_locale[0]) { + /* Hurrey! encoding needs to be placed *before* variant! */ + char *variant = strchr(short_locale, '@'); + if (variant) { + char *locale = BLI_strdupn(short_locale, variant - short_locale); + short_locale_utf8 = BLI_sprintfN("%s.UTF-8%s", locale, variant); + MEM_freeN(locale); } else { - if (G.debug & G_DEBUG) - printf("Setting LANG=%s and LANGUAGE=%s\n", default_lang, default_language); - - BLI_setenv("LANG", default_lang); - BLI_setenv("LANGUAGE", default_language); - locreturn = setlocale(LC_ALL, ""); - - if (G.debug & G_DEBUG && locreturn == NULL) - printf("Could not reset locale\n"); - } - - if (locreturn == NULL) { - char language[65]; - - get_language(short_locale, default_lang, language, sizeof(language)); - - if (G.debug & G_DEBUG) - printf("Fallback to LANG=%s and LANGUAGE=%s\n", default_lang, language); - - /* Fallback to default settings. */ - BLI_setenv("LANG", default_lang); - BLI_setenv("LANGUAGE", language); - - locreturn = setlocale(LC_ALL, ""); - - ok = FALSE; + short_locale_utf8 = BLI_sprintfN("%s.UTF-8", short_locale); } } -#endif - - if (ok) { - /*printf("Change locale to %s\n", locreturn ); */ - BLI_strncpy(global_language, locreturn, sizeof(global_language)); + else { + short_locale_utf8 = short_locale; } - setlocale(LC_NUMERIC, "C"); + bl_locale_set(short_locale_utf8); - textdomain(TEXT_DOMAIN_NAME); - bindtextdomain(TEXT_DOMAIN_NAME, global_messagepath); - bind_textdomain_codeset(TEXT_DOMAIN_NAME, global_encoding_name); + if (short_locale[0]) { + MEM_freeN((void*)short_locale_utf8); + } } const char *BLF_lang_get(void) @@ -385,12 +239,6 @@ const char *BLF_lang_get(void) return LOCALE(uilang); } -void BLF_lang_encoding(const char *str) -{ - BLI_strncpy(global_encoding_name, str, sizeof(global_encoding_name)); - /* bind_textdomain_codeset(TEXT_DOMAIN_NAME, encoding_name); */ -} - #undef LOCALE #undef ULANGUAGE @@ -406,12 +254,6 @@ void BLF_lang_free(void) return; } -void BLF_lang_encoding(const char *str) -{ - (void)str; - return; -} - void BLF_lang_set(const char *str) { (void)str; diff --git a/source/blender/blenfont/intern/blf_translation.c b/source/blender/blenfont/intern/blf_translation.c index 9c863da9eba..5d4b631688a 100644 --- a/source/blender/blenfont/intern/blf_translation.c +++ b/source/blender/blenfont/intern/blf_translation.c @@ -31,18 +31,11 @@ #include #include -#ifdef WITH_INTERNATIONAL -#include -#include - -#define GETTEXT_CONTEXT_GLUE "\004" +#include "BLF_translation.h" -/* needed for windows version of gettext */ -#ifndef LC_MESSAGES -# define LC_MESSAGES 1729 -#endif +#ifdef WITH_INTERNATIONAL -#endif +#include "boost_locale_wrapper.h" #include "MEM_guardedalloc.h" @@ -52,11 +45,8 @@ #include "BLI_path_util.h" #include "BLI_fileops.h" -#include "BLF_translation.h" - #include "DNA_userdef_types.h" /* For user settings. */ -#ifdef WITH_INTERNATIONAL static const char unifont_filename[] = "droidsans.ttf.gz"; static unsigned char *unifont_ttf = NULL; static int unifont_size = 0; @@ -90,55 +80,19 @@ void BLF_free_unifont(void) #endif -const char *BLF_gettext(const char *msgid) +const char *BLF_pgettext(const char *msgctxt, const char *msgid) { #ifdef WITH_INTERNATIONAL - if (msgid && msgid[0]) - return gettext(msgid); + if (msgid && msgid[0]) { + return bl_locale_pgettext(msgctxt, msgid); + } return ""; #else + (void)msgctxt; return msgid; #endif } -const char *BLF_pgettext(const char *context, const char *message) -{ -#ifdef WITH_INTERNATIONAL - char static_msg_ctxt_id[1024]; - char *dynamic_msg_ctxt_id = NULL; - char *msg_ctxt_id; - const char *translation; - - size_t overall_length = strlen(context) + strlen(message) + sizeof(GETTEXT_CONTEXT_GLUE) + 1; - - if (!message || !context || !message[0]) - return ""; - - if (overall_length > sizeof(static_msg_ctxt_id)) { - dynamic_msg_ctxt_id = malloc(overall_length); - msg_ctxt_id = dynamic_msg_ctxt_id; - } - else { - msg_ctxt_id = static_msg_ctxt_id; - } - - sprintf(msg_ctxt_id, "%s%s%s", context, GETTEXT_CONTEXT_GLUE, message); - - translation = (char *)dcgettext(TEXT_DOMAIN_NAME, msg_ctxt_id, LC_MESSAGES); - - if (dynamic_msg_ctxt_id) - free(dynamic_msg_ctxt_id); - - if (translation == msg_ctxt_id) - translation = message; - - return translation; -#else - (void)context; - return message; -#endif -} - int BLF_translate_iface(void) { #ifdef WITH_INTERNATIONAL @@ -157,36 +111,32 @@ int BLF_translate_tooltips(void) #endif } -const char *BLF_translate_do_iface(const char *context, const char *msgid) +const char *BLF_translate_do_iface(const char *msgctxt, const char *msgid) { #ifdef WITH_INTERNATIONAL if (BLF_translate_iface()) { - if (context) - return BLF_pgettext(context, msgid); - else - return BLF_gettext(msgid); + return BLF_pgettext(msgctxt, msgid); } - else + else { return msgid; + } #else - (void)context; + (void)msgctxt; return msgid; #endif } -const char *BLF_translate_do_tooltip(const char *context, const char *msgid) +const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid) { #ifdef WITH_INTERNATIONAL if (BLF_translate_tooltips()) { - if (context) - return BLF_pgettext(context, msgid); - else - return BLF_gettext(msgid); + return BLF_pgettext(msgctxt, msgid); } - else + else { return msgid; + } #else - (void)context; + (void)msgctxt; return msgid; #endif } -- cgit v1.2.3