From dee8851b2626ffcf8116093404c52ff52838ca42 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Sun, 17 Dec 2006 11:56:57 +0000 Subject: [PATCH] added support for right to left languages by using the fribidi library (patch from Ehud Shabtai, thanks!) --- SConstruct | 13 ++++++++++ include/mapnik/unicode.hpp | 51 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/SConstruct b/SConstruct index c7d461c8b..d1adb102b 100644 --- a/SConstruct +++ b/SConstruct @@ -32,6 +32,8 @@ opts.Add('PREFIX', 'The install path "prefix"', '/usr/local') opts.Add(PathOption('BOOST_INCLUDES', 'Search path for boost include files', '/usr/include')) opts.Add(PathOption('BOOST_LIBS', 'Search path for boost library files', '/usr/' + LIBDIR_SCHEMA)) opts.Add(PathOption('FREETYPE_CONFIG', 'The path to the freetype-config executable.', '/usr/bin/freetype-config')) +opts.Add(PathOption('FRIBIDI_INCLUDES', 'Search path for fribidi include files', '/usr/include')) +opts.Add(PathOption('FRIBIDI_LIBS','Search path for fribidi include files','/usr/' + LIBDIR_SCHEMA)) opts.Add(PathOption('PNG_INCLUDES', 'Search path for libpng include files', '/usr/include')) opts.Add(PathOption('PNG_LIBS','Search path for libpng include files','/usr/' + LIBDIR_SCHEMA)) opts.Add(PathOption('JPEG_INCLUDES', 'Search path for libjpeg include files', '/usr/include')) @@ -46,6 +48,7 @@ opts.Add(PathOption('PYTHON','Python executable', sys.executable)) opts.Add(ListOption('INPUT_PLUGINS','Input drivers to include','all',['postgis','shape','raster'])) opts.Add(ListOption('BINDINGS','Language bindings to build','all',['python'])) opts.Add('DEBUG', 'Compile a debug version of mapnik', '') +opts.Add('BIDI', 'BIDI support', '') env = Environment(ENV=os.environ, options=opts) env['LIBDIR_SCHEMA'] = LIBDIR_SCHEMA @@ -78,6 +81,14 @@ for path in [env['BOOST_LIBS'], env.ParseConfig(env['FREETYPE_CONFIG'] + ' --libs --cflags') +if env['BIDI']: + env.Append(CXXFLAGS = '-DUSE_FRIBIDI') + if env['FRIBIDI_INCLUDES'] not in env['CPPPATH']: + env['CPPPATH'].append(env['FRIBIDI_INCLUDES']) + if env['FRIBIDI_LIBS'] not in env['LIBPATH']: + env['CPPPATH'].append(env['FRIBIDI_LIBS']) + env['LIBS'].append('fribidi') + C_LIBSHEADERS = [ ['m', 'math.h', True], ['ltdl', 'ltdl.h', True], @@ -89,6 +100,8 @@ C_LIBSHEADERS = [ ['pq', 'libpq-fe.h', False] ] +if env['BIDI'] : C_LIBSHEADERS.append(['fribidi','fribidi/fribidi.h',True]) + BOOST_LIBSHEADERS = [ ['thread', 'boost/thread/mutex.hpp', True], ['filesystem', 'boost/filesystem/operations.hpp', True], diff --git a/include/mapnik/unicode.hpp b/include/mapnik/unicode.hpp index 1bb056d3a..c45e8f682 100644 --- a/include/mapnik/unicode.hpp +++ b/include/mapnik/unicode.hpp @@ -26,8 +26,53 @@ #include +#ifdef USE_FRIBIDI +#include +#endif + namespace mapnik { +/* +** Use FRIBIDI to encode the string. +** The return value must be freed by the caller. +*/ + +#ifdef USE_FRIBIDI + inline wchar_t* bidi_string(const wchar_t *logical) + { + FriBidiCharType base = FRIBIDI_TYPE_ON; + size_t len; + + len = wcslen(logical); + + FriBidiChar *visual; + + FriBidiStrIndex *ltov, *vtol; + FriBidiLevel *levels; + FriBidiStrIndex new_len; + fribidi_boolean log2vis; + + visual = (FriBidiChar *) malloc (sizeof (FriBidiChar) * (len + 1)); + ltov = 0; + vtol = 0; + levels = 0; + + /* Create a bidi string. */ + log2vis = fribidi_log2vis ((FriBidiChar *)logical, len, &base, + /* output */ + visual, ltov, vtol, levels); + + if (!log2vis) { + return 0; + } + + new_len = len; + + return (wchar_t *)visual; + } +#endif + + inline std::wstring to_unicode(std::string const& text) { std::wstring out; @@ -75,6 +120,12 @@ namespace mapnik { } out.push_back(wchar_t(code)); } +#ifdef USE_FRIBIDI + wchar_t *bidi_text = bidi_string(out.c_str()); + out = bidi_text; + free(bidi_text); +#endif + return out; } }