aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/FbString.cc
diff options
context:
space:
mode:
authorMathias Gumz <akira at fluxbox dot org>2010-09-08 18:17:21 (GMT)
committerMathias Gumz <akira at fluxbox dot org>2010-09-08 18:17:21 (GMT)
commit690d926ac444243611cd875fb84fabb4e6db2cf2 (patch)
treec8ef84056b295071f9a9207ffea5393c6cf4ad4d /src/FbTk/FbString.cc
parent1e8fe2bc14856fa16508686a28a85e72cb0e422c (diff)
downloadfluxbox-690d926ac444243611cd875fb84fabb4e6db2cf2.zip
fluxbox-690d926ac444243611cd875fb84fabb4e6db2cf2.tar.bz2
introduced FbTk::BidiString
a 'BidiString' holds both the logical content and the visual reordered version of the content of a string. this helps to reduce the number of calls to reorder the string before drawing it (as introduced in the patch from Ken Bloom) and to be more consistent in menus and textboxes (drawing cursors and underlining text).
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