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).
This commit is contained in:
Bastien Montagne 2012-11-11 16:54:26 +00:00
parent afd42031a9
commit 5ff3017900
23 changed files with 335 additions and 391 deletions

@ -296,11 +296,11 @@ if(APPLE)
if(${CMAKE_GENERATOR} MATCHES "Xcode")
##### cmake incompatibility with xcode 4.3 and higher #####
##### workaround for actual official cmake incompatibility with xcode 4.3 #####
if(${XCODE_VERSION} MATCHES '') # cmake fails due looking for xcode in the wrong path, thus will be empty var
message(FATAL_ERROR "Xcode 4.3 and higher must be used with cmake 2.8-8 or higher")
message("Official cmake does not yet support Xcode 4.3, get a patched version here: http://www.jensverwiebe.de/Blender/CMake%202.8-7patched.zip")
endif()
### end cmake incompatibility with xcode 4.3 and higher ###
### end workaround for actual official cmake incompatibility with xcode 4.3 ###
if(${XCODE_VERSION} VERSION_EQUAL 4 OR ${XCODE_VERSION} VERSION_GREATER 4 AND ${XCODE_VERSION} VERSION_LESS 4.3)
# Xcode 4 defaults to the Apple LLVM Compiler.
@ -376,8 +376,8 @@ if(WITH_CYCLES)
set(WITH_OPENIMAGEIO ON)
endif()
# auto enable boost for cycles, booleans or audaspace
if(WITH_CYCLES OR WITH_MOD_BOOLEAN OR WITH_AUDASPACE)
# auto enable boost for cycles, booleans, audaspace or i18n
if(WITH_CYCLES OR WITH_MOD_BOOLEAN OR WITH_AUDASPACE OR WITH_INTERNATIONAL)
set(WITH_BOOST ON)
endif()
@ -593,28 +593,6 @@ if(UNIX AND NOT APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__STDC_CONSTANT_MACROS")
endif()
if(WITH_INTERNATIONAL)
find_library(INTL_LIBRARY
NAMES intl
PATHS
/sw/lib
)
find_library(ICONV_LIBRARY
NAMES iconv
PATHS
/sw/lib
)
mark_as_advanced(
ICONV_LIBRARY
INTL_LIBRARY
)
if(INTL_LIBRARY AND ICONV_LIBRARY)
set(GETTEXT_LIBRARIES ${INTL_LIBRARY} ${ICONV_LIBRARY})
endif()
endif()
if(WITH_FFTW3)
find_package(Fftw3)
if(NOT FFTW3_FOUND)
@ -662,7 +640,11 @@ if(UNIX AND NOT APPLE)
else()
set(Boost_USE_MULTITHREADED ON)
endif()
find_package(Boost 1.34 COMPONENTS filesystem regex system thread)
set(__boost_packages filesystem regex system thread)
if (WITH_INTERNATIONAL)
list(APPEND __boost_packages locale)
endif()
find_package(Boost 1.34 COMPONENTS ${__boost_packages})
mark_as_advanced(Boost_DIR) # why doesnt boost do this?
endif()
@ -879,13 +861,6 @@ elseif(WIN32)
add_definitions(-DWIN32)
if(WITH_INTERNATIONAL)
set(ICONV ${LIBDIR}/iconv)
set(ICONV_INCLUDE_DIRS ${ICONV}/include)
set(ICONV_LIBRARIES iconv)
set(ICONV_LIBPATH ${ICONV}/lib)
endif()
set(JPEG "${LIBDIR}/jpeg")
set(JPEG_INCLUDE_DIR "${JPEG}/include")
set(JPEG_LIBPATH ${JPEG}/lib) # not cmake defined
@ -978,13 +953,6 @@ elseif(WIN32)
set(CXX_WARNINGS "${_WARNINGS}")
unset(_WARNINGS)
if(WITH_INTERNATIONAL)
set(GETTEXT ${LIBDIR}/gettext)
set(GETTEXT_INCLUDE_DIRS ${GETTEXT}/include)
set(GETTEXT_LIBPATH ${GETTEXT}/lib)
set(GETTEXT_LIBRARIES gnu_gettext)
endif()
if(WITH_MOD_CLOTH_ELTOPO)
set(LAPACK ${LIBDIR}/lapack)
# set(LAPACK_INCLUDE_DIR ${LAPACK}/include)
@ -1137,6 +1105,11 @@ elseif(WIN32)
debug libboost_date_time-${BOOST_DEBUG_POSTFIX} debug libboost_filesystem-${BOOST_DEBUG_POSTFIX}
debug libboost_regex-${BOOST_DEBUG_POSTFIX}
debug libboost_system-${BOOST_DEBUG_POSTFIX} debug libboost_thread-${BOOST_DEBUG_POSTFIX})
if(WITH_INTERNATIONAL)
set(BOOST_LIBRARIES ${BOOST_LIBRARIES}
optimized libboost_locale-${BOOST_POSTFIX}
debug libboost_locale-${BOOST_DEBUG_POSTFIX})
endif(WITH_INTERNATIONAL)
set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB")
endif()
@ -1190,16 +1163,8 @@ elseif(WIN32)
add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE)
add_definitions(-DFREE_WINDOWS)
if(WITH_INTERNATIONAL)
set(GETTEXT ${LIBDIR}/gettext)
set(GETTEXT_INCLUDE_DIRS ${GETTEXT}/include)
set(GETTEXT_LIBPATH ${GETTEXT}/lib)
set(GETTEXT_LIBRARIES intl)
endif()
set(PNG "${LIBDIR}/png")
set(PNG_INCLUDE_DIR "${PNG}/include")
set(PNG_LIBPATH ${PNG}/lib) # not cmake defined
@ -1317,6 +1282,11 @@ elseif(WIN32)
debug boost_date_time-${BOOST_DEBUG_POSTFIX} boost_filesystem-${BOOST_DEBUG_POSTFIX}
boost_regex-${BOOST_DEBUG_POSTFIX}
boost_system-${BOOST_DEBUG_POSTFIX} boost_thread-${BOOST_DEBUG_POSTFIX})
if(WITH_INTERNATIONAL)
set(BOOST_LIBRARIES ${BOOST_LIBRARIES}
optimized libboost_locale-${BOOST_POSTFIX}
debug libboost_locale-${BOOST_DEBUG_POSTFIX})
endif(WITH_CYCLES_OSL)
set(BOOST_LIBPATH ${BOOST}/lib)
set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB -DBOOST_THREAD_USE_LIB ")
endif()
@ -1383,13 +1353,10 @@ elseif(APPLE)
endif()
if(WITH_JACK)
find_library(JACK_FRAMEWORK
NAMES jackmp
)
set(JACK_INCLUDE_DIRS ${JACK_FRAMEWORK}/headers)
if(NOT JACK_FRAMEWORK)
set(WITH_JACK OFF)
endif()
set(JACK /usr/local)
set(JACK_INCLUDE_DIRS ${JACK}/include/jack)
set(JACK_LIBRARIES jack)
set(JACK_LIBPATH ${JACK}/lib)
endif()
if(WITH_CODEC_SNDFILE)
@ -1427,13 +1394,6 @@ elseif(APPLE)
set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
endif()
if(WITH_INTERNATIONAL)
set(GETTEXT ${LIBDIR}/gettext)
set(GETTEXT_INCLUDE_DIRS "${GETTEXT}/include")
set(GETTEXT_LIBRARIES intl iconv)
set(GETTEXT_LIBPATH ${GETTEXT}/lib)
endif()
if(WITH_FFTW3)
set(FFTW3 ${LIBDIR}/fftw3)
set(FFTW3_INCLUDE_DIRS ${FFTW3}/include)
@ -1500,10 +1460,10 @@ elseif(APPLE)
if(WITH_INPUT_NDOF)
# This thread it *should* work and check the framework - campbell
# http://www.cmake.org/pipermail/cmake/2005-December/007740.html
find_library(3DCONNEXION_CLIENT_FRAMEWORK
find_library(3D_CONNEXION_CLIENT_LIBRARY
NAMES 3DconnexionClient
)
if(NOT 3DCONNEXION_CLIENT_FRAMEWORK)
if(NOT 3D_CONNEXION_CLIENT_LIBRARY)
set(WITH_INPUT_NDOF OFF)
endif()
@ -1512,10 +1472,6 @@ elseif(APPLE)
endif()
endif()
if(WITH_JACK)
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -weak_framework jackmp")
endif()
else()
set(PLATFORM_CFLAGS "-pipe -funsigned-char")
set(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime")
@ -1579,6 +1535,9 @@ elseif(APPLE)
set(BOOST ${LIBDIR}/boost)
set(BOOST_INCLUDE_DIR ${BOOST}/include)
set(BOOST_LIBRARIES boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt)
if (WITH_INTERNATIONAL)
list(APPEND BOOST_LIBRARIES boost_locale-mt)
endif()
set(BOOST_LIBPATH ${BOOST}/lib)
set(BOOST_DEFINITIONS)
endif()
@ -1704,6 +1663,11 @@ if(WITH_CYCLES)
endif()
endif()
if(WITH_INTERNATIONAL)
if(NOT WITH_BOOST)
message(FATAL_ERROR "Internationalization reqires WITH_BOOST, the library may not have been found. Configure BOOST or disable WITH_INTERNATIONAL")
endif()
endif()
# See TEST_SSE_SUPPORT() for how this is defined.

@ -196,10 +196,6 @@ macro(SETUP_LIBDIRS)
if(WITH_PYTHON) # AND NOT WITH_PYTHON_MODULE # WIN32 needs
link_directories(${PYTHON_LIBPATH})
endif()
if(WITH_INTERNATIONAL)
link_directories(${ICONV_LIBPATH})
link_directories(${GETTEXT_LIBPATH})
endif()
if(WITH_SDL)
link_directories(${SDL_LIBPATH})
endif()
@ -287,14 +283,6 @@ macro(setup_liblinks
target_link_libraries(${target} ${GLEW_LIBRARY})
endif()
if(WITH_INTERNATIONAL)
target_link_libraries(${target} ${GETTEXT_LIBRARIES})
if(WIN32 AND NOT UNIX)
target_link_libraries(${target} ${ICONV_LIBRARIES})
endif()
endif()
if(WITH_OPENAL)
target_link_libraries(${target} ${OPENAL_LIBRARY})
endif()

@ -297,6 +297,8 @@ WITH_BF_BOOST = True
BF_BOOST = LIBDIR + '/boost'
BF_BOOST_INC = BF_BOOST + '/include'
BF_BOOST_LIB = 'boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt'
if WITH_BF_INTERNATIONAL:
BF_BOOST_LIB += ' boost_locale-mt'
BF_BOOST_LIBPATH = BF_BOOST + '/lib'
WITH_BF_CYCLES_CUDA_BINARIES = False

@ -233,6 +233,8 @@ if not os.path.exists(LCGDIR + '/boost'):
BF_BOOST = '/usr'
BF_BOOST_INC = BF_BOOST + '/include'
BF_BOOST_LIB = 'boost_date_time boost_filesystem boost_regex boost_system boost_thread'
if WITH_BF_INTERNATIONAL:
BF_BOOST_LIB += ' boost_locale'
BF_BOOST_LIBPATH = BF_BOOST + '/lib'
WITH_BF_CYCLES = WITH_BF_OIIO and WITH_BF_BOOST

@ -169,6 +169,8 @@ WITH_BF_BOOST = True
BF_BOOST = LIBDIR + '/boost'
BF_BOOST_INC = BF_BOOST + '/include'
BF_BOOST_LIB = 'boost_date_time-mgw46-mt-s-1_49 boost_filesystem-mgw46-mt-s-1_49 boost_regex-mgw46-mt-s-1_49 boost_system-mgw46-mt-s-1_49 boost_thread-mgw46-mt-s-1_49'
if WITH_BF_INTERNATIONAL:
BF_BOOST_LIB += ' boost_locale-mgw46-mt-s-1_49'
BF_BOOST_LIBPATH = BF_BOOST + '/lib'
#Ray trace optimization

@ -171,6 +171,8 @@ WITH_BF_BOOST = True
BF_BOOST = '${LIBDIR}/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_49 libboost_filesystem-vc90-mt-s-1_49 libboost_regex-vc90-mt-s-1_49 libboost_system-vc90-mt-s-1_49 libboost_thread-vc90-mt-s-1_49'
if WITH_BF_INTERNATIONAL:
BF_BOOST_LIB += ' libboost_locale-vc90-mt-s-1_49'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
#CUDA

@ -169,6 +169,8 @@ WITH_BF_BOOST = True
BF_BOOST = LIBDIR + '/boost'
BF_BOOST_INC = BF_BOOST + '/include'
BF_BOOST_LIB = 'boost_date_time-mgw47-mt-s-1_49 boost_date_time-mgw47-mt-sd-1_49 boost_filesystem-mgw47-mt-s-1_49 boost_filesystem-mgw47-mt-sd-1_49 boost_regex-mgw47-mt-s-1_49 boost_regex-mgw47-mt-sd-1_49 boost_system-mgw47-mt-s-1_49 boost_system-mgw47-mt-sd-1_49 boost_thread-mgw47-mt-s-1_49 boost_thread-mgw47-mt-sd-1_49'
if WITH_BF_INTERNATIONAL:
BF_BOOST_LIB += ' boost_locale-mgw47-mt-s-1_49 boost_locale-mgw47-mt-sd-1_49'
BF_BOOST_LIBPATH = BF_BOOST + '/lib'
#Ray trace optimization

@ -169,6 +169,8 @@ WITH_BF_BOOST = True
BF_BOOST = '${LIBDIR}/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_49 libboost_filesystem-vc90-mt-s-1_49 libboost_regex-vc90-mt-s-1_49 libboost_system-vc90-mt-s-1_49 libboost_thread-vc90-mt-s-1_49'
if WITH_BF_INTERNATIONAL:
BF_BOOST_LIB += ' libboost_locale-vc90-mt-s-1_49'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
#CUDA

@ -65,6 +65,10 @@ if(WITH_CYCLES)
add_subdirectory(cycles)
endif()
if(WITH_INTERNATIONAL)
add_subdirectory(locale)
endif()
# only windows needs utf16 converter
if(WIN32)
add_subdirectory(utfconv)

@ -30,6 +30,9 @@ if env['WITH_BF_CYCLES']:
if env['WITH_BF_BOOLEAN']:
SConscript(['bsp/SConscript'])
if env['WITH_BF_INTERNATIONAL']:
SConscript(['locale/SConscript'])
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-mingw', 'linuxcross', 'win64-vc'):
SConscript(['utfconv/SConscript'])

@ -0,0 +1,44 @@
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# The Original Code is Copyright (C) 2012, Blender Foundation
# All rights reserved.
#
# The Original Code is: all of this file.
#
# Contributor(s): Bastien Montagne.
#
# ***** END GPL LICENSE BLOCK *****
set(INC
.
)
set(INC_SYS
)
set(SRC
boost_locale_wrapper.cpp
)
if(WITH_INTERNATIONAL)
list(APPEND INC_SYS
${BOOST_INCLUDE_DIR}
)
add_definitions(-DWITH_INTERNATIONAL)
endif()
blender_add_lib(bf_intern_locale "${SRC}" "${INC}" "${INC_SYS}")

14
intern/locale/SConscript Normal file

@ -0,0 +1,14 @@
#!/usr/bin/python
Import('env')
sources = env.Glob('*.cpp')
incs = '.'
defs = []
if env['WITH_BF_INTERNATIONAL']:
defs.append('WITH_INTERNATIONAL')
incs += ' ' + env['BF_BOOST_INC']
env.BlenderLib( 'bf_intern_locale', sources, Split(incs), defs, libtype=['extern','player'], priority=[10, 185])

@ -0,0 +1,87 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2012, Blender Foundation
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Bastien Montagne.
*
* ***** END GPL LICENSE BLOCK *****
*
*/
#include <boost/locale.hpp>
#include "boost_locale_wrapper.h"
static std::string messages_path;
static std::string default_domain;
void bl_locale_init(const char *_messages_path, const char *_default_domain)
{
// Avoid using ICU backend, we do not need its power and it's rather heavy!
boost::locale::localization_backend_manager lman = boost::locale::localization_backend_manager::global();
#if defined (_WIN32)
lman.select("winapi");
#else
lman.select("posix");
#endif
boost::locale::localization_backend_manager::global(lman);
messages_path = _messages_path;
default_domain = _default_domain;
}
void bl_locale_set(const char *locale)
{
boost::locale::generator gen;
// Specify location of dictionaries.
gen.add_messages_path(messages_path);
gen.add_messages_domain(default_domain);
//gen.set_default_messages_domain(default_domain);
if (locale && locale[0]) {
std::locale::global(gen(locale));
}
else {
std::locale::global(gen(""));
}
// Note: boost always uses "C" LC_NUMERIC by default!
}
const char* bl_locale_pgettext(const char *msgctxt, const char *msgid)
{
// Note: We cannot use short stuff like boost::locale::gettext, because those return
// std::basic_string objects, which c_ptr()-returned char* is no more valid
// once deleted (which happens as soons they are out of scope of this func).
typedef boost::locale::message_format<char> char_message_facet;
try {
std::locale l;
char_message_facet const &facet = std::use_facet<char_message_facet>(l);
char const *r = facet.get(0, msgctxt, msgid);
if(r)
return r;
return msgid;
}
catch(std::exception const &e) {
// std::cout << "boost_locale_pgettext: " << e.what() << " \n";
return msgid;
}
}

@ -0,0 +1,49 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2012, Blender Foundation
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Bastien Montagne.
*
* ***** END GPL LICENSE BLOCK *****
*
*/
/** \file locale/boost_locale_wrapper.h
* \ingroup locale
* A thin C wrapper around boost::locale...
*/
#ifndef __BOOST_LOCALE_WRAPPER_H__
#define __BOOST_LOCALE_WRAPPER_H__
#ifdef __cplusplus
extern "C" {
#endif
void bl_locale_init(const char *messages_path, const char *default_domain);
void bl_locale_set(const char *locale);
const char* bl_locale_pgettext(const char *msgctxt, const char *msgid);
#ifdef __cplusplus
}
#endif
#endif /* __BOOST_LOCALE_WRAPPER_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. */

@ -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()

@ -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']

@ -28,20 +28,17 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "BKE_global.h"
#include "BLF_api.h"
#include "BLF_translation.h" /* own include */
#ifdef WITH_INTERNATIONAL
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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);
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("");
}
}
else {
locales[id] = locales_menu[idx].description = BLI_strdup(loc);
long_locales[id] = BLI_strdup(sep3 + 1);
}
idx++;
}
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("");
}
/* Menu "label", not to be stored in locales! */
else {
locales_menu[idx].description = BLI_strdup("");
}
}
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;

