From ea98db414033aa17aee720135e2f9ee0a08696cc Mon Sep 17 00:00:00 2001 From: Ken Bloom Date: Sat, 4 Sep 2010 15:01:33 +0200 Subject: added support for bidirectional text --- configure.in | 27 +++++++++++++++++++++++++-- src/FbTk/FbString.cc | 37 +++++++++++++++++++++++++++++++++++++ src/FbTk/FbString.hh | 5 +++++ 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 fi fi - - AC_CHECK_LIB(nsl, t_open, LIBS="$LIBS -lnsl") AC_CHECK_LIB(socket, socket, LIBS="$LIBS -lsocket") @@ -603,6 +601,31 @@ fi # ) +enableval="yes" +AC_MSG_CHECKING([whether to have FRIBIDI support]) +AC_ARG_ENABLE(fribidi, + AC_HELP_STRING([--enable-fribidi], + [FRIBIDI support [default=yes]]), , + [enableval=yes]) +if test "x$enableval" = "xyes"; then + AC_MSG_RESULT([yes]) + AC_CHECK_LIB(fribidi, fribidi_version_info, + AC_MSG_CHECKING([for fribidi/fribidi.h]) + AC_TRY_COMPILE( +#include + , fribidi_version_info, + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_FRIBIDI, [1], [Define to 1 if you have FRIBIDI]) + LIBS="$LIBS -lfribidi", + AC_MSG_RESULT([no]))) +else + AC_MSG_RESULT([no]) + CONFIGOPTS="$CONFIGOPTS --disable-fribidi" +fi + + + + AC_ARG_WITH( 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 @@ #include +#ifdef HAVE_FRIBIDI +#include +#endif + + using std::string; #ifdef DEBUG @@ -239,6 +244,37 @@ bool haveUTF8() { } +#ifdef HAVE_FRIBIDI + +FbString BidiLog2Vis (const FbString& src){ + FriBidiChar * us, * out_us; + FriBidiCharType base; + FbString r; + char * out; + + us = new FriBidiChar[src.size()+1]; + out_us = new FriBidiChar[src.size()+1]; + + unsigned int len = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, const_cast(src.c_str()), src.length(), us); + + base = FRIBIDI_TYPE_N; + fribidi_log2vis(us, len, &base, out_us, NULL, NULL, NULL); + + out = new char[4*src.size()+1]; + + fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, out_us, len, out); + + r = out; + + delete[] out_us; + delete[] us; + delete[] out; + + return r; +} + +#endif + } // end namespace StringUtil StringConvertor::StringConvertor(EncodingTarget target): @@ -289,4 +325,5 @@ string StringConvertor::recode(const string &src) { #endif } + } // 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); FbString LocaleStrToFb(const std::string &src); std::string FbStrToLocale(const FbString &src); +#ifdef HAVE_FRIBIDI +/// Make Bidi +FbString BidiLog2Vis (const FbString& src); +#endif + bool haveUTF8(); } // 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) { } unsigned int Font::textWidth(const FbString &text, unsigned int size) const { - return m_fontimp->textWidth(text, size); +#ifdef HAVE_FRIBIDI + const FbString visualOrder(FbTk::FbStringUtil::BidiLog2Vis(text)); +#else + const FbString &visualOrder = text; +#endif + + return m_fontimp->textWidth(visualOrder, size); } unsigned int Font::height() const { @@ -273,31 +279,30 @@ void Font::drawText(const FbDrawable &w, int screen, GC gc, if (text.empty() || len == 0) return; - // so we don't end up in a loop with m_shadow - static bool first_run = true; +#ifdef HAVE_FRIBIDI + const FbString visualOrder(FbTk::FbStringUtil::BidiLog2Vis(text)); +#else + const FbString &visualOrder = text; +#endif + // draw "effects" first - if (first_run) { - if (m_shadow) { - FbTk::GContext shadow_gc(w); - shadow_gc.setForeground(m_shadow_color); - first_run = false; - drawText(w, screen, shadow_gc.gc(), text, len, - x + m_shadow_offx, y + m_shadow_offy, orient); - first_run = true; - } else if (m_halo) { - FbTk::GContext halo_gc(w); - halo_gc.setForeground(m_halo_color); - first_run = false; - drawText(w, screen, halo_gc.gc(), text, len, x + 1, y + 1, orient); - drawText(w, screen, halo_gc.gc(), text, len, x - 1, y + 1, orient); - drawText(w, screen, halo_gc.gc(), text, len, x - 1, y - 1, orient); - drawText(w, screen, halo_gc.gc(), text, len, x + 1, y - 1, orient); - first_run = true; - } + if (m_shadow) { + FbTk::GContext shadow_gc(w); + shadow_gc.setForeground(m_shadow_color); + m_fontimp->drawText(w, screen, shadow_gc.gc(), visualOrder, len, + x + m_shadow_offx, y + m_shadow_offy, orient); + } else if (m_halo) { + FbTk::GContext halo_gc(w); + halo_gc.setForeground(m_halo_color); + m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x + 1, y + 1, orient); + m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x - 1, y + 1, orient); + m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x - 1, y - 1, orient); + m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x + 1, y - 1, orient); } - m_fontimp->drawText(w, screen, gc, text, len, x, y, orient); + m_fontimp->drawText(w, screen, gc, visualOrder, len, x, y, orient); + } -- cgit v0.11.2