Mercurial > hg > octave-lyh
changeset 17360:4a348443de9b
Support multibyte characters in Freetype-based renderer (bug #31596).
* bootstrap.conf (gnulib_modules): Add mbrtowc.
* libinterp/corefcn/txt-eng-ft.cc (clocale, cwchar): New include.
(ft_render::visit(text_element_string)): Decode string using mbrtowc.
author | Michael Goffioul <michael.goffioul@gmail.com> |
---|---|
date | Fri, 30 Aug 2013 10:07:42 -0400 |
parents | 80bf005cdf8e |
children | de4cf28c7e11 |
files | bootstrap.conf libinterp/corefcn/txt-eng-ft.cc |
diffstat | 2 files changed, 31 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/bootstrap.conf +++ b/bootstrap.conf @@ -49,6 +49,7 @@ link lstat malloc-gnu + mbrtowc mkdir mkfifo mkostemp
--- a/libinterp/corefcn/txt-eng-ft.cc +++ b/libinterp/corefcn/txt-eng-ft.cc @@ -30,6 +30,8 @@ #include <fontconfig/fontconfig.h> #endif +#include <clocale> +#include <cwchar> #include <iostream> #include <map> #include <utility> @@ -628,18 +630,39 @@ { if (font.is_valid ()) { - std::string str = e.string_value (); FT_UInt glyph_index, previous = 0; - for (size_t i = 0; i < str.length (); i++) + std::string str = e.string_value (); + size_t n = str.length (), curr = 0; + mbstate_t ps = { 0 }; + wchar_t wc; + + while (n > 0) { - glyph_index = process_character (static_cast<unsigned char> (str[i]), - previous); + size_t r = gnulib::mbrtowc (&wc, str.data () + curr, n, &ps); + + if (r > 0 + && r != static_cast<size_t> (-1) + && r != static_cast<size_t> (-2)) + { + n -= r; + curr += r; - if (str[i] == '\n') - previous = 0; + glyph_index = process_character (wc, previous); + + if (wc == L'\n') + previous = 0; + else + previous = glyph_index; + } else - previous = glyph_index; + { + if (r != 0) + ::warning ("ft_render: failed to decode string `%s' with " + "locale `%s'", str.c_str (), + std::setlocale (LC_CTYPE, NULL)); + break; + } } } }