all repos — fluxbox @ ea98db414033aa17aee720135e2f9ee0a08696cc

custom fork of the fluxbox windowmanager

added support for bidirectional text
Ken Bloom kbloom at gmail com
commit

ea98db414033aa17aee720135e2f9ee0a08696cc

parent

b1b2f47e7dd185fef88a44a318a9b374083ecb40

4 files changed, 94 insertions(+), 24 deletions(-)

jump to
M configure.inconfigure.in

@@ -163,8 +163,6 @@ fi

fi fi - - AC_CHECK_LIB(nsl, t_open, LIBS="$LIBS -lnsl") AC_CHECK_LIB(socket, socket, LIBS="$LIBS -lsocket")

@@ -601,6 +599,31 @@ # AC_MSG_RESULT([yes])

# AC_CHECK_LIB(Xrandr, XRRUpdateConfiguration, # AC_DEFINE(HAVE_RANDR1_2, 1, "randr 1.2 support")) # ) + + +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/fribidi.h> + , 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 + +
M src/FbTk/FbString.ccsrc/FbTk/FbString.cc

@@ -45,6 +45,11 @@ #include <locale.h>

#include <iostream> +#ifdef HAVE_FRIBIDI +#include <fribidi/fribidi.h> +#endif + + using std::string; #ifdef DEBUG

@@ -239,6 +244,37 @@ return false;

} +#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<char *>(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):

@@ -288,5 +324,6 @@ #else

return src; #endif } + } // end namespace FbTk
M src/FbTk/FbString.hhsrc/FbTk/FbString.hh

@@ -52,6 +52,11 @@ /// Handle thislocale string encodings (strings coming from userspace)

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
M src/FbTk/Font.ccsrc/FbTk/Font.cc

@@ -248,7 +248,13 @@ return false;

} 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 @@ Orientation orient) const {

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); + }