aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/FbTk/FbString.cc42
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
249FbString BidiLog2Vis (const FbString& src){ 250FbString 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