aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk
diff options
context:
space:
mode:
authorKen Bloom <kbloom at gmail com>2010-09-04 13:01:33 (GMT)
committerMathias Gumz <akira at fluxbox dot org>2010-09-04 13:01:33 (GMT)
commitea98db414033aa17aee720135e2f9ee0a08696cc (patch)
tree40f0f68ee4a86289d832713890c226f31cdf853a /src/FbTk
parentb1b2f47e7dd185fef88a44a318a9b374083ecb40 (diff)
downloadfluxbox-ea98db414033aa17aee720135e2f9ee0a08696cc.zip
fluxbox-ea98db414033aa17aee720135e2f9ee0a08696cc.tar.bz2
added support for bidirectional text
Diffstat (limited to 'src/FbTk')
-rw-r--r--src/FbTk/FbString.cc37
-rw-r--r--src/FbTk/FbString.hh5
-rw-r--r--src/FbTk/Font.cc49
3 files changed, 69 insertions, 22 deletions
diff --git a/src/FbTk/FbString.cc b/src/FbTk/FbString.cc
index 0164afd..1cef002 100644
--- a/src/FbTk/FbString.cc
+++ b/src/FbTk/FbString.cc
@@ -45,6 +45,11 @@
45 45
46#include <iostream> 46#include <iostream>
47 47
48#ifdef HAVE_FRIBIDI
49#include <fribidi/fribidi.h>
50#endif
51
52
48using std::string; 53using std::string;
49 54
50#ifdef DEBUG 55#ifdef DEBUG
@@ -239,6 +244,37 @@ bool haveUTF8() {
239} 244}
240 245
241 246
247#ifdef HAVE_FRIBIDI
248
249FbString BidiLog2Vis (const FbString& src){
250 FriBidiChar * us, * out_us;
251 FriBidiCharType base;
252 FbString r;
253 char * out;
254
255 us = new FriBidiChar[src.size()+1];
256 out_us = new FriBidiChar[src.size()+1];
257
258 unsigned int len = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, const_cast<char *>(src.c_str()), src.length(), us);
259
260 base = FRIBIDI_TYPE_N;
261 fribidi_log2vis(us, len, &base, out_us, NULL, NULL, NULL);
262
263 out = new char[4*src.size()+1];
264
265 fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, out_us, len, out);
266
267 r = out;
268
269 delete[] out_us;
270 delete[] us;
271 delete[] out;
272
273 return r;
274}
275
276#endif
277
242} // end namespace StringUtil 278} // end namespace StringUtil
243 279
244StringConvertor::StringConvertor(EncodingTarget target): 280StringConvertor::StringConvertor(EncodingTarget target):
@@ -289,4 +325,5 @@ string StringConvertor::recode(const string &src) {
289#endif 325#endif
290} 326}
291 327
328
292} // end namespace FbTk 329} // end namespace FbTk
diff --git a/src/FbTk/FbString.hh b/src/FbTk/FbString.hh
index 1e473cc..e1a5dc5 100644
--- a/src/FbTk/FbString.hh
+++ b/src/FbTk/FbString.hh
@@ -52,6 +52,11 @@ std::string FbStrToX(const FbString &src);
52FbString LocaleStrToFb(const std::string &src); 52FbString LocaleStrToFb(const std::string &src);
53std::string FbStrToLocale(const FbString &src); 53std::string FbStrToLocale(const FbString &src);
54 54
55#ifdef HAVE_FRIBIDI
56/// Make Bidi
57FbString BidiLog2Vis (const FbString& src);
58#endif
59
55bool haveUTF8(); 60bool haveUTF8();
56 61
57} // namespace FbStringUtil 62} // namespace FbStringUtil
diff --git a/src/FbTk/Font.cc b/src/FbTk/Font.cc
index cbd8250..28341a7 100644
--- a/src/FbTk/Font.cc
+++ b/src/FbTk/Font.cc
@@ -248,7 +248,13 @@ bool Font::load(const string &name) {
248} 248}
249 249
250unsigned int Font::textWidth(const FbString &text, unsigned int size) const { 250unsigned int Font::textWidth(const FbString &text, unsigned int size) const {
251 return m_fontimp->textWidth(text, size); 251#ifdef HAVE_FRIBIDI
252 const FbString visualOrder(FbTk::FbStringUtil::BidiLog2Vis(text));
253#else
254 const FbString &visualOrder = text;
255#endif
256
257 return m_fontimp->textWidth(visualOrder, size);
252} 258}
253 259
254unsigned int Font::height() const { 260unsigned int Font::height() const {
@@ -273,31 +279,30 @@ void Font::drawText(const FbDrawable &w, int screen, GC gc,
273 if (text.empty() || len == 0) 279 if (text.empty() || len == 0)
274 return; 280 return;
275 281
276 // so we don't end up in a loop with m_shadow 282#ifdef HAVE_FRIBIDI
277 static bool first_run = true; 283 const FbString visualOrder(FbTk::FbStringUtil::BidiLog2Vis(text));
284#else
285 const FbString &visualOrder = text;
286#endif
287
278 288
279 // draw "effects" first 289 // draw "effects" first
280 if (first_run) { 290 if (m_shadow) {
281 if (m_shadow) { 291 FbTk::GContext shadow_gc(w);
282 FbTk::GContext shadow_gc(w); 292 shadow_gc.setForeground(m_shadow_color);
283 shadow_gc.setForeground(m_shadow_color); 293 m_fontimp->drawText(w, screen, shadow_gc.gc(), visualOrder, len,
284 first_run = false; 294 x + m_shadow_offx, y + m_shadow_offy, orient);
285 drawText(w, screen, shadow_gc.gc(), text, len, 295 } else if (m_halo) {
286 x + m_shadow_offx, y + m_shadow_offy, orient); 296 FbTk::GContext halo_gc(w);
287 first_run = true; 297 halo_gc.setForeground(m_halo_color);
288 } else if (m_halo) { 298 m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x + 1, y + 1, orient);
289 FbTk::GContext halo_gc(w); 299 m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x - 1, y + 1, orient);
290 halo_gc.setForeground(m_halo_color); 300 m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x - 1, y - 1, orient);
291 first_run = false; 301 m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x + 1, y - 1, orient);
292 drawText(w, screen, halo_gc.gc(), text, len, x + 1, y + 1, orient);
293 drawText(w, screen, halo_gc.gc(), text, len, x - 1, y + 1, orient);
294 drawText(w, screen, halo_gc.gc(), text, len, x - 1, y - 1, orient);
295 drawText(w, screen, halo_gc.gc(), text, len, x + 1, y - 1, orient);
296 first_run = true;
297 }
298 } 302 }
299 303
300 m_fontimp->drawText(w, screen, gc, text, len, x, y, orient); 304 m_fontimp->drawText(w, screen, gc, visualOrder, len, x, y, orient);
305
301 306
302} 307}
303 308