diff options
author | Ken Bloom <kbloom at gmail com> | 2010-09-04 13:01:33 (GMT) |
---|---|---|
committer | Mathias Gumz <akira at fluxbox dot org> | 2010-09-04 13:01:33 (GMT) |
commit | ea98db414033aa17aee720135e2f9ee0a08696cc (patch) | |
tree | 40f0f68ee4a86289d832713890c226f31cdf853a /src/FbTk | |
parent | b1b2f47e7dd185fef88a44a318a9b374083ecb40 (diff) | |
download | fluxbox-ea98db414033aa17aee720135e2f9ee0a08696cc.zip fluxbox-ea98db414033aa17aee720135e2f9ee0a08696cc.tar.bz2 |
added support for bidirectional text
Diffstat (limited to 'src/FbTk')
-rw-r--r-- | src/FbTk/FbString.cc | 37 | ||||
-rw-r--r-- | src/FbTk/FbString.hh | 5 | ||||
-rw-r--r-- | src/FbTk/Font.cc | 49 |
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 | |||
48 | using std::string; | 53 | using 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 | |||
249 | FbString 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 | ||
244 | StringConvertor::StringConvertor(EncodingTarget target): | 280 | StringConvertor::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); | |||
52 | FbString LocaleStrToFb(const std::string &src); | 52 | FbString LocaleStrToFb(const std::string &src); |
53 | std::string FbStrToLocale(const FbString &src); | 53 | std::string FbStrToLocale(const FbString &src); |
54 | 54 | ||
55 | #ifdef HAVE_FRIBIDI | ||
56 | /// Make Bidi | ||
57 | FbString BidiLog2Vis (const FbString& src); | ||
58 | #endif | ||
59 | |||
55 | bool haveUTF8(); | 60 | bool 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 | ||
250 | unsigned int Font::textWidth(const FbString &text, unsigned int size) const { | 250 | unsigned 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 | ||
254 | unsigned int Font::height() const { | 260 | unsigned 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 | ||