diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/FbTk/FbString.cc | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/src/FbTk/FbString.cc b/src/FbTk/FbString.cc index 1cef002..de23fd2 100644 --- a/src/FbTk/FbString.cc +++ b/src/FbTk/FbString.cc | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <locale.h> | 44 | #include <locale.h> |
45 | 45 | ||
46 | #include <iostream> | 46 | #include <iostream> |
47 | #include <vector> | ||
47 | 48 | ||
48 | #ifdef HAVE_FRIBIDI | 49 | #ifdef HAVE_FRIBIDI |
49 | #include <fribidi/fribidi.h> | 50 | #include <fribidi/fribidi.h> |
@@ -246,31 +247,38 @@ bool haveUTF8() { | |||
246 | 247 | ||
247 | #ifdef HAVE_FRIBIDI | 248 | #ifdef HAVE_FRIBIDI |
248 | 249 | ||
249 | FbString BidiLog2Vis (const FbString& src){ | 250 | FbString BidiLog2Vis (const FbString& src) { |
250 | FriBidiChar * us, * out_us; | ||
251 | FriBidiCharType base; | ||
252 | FbString r; | ||
253 | char * out; | ||
254 | 251 | ||
255 | us = new FriBidiChar[src.size()+1]; | 252 | FriBidiCharType base = FRIBIDI_TYPE_N; |
256 | out_us = new FriBidiChar[src.size()+1]; | ||
257 | 253 | ||
258 | unsigned int len = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, const_cast<char *>(src.c_str()), src.length(), us); | 254 | // reuse allocated memory for reencoding / reordering |
255 | static std::vector<FriBidiChar> us; | ||
256 | static std::vector<FriBidiChar> out_us; | ||
257 | static FbString result; | ||
259 | 258 | ||
260 | base = FRIBIDI_TYPE_N; | 259 | const size_t S = src.size() + 1; |
261 | fribidi_log2vis(us, len, &base, out_us, NULL, NULL, NULL); | 260 | const size_t S4 = S * 4; |
262 | 261 | ||
263 | out = new char[4*src.size()+1]; | 262 | if (us.capacity() < S) |
263 | us.reserve(S); | ||
264 | if (out_us.capacity() < S) | ||
265 | out_us.reserve(S); | ||
266 | if (result.capacity() < S4) | ||
267 | result.reserve(S4); | ||
264 | 268 | ||
265 | fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, out_us, len, out); | 269 | us.resize(S); |
270 | FriBidiStrIndex len = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, | ||
271 | const_cast<char*>(src.c_str()), S - 1, | ||
272 | &us[0]); | ||
266 | 273 | ||
267 | r = out; | 274 | out_us.resize(S); |
275 | fribidi_log2vis(&us[0], len, &base, &out_us[0], NULL, NULL, NULL); | ||
268 | 276 | ||
269 | delete[] out_us; | 277 | result.resize(S4); |
270 | delete[] us; | 278 | len = fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, &out_us[0], len, &result[0]); |
271 | delete[] out; | 279 | result.resize(len); // trim to currently used chars |
272 | 280 | ||
273 | return r; | 281 | return result; |
274 | } | 282 | } |
275 | 283 | ||
276 | #endif | 284 | #endif |