aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/FbString.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk/FbString.cc')
-rw-r--r--src/FbTk/FbString.cc150
1 files changed, 96 insertions, 54 deletions
diff --git a/src/FbTk/FbString.cc b/src/FbTk/FbString.cc
index 2190a76..79b773a 100644
--- a/src/FbTk/FbString.cc
+++ b/src/FbTk/FbString.cc
@@ -62,8 +62,86 @@ using std::cerr;
62using std::endl; 62using std::endl;
63#endif // DEBUG 63#endif // DEBUG
64 64
65namespace {
66
67#ifdef HAVE_FRIBIDI
68FbTk::FbString makeVisualFromLogical(const FbTk::FbString& src) {
69
70 FriBidiCharType base = FRIBIDI_TYPE_N;
71
72 // reuse allocated memory for reencoding / reordering
73 static std::vector<FriBidiChar> us;
74 static std::vector<FriBidiChar> out_us;
75 static FbTk::FbString result;
76
77 const size_t S = src.size() + 1;
78 const size_t S4 = S * 4;
79
80 if (us.capacity() < S)
81 us.reserve(S);
82 if (out_us.capacity() < S)
83 out_us.reserve(S);
84 if (result.capacity() < S4)
85 result.reserve(S4);
86
87 us.resize(S);
88 FriBidiStrIndex len = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8,
89 const_cast<char*>(src.c_str()), S - 1,
90 &us[0]);
91
92 out_us.resize(S);
93 fribidi_log2vis(&us[0], len, &base, &out_us[0], NULL, NULL, NULL);
94
95 result.resize(S4);
96 len = fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, &out_us[0], len, &result[0]);
97 result.resize(len); // trim to currently used chars
98
99 return result;
100}
101
102#endif
103
104} // end of anonymous namespace
105
106
65namespace FbTk { 107namespace FbTk {
66 108
109
110BiDiString::BiDiString(const FbString& logical)
111#ifdef HAVE_FRIBIDI
112 : m_visual_dirty(false)
113#endif
114{
115 if (!logical.empty())
116 setLogical(logical);
117}
118
119const FbString& BiDiString::setLogical(const FbString& logical) {
120 m_logical = logical;
121#if HAVE_FRIBIDI
122 if (m_logical.empty()) {
123 m_visual_dirty = false;
124 m_visual.clear();
125 } else {
126 m_visual_dirty = true;
127 }
128#endif
129}
130
131const FbString& BiDiString::visual() const {
132#if HAVE_FRIBIDI
133 if (m_visual_dirty) {
134 m_visual = ::makeVisualFromLogical(logical());
135 }
136 m_visual_dirty = false;
137 return m_visual;
138#else
139 return m_logical;
140#endif
141}
142
143
144
67namespace FbStringUtil { 145namespace FbStringUtil {
68 146
69enum ConvType { FB2X = 0, X2FB, LOCALE2FB, FB2LOCALE, CONVSIZE }; 147enum ConvType { FB2X = 0, X2FB, LOCALE2FB, FB2LOCALE, CONVSIZE };
@@ -128,7 +206,6 @@ void shutdown() {
128 206
129 207
130 208
131#ifdef HAVE_ICONV
132/** 209/**
133 Recodes the text from one encoding to another 210 Recodes the text from one encoding to another
134 assuming cd is correct 211 assuming cd is correct
@@ -137,7 +214,9 @@ void shutdown() {
137 @param size number of BYTES to convert 214 @param size number of BYTES to convert
138 @return the recoded string, or 0 on failure 215 @return the recoded string, or 0 on failure
139*/ 216*/
217string recode(iconv_t cd, const string &in) {
140 218
219#ifdef HAVE_ICONV
141/** 220/**
142 --NOTE-- 221 --NOTE--
143 In the "C" locale, this will strip any high-bit characters 222 In the "C" locale, this will strip any high-bit characters
@@ -145,8 +224,6 @@ void shutdown() {
145 then you need to set your locale to something UTF-8, OR something 224 then you need to set your locale to something UTF-8, OR something
146 ISO8859-1. 225 ISO8859-1.
147*/ 226*/
148string recode(iconv_t cd,
149 const string &in) {
150 227
151 // If empty message, yes this can happen, return 228 // If empty message, yes this can happen, return
152 if (in.empty()) 229 if (in.empty())
@@ -163,18 +240,18 @@ string recode(iconv_t cd,
163 size_t inbytesleft = insize; 240 size_t inbytesleft = insize;
164 size_t outbytesleft = outsize; 241 size_t outbytesleft = outsize;
165 242
243#ifdef HAVE_CONST_ICONV
244 const char* in_ptr = in.data();
245#else
166 char * in_ptr = const_cast<char *>(in.data()); 246 char * in_ptr = const_cast<char *>(in.data());
247#endif
167 size_t result = (size_t)(-1); 248 size_t result = (size_t)(-1);
168 bool again = true; 249 bool again = true;
169 250
170 while (again) { 251 while (again) {
171 again = false; 252 again = false;
172 253
173#ifdef HAVE_CONST_ICONV
174 result = iconv(cd, (const char**)(&in_ptr), &inbytesleft, &out_ptr, &outbytesleft);
175#else
176 result = iconv(cd, &in_ptr, &inbytesleft, &out_ptr, &outbytesleft); 254 result = iconv(cd, &in_ptr, &inbytesleft, &out_ptr, &outbytesleft);
177#endif // HAVE_CONST_ICONV
178 255
179 if (result == (size_t)(-1)) { 256 if (result == (size_t)(-1)) {
180 switch(errno) { 257 switch(errno) {
@@ -213,13 +290,10 @@ string recode(iconv_t cd,
213 free(out); 290 free(out);
214 291
215 return ret; 292 return ret;
216}
217#else 293#else
218string recode(int cd,
219 const string &str) {
220 return str; 294 return str;
221}
222#endif // HAVE_ICONV 295#endif // HAVE_ICONV
296}
223 297
224FbString XStrToFb(const string &src) { 298FbString XStrToFb(const string &src) {
225 return recode(iconv_convs[X2FB], src); 299 return recode(iconv_convs[X2FB], src);
@@ -249,59 +323,19 @@ bool haveUTF8() {
249} 323}
250 324
251 325
252#ifdef HAVE_FRIBIDI
253
254FbString BidiLog2Vis (const FbString& src) {
255
256 FriBidiCharType base = FRIBIDI_TYPE_N;
257
258 // reuse allocated memory for reencoding / reordering
259 static std::vector<FriBidiChar> us;
260 static std::vector<FriBidiChar> out_us;
261 static FbString result;
262
263 const size_t S = src.size() + 1;
264 const size_t S4 = S * 4;
265
266 if (us.capacity() < S)
267 us.reserve(S);
268 if (out_us.capacity() < S)
269 out_us.reserve(S);
270 if (result.capacity() < S4)
271 result.reserve(S4);
272
273 us.resize(S);
274 FriBidiStrIndex len = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8,
275 const_cast<char*>(src.c_str()), S - 1,
276 &us[0]);
277
278 out_us.resize(S);
279 fribidi_log2vis(&us[0], len, &base, &out_us[0], NULL, NULL, NULL);
280
281 result.resize(S4);
282 len = fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, &out_us[0], len, &result[0]);
283 result.resize(len); // trim to currently used chars
284
285 return result;
286}
287
288#endif
289
290} // end namespace StringUtil 326} // end namespace StringUtil
291 327
292StringConvertor::StringConvertor(EncodingTarget target):
293#ifdef HAVE_ICONV 328#ifdef HAVE_ICONV
294 m_iconv((iconv_t)(-1)) { 329StringConvertor::StringConvertor(EncodingTarget target) : m_iconv((iconv_t)(-1)) {
295 if (target == ToLocaleStr) 330 if (target == ToLocaleStr)
296 m_destencoding = FbStringUtil::locale_codeset; 331 m_destencoding = FbStringUtil::locale_codeset;
297 else 332 else
298 m_destencoding = "UTF-8"; 333 m_destencoding = "UTF-8";
299} 334}
300#else 335#else
301 m_iconv(-1) {} 336StringConvertor::StringConvertor(EncodingTarget target) { }
302#endif 337#endif
303 338
304
305StringConvertor::~StringConvertor() { 339StringConvertor::~StringConvertor() {
306#ifdef HAVE_ICONV 340#ifdef HAVE_ICONV
307 if (m_iconv != ((iconv_t)-1)) 341 if (m_iconv != ((iconv_t)-1))
@@ -329,7 +363,7 @@ bool StringConvertor::setSource(const string &encoding) {
329#endif 363#endif
330} 364}
331 365
332string StringConvertor::recode(const string &src) { 366FbString StringConvertor::recode(const string &src) {
333#ifdef HAVE_ICONV 367#ifdef HAVE_ICONV
334 return FbStringUtil::recode(m_iconv, src); 368 return FbStringUtil::recode(m_iconv, src);
335#else 369#else
@@ -337,5 +371,13 @@ string StringConvertor::recode(const string &src) {
337#endif 371#endif
338} 372}
339 373
374void StringConvertor::reset() {
375#ifdef HAVE_ICONV
376 if (m_iconv != ((iconv_t)-1))
377 iconv_close(m_iconv);
378 m_iconv = ((iconv_t)(-1));
379#endif
380}
381
340 382
341} // end namespace FbTk 383} // end namespace FbTk