handle utf-8 strings properly.
use utf8 internally
This commit is contained in:
parent
0e9fa988ff
commit
520f552be7
18 changed files with 111 additions and 206 deletions
|
@ -1,5 +1,12 @@
|
|||
(Format: Year/Month/Day)
|
||||
Changes for 0.9.16:
|
||||
*06/05/07:
|
||||
* Handle UTF-8 strings properly (Simon)
|
||||
- still need to integrate EWMH strings properly (they are utf8)
|
||||
- still need to fix up TextBox
|
||||
FbTk/... FbString.hh/cc App.cc FOnt.hh/cc FontImp.hh Makefile.am
|
||||
XFontImp.hh/cc XmbFontImp.hh/cc XftFontImp.hh/cc TextButton.cc
|
||||
Window.cc Xutil.hh/cc tests/testFont.cc
|
||||
*06/05/01:
|
||||
* Make apps file keywords case insensitive, plus reload it (if newer)
|
||||
before save on close and remember menu events (Simon)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#include "App.hh"
|
||||
#include "FbString.hh"
|
||||
#include "Font.hh"
|
||||
#include "Image.hh"
|
||||
|
||||
|
@ -49,15 +50,16 @@ App::App(const char *displayname):m_done(false), m_display(0) {
|
|||
if (!m_display)
|
||||
throw std::string("Couldn't connect to XServer");
|
||||
|
||||
Font::init();
|
||||
FbStringUtil::init();
|
||||
Image::init();
|
||||
}
|
||||
|
||||
App::~App() {
|
||||
if (m_display != 0) {
|
||||
|
||||
|
||||
Font::shutdown();
|
||||
Image::shutdown();
|
||||
FbStringUtil::shutdown();
|
||||
|
||||
XCloseDisplay(m_display);
|
||||
m_display = 0;
|
||||
|
|
153
src/FbTk/Font.cc
153
src/FbTk/Font.cc
|
@ -71,6 +71,7 @@
|
|||
#include <typeinfo>
|
||||
#include <langinfo.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_CSTDLIB
|
||||
#include <cstdlib>
|
||||
|
@ -87,68 +88,6 @@ namespace {
|
|||
#include <locale.h>
|
||||
#endif //HAVE_SETLOCALE
|
||||
|
||||
#ifdef HAVE_ICONV
|
||||
/**
|
||||
Recodes the text from one encoding to another
|
||||
assuming cd is correct
|
||||
@param cd the iconv type
|
||||
@param msg text to be converted
|
||||
@param size number of chars to convert
|
||||
@return the recoded string, or 0 on failure
|
||||
*/
|
||||
char* recode(iconv_t cd,
|
||||
const char *msg, size_t size) {
|
||||
|
||||
// If empty message, yes this can happen, return
|
||||
if(strlen(msg) == 0 || size == 0)
|
||||
return 0;
|
||||
|
||||
if(strlen(msg) < size)
|
||||
size = strlen(msg);
|
||||
|
||||
size_t inbytesleft = size;
|
||||
size_t outbytesleft = 4*inbytesleft;
|
||||
char *new_msg = new char[outbytesleft];
|
||||
char *new_msg_ptr = new_msg;
|
||||
char *msg_ptr = strdup(msg);
|
||||
char *orig_msg_ptr = msg_ptr; // msg_ptr modified in iconv call
|
||||
size_t result = (size_t)(-1);
|
||||
|
||||
#ifdef HAVE_CONST_ICONV
|
||||
result = iconv(cd, (const char**)(&msg_ptr), &inbytesleft, &new_msg, &outbytesleft);
|
||||
#else
|
||||
result = iconv(cd, &msg_ptr, &inbytesleft, &new_msg, &outbytesleft);
|
||||
#endif // HAVE_CONST_ICONV
|
||||
|
||||
if (result == (size_t)(-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_ptr;
|
||||
free(orig_msg_ptr);
|
||||
return 0;
|
||||
}
|
||||
free(orig_msg_ptr);
|
||||
|
||||
*new_msg = '\0';
|
||||
|
||||
if(inbytesleft != 0) {
|
||||
delete[] new_msg_ptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return new_msg_ptr;
|
||||
}
|
||||
#else
|
||||
|
||||
char *recode(int cd,
|
||||
const char *msg, size_t size) {
|
||||
return 0;
|
||||
}
|
||||
#endif // HAVE_ICONV
|
||||
|
||||
// use to map <font1>|<font2>|<font3> => <fontthatworks>
|
||||
typedef std::map<std::string, std::string> StringMap;
|
||||
typedef StringMap::iterator StringMapIt;
|
||||
|
@ -179,11 +118,6 @@ bool Font::s_multibyte = false;
|
|||
bool Font::s_utf8mode = false;
|
||||
|
||||
|
||||
void Font::init() {
|
||||
// must be set before the first XFontSet is created
|
||||
setlocale(LC_CTYPE, "");
|
||||
}
|
||||
|
||||
void Font::shutdown() {
|
||||
|
||||
FontCacheIt fit;
|
||||
|
@ -203,12 +137,7 @@ Font::Font(const char *name):
|
|||
m_fontimp(0),
|
||||
m_shadow(false), m_shadow_color("black", DefaultScreen(App::instance()->display())),
|
||||
m_shadow_offx(2), m_shadow_offy(2),
|
||||
m_halo(false), m_halo_color("white", DefaultScreen(App::instance()->display())),
|
||||
#ifdef HAVE_ICONV
|
||||
m_iconv((iconv_t)(-1))
|
||||
#else
|
||||
m_iconv(-1)
|
||||
#endif // HAVE_ICONV
|
||||
m_halo(false), m_halo_color("white", DefaultScreen(App::instance()->display()))
|
||||
{
|
||||
// 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
|
||||
|
@ -224,35 +153,9 @@ Font::Font(const char *name):
|
|||
if (locale_codeset && strcmp("UTF-8", locale_codeset) == 0) {
|
||||
s_utf8mode = true;
|
||||
} else if (locale_codeset != 0) {
|
||||
// if locale isn't UTF-8 we try to
|
||||
// create a iconv pointer so we can
|
||||
// convert non utf-8 strings to utf-8
|
||||
|
||||
#ifdef DEBUG
|
||||
cerr<<"FbTk::Font: check UTF-8 convert for codeset = "<<locale_codeset<<endl;
|
||||
#endif // DEBUG
|
||||
|
||||
#ifdef HAVE_ICONV
|
||||
m_iconv = iconv_open("UTF-8", locale_codeset);
|
||||
if(m_iconv == (iconv_t)(-1)) {
|
||||
cerr<<"FbTk::Font: code error: from "<<locale_codeset<<" to: UTF-8"<<endl;
|
||||
// if we failed with iconv then we can't convert
|
||||
// the strings to utf-8, so we disable utf8 mode
|
||||
s_utf8mode = false;
|
||||
} else {
|
||||
// success, we can now enable utf8mode
|
||||
// and if antialias is on later we can recode
|
||||
// the non utf-8 string to utf-8 and use utf-8
|
||||
// drawing functions
|
||||
s_utf8mode = true;
|
||||
}
|
||||
#endif // HAVE_ICONV
|
||||
s_utf8mode = FbStringUtil::haveUTF8();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
cerr<<"FbTk::Font m_iconv = "<<m_iconv<<endl;
|
||||
#endif // DEBUG
|
||||
|
||||
if (name != 0) {
|
||||
load(name);
|
||||
}
|
||||
|
@ -260,10 +163,6 @@ Font::Font(const char *name):
|
|||
}
|
||||
|
||||
Font::~Font() {
|
||||
#ifdef HAVE_ICONV
|
||||
if (m_iconv != (iconv_t)(-1))
|
||||
iconv_close(m_iconv);
|
||||
#endif // HAVE_ICONV
|
||||
}
|
||||
|
||||
bool Font::load(const std::string &name) {
|
||||
|
@ -333,18 +232,7 @@ bool Font::load(const std::string &name) {
|
|||
return false;
|
||||
}
|
||||
|
||||
unsigned int Font::textWidth(const char * const text, unsigned int size) const {
|
||||
#ifdef HAVE_ICONV
|
||||
if (m_fontimp->utf8() && m_iconv != (iconv_t)(-1)) {
|
||||
char* rtext = recode(m_iconv, text, size);
|
||||
if (rtext != 0)
|
||||
size = strlen(rtext);
|
||||
unsigned int r = m_fontimp->textWidth(rtext ? rtext : text, size);
|
||||
if (rtext != 0)
|
||||
delete[] rtext;
|
||||
return r;
|
||||
}
|
||||
#endif // HAVE_ICONV
|
||||
unsigned int Font::textWidth(const FbString &text, unsigned int size) const {
|
||||
return m_fontimp->textWidth(text, size);
|
||||
}
|
||||
|
||||
|
@ -365,53 +253,36 @@ bool Font::validOrientation(FbTk::Orientation orient) {
|
|||
}
|
||||
|
||||
void Font::drawText(const FbDrawable &w, int screen, GC gc,
|
||||
const char *text, size_t len, int x, int y,
|
||||
const FbString &text, size_t len, int x, int y,
|
||||
Orientation orient) const {
|
||||
if (text == 0 || len == 0)
|
||||
if (text.empty() || len == 0)
|
||||
return;
|
||||
|
||||
char* rtext = 0;
|
||||
|
||||
// so we don't end up in a loop with m_shadow
|
||||
static bool first_run = true;
|
||||
|
||||
#ifdef HAVE_ICONV
|
||||
if (m_fontimp->utf8() && m_iconv != (iconv_t)(-1) && first_run) {
|
||||
rtext = recode(m_iconv, text, len);
|
||||
if (rtext != 0) {
|
||||
len = strlen(rtext);
|
||||
// ok, we can't use utf8 mode since the string is invalid
|
||||
}
|
||||
}
|
||||
#endif // HAVE_ICONV
|
||||
|
||||
const char *real_text = rtext ? rtext : text;
|
||||
|
||||
// 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(), real_text, len,
|
||||
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(), real_text, len, x + 1, y + 1, orient);
|
||||
drawText(w, screen, halo_gc.gc(), real_text, len, x - 1, y + 1, orient);
|
||||
drawText(w, screen, halo_gc.gc(), real_text, len, x - 1, y - 1, orient);
|
||||
drawText(w, screen, halo_gc.gc(), real_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);
|
||||
drawText(w, screen, halo_gc.gc(), text, len, x + 1, y - 1, orient);
|
||||
first_run = true;
|
||||
}
|
||||
}
|
||||
|
||||
m_fontimp->drawText(w, screen, gc, real_text, len, x, y, orient);
|
||||
|
||||
if (rtext != 0)
|
||||
delete[] rtext;
|
||||
m_fontimp->drawText(w, screen, gc, text, len, x, y, orient);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -27,16 +27,11 @@
|
|||
#include <X11/Xlib.h>
|
||||
#include <X11/Xresource.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#ifdef HAVE_ICONV
|
||||
#include <iconv.h>
|
||||
#endif // HAVE_ICONV
|
||||
|
||||
#include "FbString.hh"
|
||||
#include "Color.hh"
|
||||
#include "Text.hh"
|
||||
|
||||
|
@ -51,10 +46,7 @@ class FbDrawable;
|
|||
class Font {
|
||||
public:
|
||||
|
||||
/// called at FbTk::App creation time, initializes some stuff
|
||||
static void init();
|
||||
|
||||
/// called at FbTk::App destruction time, cleans up what was inited first
|
||||
/// called at FbTk::App destruction time, cleans up cache
|
||||
static void shutdown();
|
||||
|
||||
/// @return true if multibyte is enabled, else false
|
||||
|
@ -86,7 +78,7 @@ public:
|
|||
@param size length of text in bytes
|
||||
@return size of text in pixels
|
||||
*/
|
||||
unsigned int textWidth(const char * const text, unsigned int size) const;
|
||||
unsigned int textWidth(const FbString &text, unsigned int size) const;
|
||||
unsigned int height() const;
|
||||
int ascent() const;
|
||||
int descent() const;
|
||||
|
@ -110,7 +102,7 @@ public:
|
|||
@param rotate if the text should be drawn rotated (if it's rotated before)
|
||||
*/
|
||||
void drawText(const FbDrawable &w, int screen, GC gc,
|
||||
const char *text, size_t len,
|
||||
const FbString &text, size_t len,
|
||||
int x, int y, FbTk::Orientation orient = ROT0) const;
|
||||
|
||||
bool hasShadow() const { return m_shadow; }
|
||||
|
@ -130,11 +122,6 @@ private:
|
|||
int m_shadow_offy; ///< offset x for shadow
|
||||
bool m_halo; ///< halo text
|
||||
Color m_halo_color; ///< halo color
|
||||
#ifdef HAVE_ICONV
|
||||
iconv_t m_iconv;
|
||||
#else
|
||||
int m_iconv;
|
||||
#endif // HAVE_ICONV
|
||||
};
|
||||
|
||||
} //end namespace FbTk
|
||||
|
|
|
@ -44,8 +44,8 @@ class FontImp {
|
|||
public:
|
||||
virtual ~FontImp() { }
|
||||
virtual bool load(const std::string &name) = 0;
|
||||
virtual void drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y, FbTk::Orientation orient) const = 0;
|
||||
virtual unsigned int textWidth(const char * const text, unsigned int size) const = 0;
|
||||
virtual void drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient) const = 0;
|
||||
virtual unsigned int textWidth(const FbString &text, unsigned int size) const = 0;
|
||||
virtual bool validOrientation(FbTk::Orientation orient) { return orient == ROT0; }
|
||||
virtual int ascent() const = 0;
|
||||
virtual int descent() const = 0;
|
||||
|
|
|
@ -36,6 +36,7 @@ libFbTk_a_SOURCES = App.hh App.cc Color.cc Color.hh Command.hh \
|
|||
XLayer.cc XLayer.hh XLayerItem.cc XLayerItem.hh \
|
||||
Resource.hh Resource.cc \
|
||||
StringUtil.hh StringUtil.cc \
|
||||
FbString.hh FbString.cc \
|
||||
Subject.hh Subject.cc Observer.hh Observer.cc \
|
||||
Transparent.hh Transparent.cc \
|
||||
FbPixmap.hh FbPixmap.cc \
|
||||
|
|
|
@ -133,7 +133,7 @@ void TextButton::clearArea(int x, int y,
|
|||
|
||||
|
||||
unsigned int TextButton::textWidth() const {
|
||||
return font().textWidth(text().c_str(), text().size());
|
||||
return font().textWidth(text().data(), text().size());
|
||||
}
|
||||
|
||||
unsigned int TextButton::textHeight() const {
|
||||
|
@ -157,7 +157,7 @@ void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) {
|
|||
bevel(),
|
||||
justify(),
|
||||
font(),
|
||||
text().c_str(), text().size(),
|
||||
text().data(), text().size(),
|
||||
textlen); // return new text lne
|
||||
|
||||
// center text by default
|
||||
|
@ -175,7 +175,7 @@ void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) {
|
|||
font().drawText(*drawable,
|
||||
screenNumber(),
|
||||
gc(), // graphic context
|
||||
text().c_str(), textlen, // string and string size
|
||||
text().data(), textlen, // string and string size
|
||||
textx, texty, m_orientation); // position
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ bool XFontImp::load(const std::string &fontname) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void XFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y, FbTk::Orientation orient) const {
|
||||
void XFontImp::drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient) const {
|
||||
if (m_fontstruct == 0)
|
||||
return;
|
||||
|
||||
|
@ -91,15 +91,23 @@ void XFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *text
|
|||
return;
|
||||
}
|
||||
|
||||
std::string localestr = text;
|
||||
localestr.erase(len, std::string::npos);
|
||||
localestr = FbStringUtil::FbStrToLocale(localestr);
|
||||
|
||||
XSetFont(w.display(), gc, m_fontstruct->fid);
|
||||
XDrawString(w.display(), w.drawable(), gc, x, y, text, len);
|
||||
XDrawString(w.display(), w.drawable(), gc, x, y, localestr.data(), localestr.size());
|
||||
}
|
||||
|
||||
unsigned int XFontImp::textWidth(const char * const text, unsigned int size) const {
|
||||
if (text == 0 || m_fontstruct == 0)
|
||||
unsigned int XFontImp::textWidth(const FbString &text, unsigned int size) const {
|
||||
if (text.empty() || m_fontstruct == 0)
|
||||
return 0;
|
||||
|
||||
return XTextWidth(m_fontstruct, text, size);
|
||||
std::string localestr = text;
|
||||
localestr.erase(size, std::string::npos);
|
||||
localestr = FbStringUtil::FbStrToLocale(localestr);
|
||||
|
||||
return XTextWidth(m_fontstruct, localestr.data(), localestr.size());
|
||||
}
|
||||
|
||||
unsigned int XFontImp::height() const {
|
||||
|
@ -308,7 +316,7 @@ void XFontImp::freeRotFont(XRotFontStruct *rotfont) {
|
|||
rotfont = 0;
|
||||
}
|
||||
|
||||
void XFontImp::drawRotText(Drawable w, int screen, GC gc, const char *text, size_t len, int x, int y, FbTk::Orientation orient) const {
|
||||
void XFontImp::drawRotText(Drawable w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient) const {
|
||||
|
||||
Display *dpy = App::instance()->display();
|
||||
static GC my_gc = 0;
|
||||
|
@ -316,7 +324,7 @@ void XFontImp::drawRotText(Drawable w, int screen, GC gc, const char *text, size
|
|||
|
||||
XRotFontStruct *rotfont = m_rotfonts[orient];
|
||||
|
||||
if (text == NULL || len<1)
|
||||
if (text.empty() || len<1)
|
||||
return;
|
||||
|
||||
if (my_gc == 0)
|
||||
|
@ -327,10 +335,16 @@ void XFontImp::drawRotText(Drawable w, int screen, GC gc, const char *text, size
|
|||
// vertical or upside down
|
||||
|
||||
XSetFillStyle(dpy, my_gc, FillStippled);
|
||||
std::string localestr = text;
|
||||
localestr.erase(len, std::string::npos);
|
||||
localestr = FbStringUtil::FbStrToLocale(localestr);
|
||||
const char *ctext = localestr.data();
|
||||
len = localestr.size();
|
||||
|
||||
|
||||
// loop through each character in texting
|
||||
for (size_t i = 0; i<len; i++) {
|
||||
ichar = text[i]-32;
|
||||
ichar = ctext[i]-32;
|
||||
|
||||
// make sure it's a printing character
|
||||
if (ichar >= 0 && ichar<95) {
|
||||
|
|
|
@ -36,11 +36,11 @@ public:
|
|||
explicit XFontImp(const char *filename = 0);
|
||||
~XFontImp();
|
||||
bool load(const std::string &filename);
|
||||
unsigned int textWidth(const char * const text, unsigned int size) const;
|
||||
unsigned int textWidth(const FbString &text, unsigned int size) const;
|
||||
unsigned int height() const;
|
||||
int ascent() const;
|
||||
int descent() const { return m_fontstruct ? m_fontstruct->descent : 0; }
|
||||
void drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y, FbTk::Orientation orient) const;
|
||||
void drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient) const;
|
||||
|
||||
bool validOrientation(FbTk::Orientation orient);
|
||||
|
||||
|
@ -76,7 +76,7 @@ private:
|
|||
void rotate(FbTk::Orientation orient);
|
||||
|
||||
void freeRotFont(XRotFontStruct * rotfont);
|
||||
void drawRotText(Drawable w, int screen, GC gc, const char *text, size_t len, int x, int y, FbTk::Orientation orient) const;
|
||||
void drawRotText(Drawable w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient) const;
|
||||
|
||||
XRotFontStruct *m_rotfonts[4]; ///< rotated font structure (only 3 used)
|
||||
XFontStruct *m_fontstruct; ///< X font structure
|
||||
|
|
|
@ -72,7 +72,7 @@ bool XftFontImp::load(const std::string &name) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y, FbTk::Orientation orient) const {
|
||||
void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient) const {
|
||||
if (m_xftfonts[orient] == 0)
|
||||
return;
|
||||
|
||||
|
@ -130,14 +130,14 @@ void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *te
|
|||
XGlyphInfo ginfo;
|
||||
XftTextExtentsUtf8(w.display(),
|
||||
m_xftfonts[ROT0],
|
||||
(XftChar8 *)text, len,
|
||||
(XftChar8 *)text.data(), len,
|
||||
&ginfo);
|
||||
if (ginfo.xOff != 0) {
|
||||
XftDrawStringUtf8(draw,
|
||||
&xftcolor,
|
||||
font,
|
||||
x, y,
|
||||
(XftChar8 *)(text), len);
|
||||
(XftChar8 *)(text.data()), len);
|
||||
XftColorFree(w.display(),
|
||||
DefaultVisual(w.display(), screen),
|
||||
DefaultColormap(w.display(), screen), &xftcolor);
|
||||
|
@ -151,7 +151,7 @@ void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *te
|
|||
&xftcolor,
|
||||
font,
|
||||
x, y,
|
||||
(XftChar8 *)(text), len);
|
||||
(XftChar8 *)(text.data()), len);
|
||||
|
||||
|
||||
XftColorFree(w.display(),
|
||||
|
@ -160,7 +160,7 @@ void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *te
|
|||
XftDrawDestroy(draw);
|
||||
}
|
||||
|
||||
unsigned int XftFontImp::textWidth(const char * const text, unsigned int len) const {
|
||||
unsigned int XftFontImp::textWidth(const FbString &text, unsigned int len) const {
|
||||
if (m_xftfonts[ROT0] == 0)
|
||||
return 0;
|
||||
|
||||
|
@ -174,7 +174,7 @@ unsigned int XftFontImp::textWidth(const char * const text, unsigned int len) co
|
|||
if (m_utf8mode) {
|
||||
XftTextExtentsUtf8(disp,
|
||||
font,
|
||||
(XftChar8 *)text, len,
|
||||
(XftChar8 *)text.data(), len,
|
||||
&ginfo);
|
||||
if (ginfo.xOff != 0)
|
||||
return ginfo.xOff;
|
||||
|
@ -183,9 +183,13 @@ unsigned int XftFontImp::textWidth(const char * const text, unsigned int len) co
|
|||
}
|
||||
#endif //HAVE_XFT_UTF8_STRING
|
||||
|
||||
std::string localestr = text;
|
||||
localestr.erase(len, std::string::npos);
|
||||
localestr = FbStringUtil::FbStrToLocale(localestr);
|
||||
|
||||
XftTextExtents8(disp,
|
||||
font,
|
||||
(XftChar8 *)text, len,
|
||||
(XftChar8 *)localestr.data(), localestr.size(),
|
||||
&ginfo);
|
||||
|
||||
return ginfo.xOff;
|
||||
|
|
|
@ -36,8 +36,8 @@ public:
|
|||
XftFontImp(const char *fontname, bool utf8);
|
||||
~XftFontImp();
|
||||
bool load(const std::string &name);
|
||||
void drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y , FbTk::Orientation orient) const;
|
||||
unsigned int textWidth(const char * const text, unsigned int len) const;
|
||||
void drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y , FbTk::Orientation orient) const;
|
||||
unsigned int textWidth(const FbString &text, unsigned int len) const;
|
||||
unsigned int height() const;
|
||||
int ascent() const { return m_xftfonts[0] ? m_xftfonts[0]->ascent : 0; }
|
||||
int descent() const { return m_xftfonts[0] ? m_xftfonts[0]->descent : 0; }
|
||||
|
|
|
@ -123,7 +123,9 @@ XFontSet createFontSet(const char *fontname, bool& utf8mode) {
|
|||
#ifdef HAVE_SETLOCALE
|
||||
if (utf8mode) {
|
||||
orig_locale = setlocale(LC_CTYPE, NULL);
|
||||
setlocale(LC_CTYPE, "UTF-8");
|
||||
if (setlocale(LC_CTYPE, "UTF-8") == NULL) {
|
||||
utf8mode = false;
|
||||
}
|
||||
}
|
||||
#endif // HAVE_SETLOCALE
|
||||
fs = XCreateFontSet(display,
|
||||
|
@ -146,11 +148,13 @@ XFontSet createFontSet(const char *fontname, bool& utf8mode) {
|
|||
fs = XCreateFontSet(display, fontname,
|
||||
&missing, &nmissing, &def);
|
||||
setlocale(LC_CTYPE, orig_locale.c_str());
|
||||
return fs;
|
||||
}
|
||||
if (utf8mode)
|
||||
setlocale(LC_CTYPE, orig_locale.c_str());
|
||||
#endif // HAVE_SETLOCALE
|
||||
|
||||
// set to false because our strings won't be utf8-happy
|
||||
utf8mode = false;
|
||||
|
||||
return fs;
|
||||
|
@ -186,7 +190,7 @@ bool XmbFontImp::load(const std::string &fontname) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void XmbFontImp::drawText(const FbDrawable &d, int screen, GC main_gc, const char *text,
|
||||
void XmbFontImp::drawText(const FbDrawable &d, int screen, GC main_gc, const FbString &text,
|
||||
size_t len, int x, int y, FbTk::Orientation orient) const {
|
||||
|
||||
if (m_fontset == 0)
|
||||
|
@ -197,13 +201,16 @@ void XmbFontImp::drawText(const FbDrawable &d, int screen, GC main_gc, const cha
|
|||
if (m_utf8mode) {
|
||||
Xutf8DrawString(d.display(), d.drawable(), m_fontset,
|
||||
main_gc, x, y,
|
||||
text, len);
|
||||
text.data(), len);
|
||||
} else
|
||||
#endif //X_HAVE_UTF8_STRING
|
||||
{
|
||||
std::string localestr = text;
|
||||
localestr.erase(len, std::string::npos);
|
||||
localestr = FbStringUtil::FbStrToLocale(localestr);
|
||||
XmbDrawString(d.display(), d.drawable(), m_fontset,
|
||||
main_gc, x, y,
|
||||
text, len);
|
||||
localestr.data(), localestr.size());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -233,13 +240,16 @@ void XmbFontImp::drawText(const FbDrawable &d, int screen, GC main_gc, const cha
|
|||
if (m_utf8mode) {
|
||||
Xutf8DrawString(dpy, canvas.drawable(), m_fontset,
|
||||
font_gc.gc(), xpos, ypos,
|
||||
text, len);
|
||||
text.data(), len);
|
||||
} else
|
||||
#endif //X_HAVE_UTF8_STRING
|
||||
{
|
||||
std::string localestr = text;
|
||||
localestr.erase(len, std::string::npos);
|
||||
localestr = FbStringUtil::FbStrToLocale(localestr);
|
||||
XmbDrawString(dpy, canvas.drawable(), m_fontset,
|
||||
font_gc.gc(), xpos, ypos,
|
||||
text, len);
|
||||
localestr.data(), localestr.size());
|
||||
}
|
||||
|
||||
canvas.rotate(orient);
|
||||
|
@ -268,21 +278,24 @@ void XmbFontImp::drawText(const FbDrawable &d, int screen, GC main_gc, const cha
|
|||
|
||||
}
|
||||
|
||||
unsigned int XmbFontImp::textWidth(const char * const text, unsigned int len) const {
|
||||
unsigned int XmbFontImp::textWidth(const FbString &text, unsigned int len) const {
|
||||
if (m_fontset == 0)
|
||||
return 0;
|
||||
|
||||
XRectangle ink, logical;
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
if (m_utf8mode) {
|
||||
Xutf8TextExtents(m_fontset, text, len,
|
||||
Xutf8TextExtents(m_fontset, text.data(), len,
|
||||
&ink, &logical);
|
||||
if (logical.width != 0)
|
||||
return logical.width;
|
||||
}
|
||||
#endif // X_HAVE_UTF8_STRING
|
||||
|
||||
XmbTextExtents(m_fontset, text, len,
|
||||
std::string localestr = text;
|
||||
localestr.erase(len, std::string::npos);
|
||||
localestr = FbStringUtil::FbStrToLocale(localestr);
|
||||
XmbTextExtents(m_fontset, localestr.data(), localestr.size(),
|
||||
&ink, &logical);
|
||||
return logical.width;
|
||||
}
|
||||
|
|
|
@ -36,8 +36,8 @@ public:
|
|||
XmbFontImp(const char *fontname, bool utf8);
|
||||
~XmbFontImp();
|
||||
bool load(const std::string &name);
|
||||
virtual void drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y, FbTk::Orientation orient) const;
|
||||
unsigned int textWidth(const char * const text, unsigned int len) const;
|
||||
virtual void drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient) const;
|
||||
unsigned int textWidth(const FbString &text, unsigned int len) const;
|
||||
unsigned int height() const;
|
||||
int ascent() const { return m_setextents ? -m_setextents->max_ink_extent.y : 0; }
|
||||
int descent() const { return m_setextents ? m_setextents->max_ink_extent.height + m_setextents->max_ink_extent.y : 0; }
|
||||
|
|
|
@ -188,6 +188,7 @@ static void translateMenuItem(Parser &parse, ParseItem &pitem) {
|
|||
} else if (str_key == "nop") {
|
||||
int menuSize = menu.insert(str_label.c_str());
|
||||
menu.setItemEnabled(menuSize-1, false);
|
||||
menu.setItemEnabled(menuSize-1, false);
|
||||
} else if (str_key == "icons") {
|
||||
FbTk::Menu *submenu = MenuCreator::createMenuType("iconmenu", menu.screenNumber());
|
||||
if (submenu == 0)
|
||||
|
|
|
@ -439,7 +439,7 @@ void FluxboxWindow::init() {
|
|||
decorations.sticky = decorations.shade = decorations.tab = true;
|
||||
|
||||
|
||||
functions.resize = functions.move = functions.iconify = functions.maximize = functions.tabable = true;
|
||||
functions.resize = functions.move = functions.iconify = functions.maximize = functions.close = functions.tabable = true;
|
||||
decorations.close = false;
|
||||
|
||||
if (m_client->getBlackboxHint() != 0)
|
||||
|
|
15
src/Xutil.cc
15
src/Xutil.cc
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "FbTk/I18n.hh"
|
||||
#include "FbTk/App.hh"
|
||||
#include "FbTk/FbString.hh"
|
||||
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
@ -35,7 +36,7 @@ using namespace std;
|
|||
|
||||
namespace Xutil {
|
||||
|
||||
std::string getWMName(Window window) {
|
||||
FbTk::FbString getWMName(Window window) {
|
||||
|
||||
if (window == None)
|
||||
return "";
|
||||
|
@ -58,22 +59,22 @@ std::string getWMName(Window window) {
|
|||
if ((XmbTextPropertyToTextList(display, &text_prop,
|
||||
&list, &num) == Success) &&
|
||||
(num > 0) && *list) {
|
||||
name = static_cast<char *>(*list);
|
||||
name = FbTk::FbStringUtil::LocaleStrToFb(static_cast<char *>(*list));
|
||||
XFreeStringList(list);
|
||||
} else
|
||||
name = text_prop.value ? (char *)text_prop.value : "";
|
||||
name = text_prop.value ? FbTk::FbStringUtil::XStrToFb((char *)text_prop.value) : "";
|
||||
|
||||
} else
|
||||
name = text_prop.value ? (char *)text_prop.value : "";
|
||||
} else
|
||||
name = text_prop.value ? FbTk::FbStringUtil::XStrToFb((char *)text_prop.value) : "";
|
||||
|
||||
XFree(text_prop.value);
|
||||
|
||||
} else { // default name
|
||||
name = _FBTEXT(Window, Unnamed, "Unnamed", "Default name for a window without a WM_NAME");
|
||||
name = FbTk::FbStringUtil::LocaleStrToFb(_FBTEXT(Window, Unnamed, "Unnamed", "Default name for a window without a WM_NAME"));
|
||||
}
|
||||
} else {
|
||||
// default name
|
||||
name = _FBTEXT(Window, Unnamed, "Unnamed", "Default name for a window without a WM_NAME");
|
||||
name = FbTk::FbStringUtil::LocaleStrToFb(_FBTEXT(Window, Unnamed, "Unnamed", "Default name for a window without a WM_NAME"));
|
||||
}
|
||||
|
||||
return name;
|
||||
|
|
|
@ -26,12 +26,13 @@
|
|||
#define XUTIL_HH
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include "FbTk/FbString.hh"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Xutil {
|
||||
|
||||
std::string getWMName(Window window);
|
||||
FbTk::FbString getWMName(Window window);
|
||||
|
||||
std::string getWMClassName(Window win);
|
||||
std::string getWMClassClass(Window win);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "EventManager.hh"
|
||||
#include "GContext.hh"
|
||||
#include "Color.hh"
|
||||
#include "FbString.hh"
|
||||
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/keysym.h>
|
||||
|
@ -180,8 +181,10 @@ int main(int argc, char **argv) {
|
|||
cerr<<"Orientation not valid ("<<orient<<")"<<endl;
|
||||
orient = FbTk::ROT0;
|
||||
}
|
||||
// utf-8 it
|
||||
|
||||
cerr<<"Setting text: "<<text<<endl;
|
||||
app.setText(text, orient);
|
||||
app.setText(FbTk::FbStringUtil::XStrToFb(text), orient);
|
||||
|
||||
app.redraw();
|
||||
app.eventLoop();
|
||||
|
|
Loading…
Reference in a new issue