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 | |
parent | b1b2f47e7dd185fef88a44a318a9b374083ecb40 (diff) | |
download | fluxbox-ea98db414033aa17aee720135e2f9ee0a08696cc.zip fluxbox-ea98db414033aa17aee720135e2f9ee0a08696cc.tar.bz2 |
added support for bidirectional text
-rw-r--r-- | configure.in | 27 | ||||
-rw-r--r-- | src/FbTk/FbString.cc | 37 | ||||
-rw-r--r-- | src/FbTk/FbString.hh | 5 | ||||
-rw-r--r-- | src/FbTk/Font.cc | 49 |
4 files changed, 94 insertions, 24 deletions
diff --git a/configure.in b/configure.in index 2766054..263beaf 100644 --- a/configure.in +++ b/configure.in | |||
@@ -163,8 +163,6 @@ dnl Check if iconv uses const in prototype declaration | |||
163 | fi | 163 | fi |
164 | fi | 164 | fi |
165 | 165 | ||
166 | |||
167 | |||
168 | AC_CHECK_LIB(nsl, t_open, LIBS="$LIBS -lnsl") | 166 | AC_CHECK_LIB(nsl, t_open, LIBS="$LIBS -lnsl") |
169 | AC_CHECK_LIB(socket, socket, LIBS="$LIBS -lsocket") | 167 | AC_CHECK_LIB(socket, socket, LIBS="$LIBS -lsocket") |
170 | 168 | ||
@@ -603,6 +601,31 @@ fi | |||
603 | # ) | 601 | # ) |
604 | 602 | ||
605 | 603 | ||
604 | enableval="yes" | ||
605 | AC_MSG_CHECKING([whether to have FRIBIDI support]) | ||
606 | AC_ARG_ENABLE(fribidi, | ||
607 | AC_HELP_STRING([--enable-fribidi], | ||
608 | [FRIBIDI support [default=yes]]), , | ||
609 | [enableval=yes]) | ||
610 | if test "x$enableval" = "xyes"; then | ||
611 | AC_MSG_RESULT([yes]) | ||
612 | AC_CHECK_LIB(fribidi, fribidi_version_info, | ||
613 | AC_MSG_CHECKING([for fribidi/fribidi.h]) | ||
614 | AC_TRY_COMPILE( | ||
615 | #include <fribidi/fribidi.h> | ||
616 | , fribidi_version_info, | ||
617 | AC_MSG_RESULT([yes]) | ||
618 | AC_DEFINE(HAVE_FRIBIDI, [1], [Define to 1 if you have FRIBIDI]) | ||
619 | LIBS="$LIBS -lfribidi", | ||
620 | AC_MSG_RESULT([no]))) | ||
621 | else | ||
622 | AC_MSG_RESULT([no]) | ||
623 | CONFIGOPTS="$CONFIGOPTS --disable-fribidi" | ||
624 | fi | ||
625 | |||
626 | |||
627 | |||
628 | |||
606 | 629 | ||
607 | AC_ARG_WITH( | 630 | AC_ARG_WITH( |
608 | menu, | 631 | menu, |
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 | ||