@ -31,18 +31,11 @@
#include <stdlib.h>
#include <string.h>
#include "BLF_translation.h"
#ifdef WITH_INTERNATIONAL
#include <libintl.h>
#include <locale.h>
#define GETTEXT_CONTEXT_GLUE "\004"
/* needed for windows version of gettext */
#ifndef LC_MESSAGES
# define LC_MESSAGES 1729
#endif
#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
}

@ -1224,10 +1224,10 @@ void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA
if (prop->translation_context)
nitem[i].name = BLF_pgettext(prop->translation_context, nitem[i].name);
else
nitem[i].name = BLF_gettext(nitem[i].name);
nitem[i].name = BLF_pgettext(NULL, nitem[i].name);
}
if (nitem[i].description)
nitem[i].description = BLF_gettext(nitem[i].description);
nitem[i].description = BLF_pgettext(NULL, nitem[i].description);
}
*item = nitem;

@ -191,6 +191,10 @@ endif()
list(APPEND BLENDER_SORTED_LIBS bf_intern_guardedalloc_cpp)
endif()
if(WITH_INTERNATIONAL)
list(APPEND BLENDER_SORTED_LIBS bf_intern_locale)
endif()
foreach(SORTLIB ${BLENDER_SORTED_LIBS})
set(REMLIB ${SORTLIB})
foreach(SEARCHLIB ${BLENDER_LINK_LIBS})

