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
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/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(
menu,

View file

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

View file

@ -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

View file

@ -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,
m_fontimp->drawText(w, screen, shadow_gc.gc(), visualOrder, 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;
}
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);
}