added support for bidirectional text
This commit is contained in:
parent
b1b2f47e7d
commit
ea98db4140
4 changed files with 94 additions and 24 deletions
27
configure.in
27
configure.in
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue