From 52cb3758861117dbd30c63fd2e24fad5e9900742 Mon Sep 17 00:00:00 2001 From: fluxgen Date: Tue, 10 Aug 2004 11:22:10 +0000 Subject: utf-8 fix, a fixed patch from Sergey Kuleshov --- src/FbTk/Font.cc | 139 ++++++++++++++++++++++++++++++++++++++++++++++++------- src/FbTk/Font.hh | 6 ++- 2 files changed, 128 insertions(+), 17 deletions(-) diff --git a/src/FbTk/Font.cc b/src/FbTk/Font.cc index 453a195..75d89f1 100644 --- a/src/FbTk/Font.cc +++ b/src/FbTk/Font.cc @@ -1,5 +1,5 @@ // Font.cc -// Copyright (c) 2002 Henrik Kinnunen (fluxgen@linuxmail.org) +// Copyright (c) 2002-2004 Henrik Kinnunen (fluxgen@linuxmail.org) // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -//$Id: Font.cc,v 1.7 2004/06/07 11:46:05 rathnor Exp $ +//$Id: Font.cc,v 1.8 2004/08/10 11:21:50 fluxgen Exp $ #include "Font.hh" @@ -44,7 +44,6 @@ #include "XFontImp.hh" #include "GContext.hh" - //use gnu extensions #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -58,12 +57,59 @@ #include #include #include + +#include + using namespace std; #ifdef HAVE_SETLOCALE #include #endif //HAVE_SETLOCALE +/** + Recodes the text from one encoding to another + assuming cd is correct + @param cd the iconv type + @param msg text to be converted + @param len number of chars to convert + @return the recoded string, or 0 on failure +*/ +static char* recode(iconv_t cd, + const char *msg, size_t size) { + + // If empty message, yes this can happen, return + if(strlen(msg) == 0) + return 0; + + + size_t inbytesleft = strlen(msg); + size_t outbytesleft = 4*inbytesleft; + char *new_msg = new char[outbytesleft]; + char *new_msg_ptr = new_msg; + char *msg_ptr = strdup(msg); + + if (iconv(cd, &msg_ptr, &inbytesleft, &new_msg, &outbytesleft) == -1) { + // iconv can fail for three reasons + // 1) Invalid multibyte sequence is encountered in the input + // 2) An incomplete multibyte sequence + // 3) The output buffer has no more room for the next converted character. + // So we the delete new message and return original message + delete new_msg; + free(msg_ptr); + return 0; + } + free(msg_ptr); + + *new_msg_ptr = '\0'; + + if(inbytesleft != 0) { + delete new_msg; + return 0; + } + + return new_msg; +} + namespace FbTk { bool Font::m_multibyte = false; @@ -71,21 +117,53 @@ bool Font::m_utf8mode = false; Font::Font(const char *name, bool antialias): m_fontimp(0), - m_antialias(false), m_rotated(false), m_shadow(false) { - + m_antialias(false), m_rotated(false), m_shadow(false), + m_iconv((iconv_t)-1) { + // MB_CUR_MAX returns the size of a char in the current locale if (MB_CUR_MAX > 1) // more than one byte, then we're multibyte m_multibyte = true; - char *s; // temporary string for enviroment variable + char *envstr; // temporary string for enviroment variable // check for utf-8 mode - if (((s = getenv("LC_ALL")) && *s) || - ((s = getenv("LC_CTYPE")) && *s) || - ((s = getenv("LANG")) && *s)) { - if (strstr(s, "UTF-8")) + if (((envstr = getenv("LC_ALL")) && *envstr) || + ((envstr = getenv("LC_CTYPE")) && *envstr) || + ((envstr = getenv("LANG")) && *envstr)) { + if (strstr(envstr, "UTF-8")) m_utf8mode = true; + m_locale = envstr; + int index = m_locale.find("."); + if (index != 0) + m_locale = m_locale.substr(index + 1); + else + m_locale = "UTF-8"; + } + // if locale isn't UTF-8 we try to + // create a iconv pointer so we can + // convert non utf-8 strings to utf-8 + if (m_locale != "UTF-8") { +#ifdef DEBUG + cerr<<"FbTk::Font: m_locale = "<(m_fontimp.get()); font->setRotate(false); // disable rotation temporarly - font->drawText(w, screen, gc, text, len, x, y); + font->drawText(w, screen, gc, real_text, len, x, y); font->setRotate(true); // enable rotation } catch (std::bad_cast &bc) { // draw normal... - m_fontimp->drawText(w, screen, gc, text, len, x, y); + m_fontimp->drawText(w, screen, gc, real_text, len, x, y); } } else - m_fontimp->drawText(w, screen, gc, text, len, x, y); + m_fontimp->drawText(w, screen, gc, real_text, len, x, y); + if (rtext != 0) + delete rtext; } @@ -263,4 +368,6 @@ void Font::rotate(float angle) { m_angle = angle; } + }; + diff --git a/src/FbTk/Font.hh b/src/FbTk/Font.hh index 2502c1b..fded0c4 100644 --- a/src/FbTk/Font.hh +++ b/src/FbTk/Font.hh @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -//$Id: Font.hh,v 1.7 2003/12/19 17:07:53 fluxgen Exp $ +//$Id: Font.hh,v 1.8 2004/08/10 11:22:10 fluxgen Exp $ #ifndef FBTK_FONT_HH #define FBTK_FONT_HH @@ -30,6 +30,8 @@ #include #include +#include + namespace FbTk { class FontImp; @@ -100,6 +102,8 @@ private: bool m_rotated; ///< wheter we're rotated or not float m_angle; ///< rotation angle bool m_shadow; ///< shadow text + std::string m_locale; ///< system encoding + iconv_t m_iconv; }; } //end namespace FbTk -- cgit v0.11.2