Replacing gettext i18n backend by boost::locale one.
authorBastien Montagne <montagne29@wanadoo.fr>
Sun, 11 Nov 2012 16:54:26 +0000 (16:54 +0000)
committerBastien Montagne <montagne29@wanadoo.fr>
Sun, 11 Nov 2012 16:54:26 +0000 (16:54 +0000)
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).

23 files changed:
CMakeLists.txt
build_files/cmake/macros.cmake
build_files/scons/config/darwin-config.py
build_files/scons/config/linux-config.py
build_files/scons/config/win32-mingw-config.py
build_files/scons/config/win32-vc-config.py
build_files/scons/config/win64-mingw-config.py
build_files/scons/config/win64-vc-config.py
intern/CMakeLists.txt
intern/SConscript
intern/locale/CMakeLists.txt [new file with mode: 0644]
intern/locale/SConscript [new file with mode: 0644]
intern/locale/boost_locale_wrapper.cpp [new file with mode: 0644]
intern/locale/boost_locale_wrapper.h [new file with mode: 0644]
source/blender/blenfont/BLF_translation.h
source/blender/blenfont/CMakeLists.txt
source/blender/blenfont/SConscript
source/blender/blenfont/intern/blf_lang.c
source/blender/blenfont/intern/blf_translation.c
source/blender/makesrna/intern/rna_access.c
source/blenderplayer/CMakeLists.txt
source/creator/CMakeLists.txt
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp

index 593cd98..cb3ddb4 100644 (file)
@@ -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()
 
@@ -1511,11 +1471,7 @@ elseif(APPLE)
                                set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -weak_framework 3DconnexionClient")
                        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.
 
index 3c321cc..2d9de5a 100644 (file)
@@ -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()
index afab413..8511e96 100644 (file)
@@ -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
index 45f6602..6160389 100644 (file)
@@ -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
index 0a72d87..29e7d8c 100644 (file)
@@ -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
index b77ff8e..dbb1817 100644 (file)
@@ -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
index 838822b..91206aa 100644 (file)
@@ -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
index 4b71946..45fef53 100644 (file)
@@ -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
index cb2fc23..be797c4 100644 (file)
@@ -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)
index 59e4123..5360ce4 100644 (file)
@@ -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'])
 
diff --git a/intern/locale/CMakeLists.txt b/intern/locale/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f3356bc
--- /dev/null
@@ -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}")
diff --git a/intern/locale/SConscript b/intern/locale/SConscript
new file mode 100644 (file)
index 0000000..4a1357b
--- /dev/null
@@ -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])
diff --git a/intern/locale/boost_locale_wrapper.cpp b/intern/locale/boost_locale_wrapper.cpp
new file mode 100644 (file)
index 0000000..ec2976f
--- /dev/null
@@ -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;
+       }
+}
+
diff --git a/intern/locale/boost_locale_wrapper.h b/intern/locale/boost_locale_wrapper.h
new file mode 100644 (file)
index 0000000..e7956d2
--- /dev/null
@@ -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__ */
index b01ce93..d0b5d82 100644 (file)
 
 #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. */
index 022dfd2..90baef1 100644 (file)
@@ -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()
 
index 075da58..91c9c67 100644 (file)
@@ -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']
index f02d4a2..0ed4862 100644 (file)
  */
 
 
-#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"
 
 
 #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;
index 9c863da..5d4b631 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
-#ifdef WITH_INTERNATIONAL
-#include <libintl.h>
-#include <locale.h>
-
-#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"
 
 #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
 }
index 69332dc..81e738e 100644 (file)
@@ -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;
index 828b7f5..11e7904 100644 (file)
@@ -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})
index c06669c..9087d10 100644 (file)
@@ -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})
index 54457d0..3e8755c 100644 (file)
@@ -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);