added support for bidirectional text

This commit is contained in:
Ken Bloom 2010-09-04 15:01:33 +02:00 committed by Mathias Gumz
parent b1b2f47e7d
commit ea98db4140
4 changed files with 94 additions and 24 deletions

View file

@ -163,8 +163,6 @@ dnl Check if iconv uses const in prototype declaration
fi fi
fi fi
AC_CHECK_LIB(nsl, t_open, LIBS="$LIBS -lnsl") AC_CHECK_LIB(nsl, t_open, LIBS="$LIBS -lnsl")
AC_CHECK_LIB(socket, socket, LIBS="$LIBS -lsocket") 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/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
AC_ARG_WITH( AC_ARG_WITH(
menu, menu,

View file

@ -45,6 +45,11 @@
#include <iostream> #include <iostream>
#ifdef HAVE_FRIBIDI
#include <fribidi/fribidi.h>
#endif
using std::string; using std::string;
#ifdef DEBUG #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<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 } // end namespace StringUtil
StringConvertor::StringConvertor(EncodingTarget target): StringConvertor::StringConvertor(EncodingTarget target):
@ -289,4 +325,5 @@ string StringConvertor::recode(const string &src) {
#endif #endif
} }
} // end namespace FbTk } // end namespace FbTk

View file

@ -52,6 +52,11 @@ std::string FbStrToX(const FbString &src);
FbString LocaleStrToFb(const std::string &src); FbString LocaleStrToFb(const std::string &src);
std::string FbStrToLocale(const FbString &src); std::string FbStrToLocale(const FbString &src);
#ifdef HAVE_FRIBIDI
/// Make Bidi
FbString BidiLog2Vis (const FbString& src);
#endif
bool haveUTF8(); bool haveUTF8();
} // namespace FbStringUtil } // namespace FbStringUtil

View file

@ -248,7 +248,13 @@ bool Font::load(const string &name) {
} }
unsigned int Font::textWidth(const FbString &text, unsigned int size) const { 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 { unsigned int Font::height() const {
@ -273,31 +279,30 @@ void Font::drawText(const FbDrawable &w, int screen, GC gc,
if (text.empty() || len == 0) if (text.empty() || len == 0)
return; return;
// so we don't end up in a loop with m_shadow #ifdef HAVE_FRIBIDI
static bool first_run = true; const FbString visualOrder(FbTk::FbStringUtil::BidiLog2Vis(text));
#else
const FbString &visualOrder = text;
#endif
// draw "effects" first // draw "effects" first
if (first_run) { if (m_shadow) {
if (m_shadow) { FbTk::GContext shadow_gc(w);
FbTk::GContext shadow_gc(w); shadow_gc.setForeground(m_shadow_color);
shadow_gc.setForeground(m_shadow_color); m_fontimp->drawText(w, screen, shadow_gc.gc(), visualOrder, len,
first_run = false; x + m_shadow_offx, y + m_shadow_offy, orient);
drawText(w, screen, shadow_gc.gc(), text, len, } else if (m_halo) {
x + m_shadow_offx, y + m_shadow_offy, orient); FbTk::GContext halo_gc(w);
first_run = true; halo_gc.setForeground(m_halo_color);
} else if (m_halo) { m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x + 1, y + 1, orient);
FbTk::GContext halo_gc(w); m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x - 1, y + 1, orient);
halo_gc.setForeground(m_halo_color); m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x - 1, y - 1, orient);
first_run = false; m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, 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);
drawText(w, screen, halo_gc.gc(), text, len, x + 1, y - 1, orient);
first_run = true;
}
} }
m_fontimp->drawText(w, screen, gc, text, len, x, y, orient); m_fontimp->drawText(w, screen, gc, visualOrder, len, x, y, orient);
} }