@ -469,20 +469,6 @@ elseif(WIN32)
DESTINATION ${TARGETDIR}
)
if(WITH_INTERNATIONAL AND (NOT WITH_MINGW64))
install(
FILES ${LIBDIR}/gettext/lib/gnu_gettext.dll
DESTINATION ${TARGETDIR}
)
if(NOT CMAKE_CL_64)
install(
FILES ${LIBDIR}/iconv/lib/iconv.dll
DESTINATION ${TARGETDIR}
)
endif()
endif()
if(WITH_PYTHON)
set_lib_path(PYLIB "python")
install(
@ -530,7 +516,7 @@ elseif(WIN32)
endif()
if(CMAKE_CL_64)
# gettext and png are statically linked on win64
# png is statically linked on win64
install(
FILES ${LIBDIR}/zlib/lib/zlib.dll
DESTINATION ${TARGETDIR}
@ -987,6 +973,10 @@ endif()
list_insert_after(BLENDER_SORTED_LIBS "cycles_kernel" "cycles_kernel_osl")
endif()
if(WITH_INTERNATIONAL)
list(APPEND BLENDER_SORTED_LIBS bf_intern_locale)
endif()
foreach(SORTLIB ${BLENDER_SORTED_LIBS})
set(REMLIB ${SORTLIB})
foreach(SEARCHLIB ${BLENDER_LINK_LIBS})

@ -450,7 +450,6 @@ int main(int argc, char** argv)
// Setup builtin font for BLF (mostly copied from creator.c, wm_init_exit.c and interface_style.c)
BLF_init(11, U.dpi);
BLF_lang_init();
BLF_lang_encoding("");
BLF_lang_set("");
BLF_load_mem("default", (unsigned char*)datatoc_bfont_ttf, datatoc_bfont_ttf_size);