From 08d793bb796f608774d6fdefd1950df54477e2c6 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 3 Jul 2002 06:34:25 +0000 Subject: [PATCH] add BFont class, with Xft support --- configure.in | 42 ++++-- src/Basemenu.cc | 112 +++------------ src/Font.cc | 333 ++++++++++++++++++++++++++++++++++++++++++++ src/Font.hh | 117 ++++++++++++++++ src/Makefile.am | 34 +++-- src/Screen.cc | 358 ++++++------------------------------------------ src/Screen.hh | 30 ++-- src/Toolbar.cc | 146 +++++--------------- src/Util.hh | 12 +- src/Window.cc | 45 ++---- 10 files changed, 635 insertions(+), 594 deletions(-) create mode 100644 src/Font.cc create mode 100644 src/Font.hh diff --git a/configure.in b/configure.in index 1da34f1b..be260e6b 100644 --- a/configure.in +++ b/configure.in @@ -53,8 +53,6 @@ AC_CHECK_LIB(X11, XOpenDisplay, LIBS="$LIBS $X_EXTRA_LIBS" -Xext_lib="" - dnl Check for XShape extension support and proper library files. SHAPE="" AC_MSG_CHECKING([whether to build support for the XShape extension]) @@ -65,16 +63,16 @@ AC_ARG_ENABLE( if test x$enableval = "xyes"; then AC_MSG_RESULT([yes]) AC_CHECK_LIB(Xext, XShapeCombineShape, - AC_MSG_CHECKING([for X11/extensions/shape.h]) - AC_TRY_LINK( + AC_MSG_CHECKING([for X11/extensions/shape.h]) + AC_TRY_LINK( #include #include #include , long foo = ShapeSet, - AC_MSG_RESULT([yes]) - SHAPE="yes", - AC_MSG_RESULT([no]) - ) + AC_MSG_RESULT([yes]) + SHAPE="yes", + AC_MSG_RESULT([no]) + ) ) else AC_MSG_RESULT([no]) @@ -84,6 +82,34 @@ if test x$SHAPE = "xyes"; then AC_DEFINE(SHAPE,1,Enable support of the XShape extension) fi +dnl Check for Xft extension support and proper library files. +XFT="" +AC_MSG_CHECKING([whether to build support for the Xft extension]) +AC_ARG_ENABLE( + xft, [ --enable-xft enable support of the Xft extension [default=yes]]) + +: ${enableval="yes"} +if test x$enableval = "xyes"; then + AC_MSG_RESULT([yes]) + AC_CHECK_LIB(Xft, XftOpenFontName, + AC_MSG_CHECKING([for X11/Xft/Xft.h]) + AC_TRY_LINK( +#include +#include +, XftFont foo, + AC_MSG_RESULT([yes]) + XFT="yes", + AC_MSG_RESULT([no]) + ) + ) +else + AC_MSG_RESULT([no]) +fi +if test x$XFT = "xyes"; then + LIBS="$LIBS -lXft" + AC_DEFINE(XFT,1,Enable support of the Xft extension) +fi + dnl Check for the Slit SLIT="" AC_MSG_CHECKING([whether to include the Slit]) diff --git a/src/Basemenu.cc b/src/Basemenu.cc index 7358df3c..2dd6af70 100644 --- a/src/Basemenu.cc +++ b/src/Basemenu.cc @@ -46,6 +46,7 @@ using namespace std; #include "i18n.hh" #include "blackbox.hh" #include "Basemenu.hh" +#include "Font.hh" #include "GCCache.hh" #include "Image.hh" #include "Screen.hh" @@ -90,27 +91,15 @@ Basemenu::Basemenu(BScreen *scrn) { menu.bevel_w = screen->getBevelWidth(); - if (i18n.multibyte()) - menu.width = menu.title_h = menu.item_w = menu.frame_h = - screen->getMenuStyle()->t_fontset_extents->max_ink_extent.height + - (menu.bevel_w * 2); - else - menu.width = menu.title_h = menu.item_w = menu.frame_h = - screen->getMenuStyle()->t_font->ascent + - screen->getMenuStyle()->t_font->descent + (menu.bevel_w * 2); + MenuStyle *style = screen->getMenuStyle(); + menu.width = menu.title_h = menu.item_w = menu.frame_h = + style->t_font->height() + (menu.bevel_w * 2); menu.sublevels = menu.persub = menu.minsub = 0; - MenuStyle *style = screen->getMenuStyle(); - if (i18n.multibyte()) { - menu.item_h = style->f_fontset_extents->max_ink_extent.height + - (menu.bevel_w); - } else { - menu.item_h = style->f_font->ascent + style->f_font->descent + - (menu.bevel_w); - } + menu.item_h = style->f_font->height() + menu.bevel_w; menu.height = menu.title_h + screen->getBorderWidth() + menu.frame_h; @@ -265,31 +254,12 @@ int Basemenu::remove(int index) { void Basemenu::update(void) { MenuStyle *style = screen->getMenuStyle(); - if (i18n.multibyte()) { - menu.item_h = style->f_fontset_extents->max_ink_extent.height + - menu.bevel_w; - menu.title_h = style->t_fontset_extents->max_ink_extent.height + - (menu.bevel_w * 2); - } else { - menu.item_h = style->f_font->ascent + style->f_font->descent + - menu.bevel_w; - menu.title_h = style->t_font->ascent + style->t_font->descent + - (menu.bevel_w * 2); - } + menu.item_h = style->f_font->height() + menu.bevel_w; + menu.title_h = style->t_font->height() + menu.bevel_w * 2; if (title_vis) { - const char *s = getLabel(); - int l = strlen(s); - - if (i18n.multibyte()) { - XRectangle ink, logical; - XmbTextExtents(screen->getMenuStyle()->t_fontset, s, l, &ink, &logical); - menu.item_w = logical.width; - } else { - menu.item_w = XTextWidth(screen->getMenuStyle()->t_font, s, l); - } - - menu.item_w += (menu.bevel_w * 2); + menu.item_w = screen->getMenuStyle()->t_font->measureString(menu.label) + + menu.bevel_w * 2; } else { menu.item_w = 1; } @@ -297,18 +267,8 @@ void Basemenu::update(void) { unsigned int ii = 0; MenuItems::iterator it = menuitems.begin(), end = menuitems.end(); for (; it != end; ++it) { - BasemenuItem *tmp = *it; - const char *s = tmp->l.c_str(); - int l = strlen(s); - - if (i18n.multibyte()) { - XRectangle ink, logical; - XmbTextExtents(screen->getMenuStyle()->f_fontset, s, l, &ink, &logical); - ii = logical.width; - } else - ii = XTextWidth(screen->getMenuStyle()->f_font, s, l); - - ii += (menu.bevel_w * 2) + (menu.item_h * 2); + ii = screen->getMenuStyle()->f_font->measureString((*it)->l) + + (menu.bevel_w * 2) + (menu.item_h * 2); menu.item_w = ((menu.item_w < ii) ? ii : menu.item_w); } @@ -484,17 +444,9 @@ void Basemenu::redrawTitle(void) { i18n(BasemenuSet, BasemenuBlackboxMenu, "Blackbox Menu"); int dx = menu.bevel_w, len = strlen(text); unsigned int l; + MenuStyle *style = screen->getMenuStyle(); - if (i18n.multibyte()) { - XRectangle ink, logical; - XmbTextExtents(screen->getMenuStyle()->t_fontset, text, len, - &ink, &logical); - l = logical.width; - } else { - l = XTextWidth(screen->getMenuStyle()->t_font, text, len); - } - - l += (menu.bevel_w * 2); + l = style->t_font->measureString(text) + menu.bevel_w * 2; switch (screen->getMenuStyle()->t_justify) { case RightJustify: @@ -510,15 +462,8 @@ void Basemenu::redrawTitle(void) { break; } - MenuStyle *style = screen->getMenuStyle(); - BPen pen(style->t_text, style->t_font); - if (i18n.multibyte()) - XmbDrawString(display, menu.title, style->t_fontset, pen.gc(), dx, - (menu.bevel_w - style->t_fontset_extents->max_ink_extent.y), - text, len); - else - XDrawString(display, menu.title, pen.gc(), dx, - (style->t_font->ascent + menu.bevel_w), text, len); + style->t_font->drawString(menu.title, dx, menu.bevel_w, + style->t_text, text); } @@ -605,19 +550,8 @@ void Basemenu::drawItem(int index, bool highlight, bool clear, unsigned int half_w = menu.item_h / 2, quarter_w = menu.item_h / 4; if (text) { - if (i18n.multibyte()) { - XRectangle ink, logical; - XmbTextExtents(screen->getMenuStyle()->f_fontset, - text, len, &ink, &logical); - text_w = logical.width; - text_y = item_y + (menu.bevel_w / 2) - - screen->getMenuStyle()->f_fontset_extents->max_ink_extent.y; - } else { - text_w = XTextWidth(screen->getMenuStyle()->f_font, text, len); - text_y = item_y + - screen->getMenuStyle()->f_font->ascent + - (menu.bevel_w / 2); - } + text_w = screen->getMenuStyle()->f_font->measureString(text); + text_y = item_y + menu.bevel_w / 2; switch(screen->getMenuStyle()->f_justify) { case LeftJustify: @@ -638,8 +572,6 @@ void Basemenu::drawItem(int index, bool highlight, bool clear, MenuStyle *style = screen->getMenuStyle(); BPen pen((highlight || item->isSelected()) ? style->h_text : style->f_text), - textpen((highlight) ? style->h_text : - item->isEnabled() ? style->f_text : style->d_text, style->f_font), hipen(style->hilite.color()); @@ -696,11 +628,11 @@ void Basemenu::drawItem(int index, bool highlight, bool clear, } if (dotext && text) { - if (i18n.multibyte()) - XmbDrawString(display, menu.frame, screen->getMenuStyle()->f_fontset, - textpen.gc(), text_x, text_y, text, len); - else - XDrawString(display, menu.frame, textpen.gc(), text_x, text_y, text, len); + style->f_font->drawString(menu.frame, text_x, text_y, + (highlight ? style->h_text : + (item->isEnabled() ? style->f_text : + style->d_text)), + text); } if (dosel && item->submenu()) { diff --git a/src/Font.cc b/src/Font.cc new file mode 100644 index 00000000..f377c5eb --- /dev/null +++ b/src/Font.cc @@ -0,0 +1,333 @@ +// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- +// Font.cc for Blackbox - an X11 Window manager +// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry +// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif // HAVE_CONFIG_H + +extern "C" { +#ifdef HAVE_STDLIB_H +# include +#endif // HAVE_STDLIB_H +} + +#include +#include + +using std::string; +using std::cerr; +using std::endl; + +#include "i18n.hh" +#include "Font.hh" +#include "Util.hh" +#include "GCCache.hh" +#include "Color.hh" + +//bool BFont::_antialias = False; +string BFont::_fallback_font = "fixed"; + + +BFont::BFont(Display *d, BScreen *screen, const string &family, int size, + bool bold, bool italic) : _display(d), + _screen(screen), + _name(family), + _simplename(False), + _size(size * 10), + _bold(bold), + _italic(italic), +#ifdef XFT + _xftfont(0), +#endif // XFT + _font(0), + _fontset(0), + _fontset_extents(0), + _cache(0), + _item(0) { + _valid = init(); +} + + +BFont::BFont(Display *d, BScreen *screen, const string &xlfd) : + _display(d), + _screen(screen), +#ifdef XFT + _xftfont(0), +#endif // XFT + _font(0), + _fontset(0), + _fontset_extents(0), + _cache(0), + _item(0) { + string int_xlfd; + if (xlfd.empty()) + int_xlfd = _fallback_font; + else + int_xlfd = xlfd; + + _valid = init(xlfd); +} + + +bool BFont::init(const string &xlfd) { + // try load the specified font + if (xlfd.empty() || parseFontString(xlfd)) + if (createFont()) + return True; + + if (xlfd != _fallback_font) { + // try the fallback + cerr << "BFont::BFont(): couldn't load font '" << _name << "'" << endl << + "Falling back to default '" << _fallback_font << "'" << endl; + if (parseFontString(_fallback_font)) + if (createFont()) + return True; + } + + cerr << "BFont::BFont(): couldn't load font '" << _name << "'" << endl << + "Giving up!" << endl; + + return False; +} + + +bool BFont::createFont(void) { + std::string fullname; + +#ifdef XFT + fullname = buildXlfdName(False); + _xftfont = XftFontOpenXlfd(_display, _screen->getScreenNumber(), + fullname.c_str()); + if (_xftfont) + return True; + + cerr << "BFont::BFont(): couldn't load font '" << _name << "'" << endl << + "as an Xft font, trying as a standard X font." << endl; +#endif + + if (i18n.multibyte()) { + char **missing, *def = "-"; + int nmissing; + + fullname = buildXlfdName(True); + _fontset = XCreateFontSet(_display, fullname.c_str(), &missing, &nmissing, + &def); + if (nmissing) XFreeStringList(missing); + if (_fontset) + _fontset_extents = XExtentsOfFontSet(_fontset); + else + return False; + + assert(_fontset_extents); + } + + fullname = buildXlfdName(False); + cerr << "loading font '" << fullname.c_str() << "'\n"; + _font = XLoadQueryFont(_display, fullname.c_str()); + if (! _font) + return False; + return True; +} + + +BFont::~BFont() { +#ifdef XFT + if (_xftfont) + XftFontClose(_display, _xftfont); +#endif // XFT + + if (i18n.multibyte() && _fontset) + XFreeFontSet(_display, _fontset); + if (_font) + XFreeFont(_display, _font); + + if (_item) + _cache->release(_item); +} + + +/* + * Takes _name, _size, _bold, _italic, etc and builds them into a full XLFD. + */ +string BFont::buildXlfdName(bool mb) const { + string weight = _bold ? "bold" : "medium"; + string slant = _italic ? "i" : "r"; + string sizestr= _size ? itostring(_size) : "*"; + + if (mb) + return _name + ',' + + "-*-*-" + weight + "-" + slant + "-*-*-" + sizestr + + "-*-*-*-*-*-*-*" + ',' + + "-*-*-*-*-*-*-" + sizestr + "-*-*-*-*-*-*-*" + ',' + + "*"; + else if (_simplename) + return _name; + else + return "-*-" + _name + "-" + weight + "-" + slant + "-*-*-*-" + + sizestr + "-*-*-*-*-*-*"; +} + + +/* + * Takes a full X font name and parses it out so we know if we're bold, our + * size, etc. + */ +bool BFont::parseFontString(const string &xlfd) { + if (xlfd.empty() || xlfd[0] != '-') { + _name = xlfd; + _simplename = True; + _bold = False; + _italic = False; + _size = 0; + } else { + _simplename = False; + string weight, + slant, + sizestr; + int i = 0; + + string::const_iterator it = xlfd.begin(), end = xlfd.end(); + while(1) { + string::const_iterator tmp = it; // current string.begin() + it = std::find(tmp, end, '-'); // look for comma between tmp and end + if (i == 2) _name = string(tmp, it); // s[tmp:it] + if (i == 3) weight = string(tmp, it); + if (i == 4) slant = string(tmp, it); + if (i == 8) sizestr = string(tmp, it); + if (it == end || i >= 8) + break; + ++it; + ++i; + } + if (i < 3) // no name even! can't parse that + return False; + _bold = weight == "bold" || weight == "demibold"; + _italic = slant == "i" || slant == "o"; + if (atoi(sizestr.c_str())) + _size = atoi(sizestr.c_str()); + } + + // min/max size restrictions for sanity, but 0 is the font's "default size" + if (_size && _size < 30) + _size = 30; + else if (_size > 970) + _size = 970; + + return True; +} + + +void BFont::drawString(Drawable d, int x, int y, const BColor &color, + const string &string) const { + assert(_valid); + +#ifdef XFT + if (_xftfont) { + XftDraw *draw = XftDrawCreate(_display, d, _screen->getVisual(), + _screen->getColormap()); + assert(draw); + + XftColor c; + c.color.red = color.red() | color.red() << 8; + c.color.green = color.green() | color.green() << 8; + c.color.blue = color.blue() | color.blue() << 8; + c.color.alpha = 0xff | 0xff << 8; // no transparency in BColor yet + c.pixel = color.pixel(); + + XftDrawStringUtf8(draw, &c, _xftfont, x, _xftfont->ascent + y, + (XftChar8 *) string.c_str(), string.size()); + + XftDrawDestroy(draw); + return; + } +#endif // XFT + + if (! _cache) + _cache = color.display()->gcCache(); + if (! _item) + _item = _cache->find(color, _font, GXcopy, ClipByChildren); + + assert(_cache); + assert(_item); + + if (i18n.multibyte()) + XmbDrawString(_display, d, _fontset, _item->gc(), + x, y - _fontset_extents->max_ink_extent.y, + string.c_str(), string.size()); + else + XDrawString(_display, d, _item->gc(), + x, _font->ascent + y, + string.c_str(), string.size()); +} + + +unsigned int BFont::measureString(const string &string) const { + assert(_valid); + +#ifdef XFT + if (_xftfont) { + XGlyphInfo info; + XftTextExtentsUtf8(_display, _xftfont, (XftChar8 *) string.c_str(), + string.size(), &info); + return info.xOff; + } +#endif // XFT + + if (i18n.multibyte()) { + XRectangle ink, logical; + XmbTextExtents(_fontset, string.c_str(), string.size(), &ink, &logical); + return logical.width; + } else { + return XTextWidth(_font, string.c_str(), string.size()); + } +} + + +unsigned int BFont::height(void) const { + assert(_valid); + +#ifdef XFT + if (_xftfont) + return _xftfont->height; +#endif // XFT + + if (i18n.multibyte()) + return _fontset_extents->max_ink_extent.height; + else + return _font->ascent + _font->descent; +} + + +unsigned int BFont::maxCharWidth(void) const { + assert(_valid); + +#ifdef XFT + if (_xftfont) + return _xftfont->max_advance_width; +#endif // XFT + + if (i18n.multibyte()) + return _fontset_extents->max_logical_extent.width; + else + return _font->max_bounds.rbearing - _font->min_bounds.lbearing; +} diff --git a/src/Font.hh b/src/Font.hh new file mode 100644 index 00000000..38c4b4f8 --- /dev/null +++ b/src/Font.hh @@ -0,0 +1,117 @@ +// -*- mode: C++; indent-tabs-mode: nil; -*- +// Font.hh for Blackbox - an X11 Window manager +// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry +// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#ifndef __Font_hh +#define __Font_hh + +extern "C" { +#include + +#ifdef XFT +# include +#endif +} + +#include + +#include + +class BGCCache; +class BGCCacheItem; +class BColor; + +#include "Screen.hh" + +class BFont { + /* + * static members + */ +private: +// static bool _antialias; + static std::string _fallback_font; + +public: +// inline static bool antialias(void) { return _antialias; } +// inline static void setAntialias(bool a) { _antialias = a; } + + inline static std::string fallbackFont(void) { return _fallback_font; } + inline static void setFallbackFont(const std::string &f) + { _fallback_font = f; } + + /* + * instance members + */ +private: + Display *_display; + BScreen *_screen; + + std::string _name; + bool _simplename; // true if not spec'd as a -*-* string + int _size; + bool _bold; + bool _italic; + +#ifdef XFT + XftFont *_xftfont; +#endif + + // standard + XFontStruct *_font; + // multibyte + XFontSet _fontset; + XFontSetExtents *_fontset_extents; + + std::string buildXlfdName(bool mb) const; + + bool init(const std::string &xlfd = ""); + bool createFont(void); + bool parseFontString(const std::string &xlfd); + + mutable BGCCache *_cache; + mutable BGCCacheItem *_item; + + bool _valid; + +public: + BFont(Display *d, BScreen *screen, const std::string &family, int size, + bool bold, bool italic); + BFont(Display *d, BScreen *screen, const std::string &xlfd); + virtual ~BFont(); + + inline bool valid(void) const { return _valid; } + + inline std::string name(void) const { assert(_valid); return _name; } + inline int size(void) const { assert(_valid); return _size / 10; } + inline bool bold(void) const { assert(_valid); return _bold; } + inline bool italic(void) const { assert(_valid); return _italic; } + + unsigned int height(void) const; + unsigned int maxCharWidth(void) const; + + unsigned int measureString(const std::string &string) const; + + void drawString(Drawable d, int x, int y, const BColor &color, + const std::string &string) const; +}; + +#endif // __Font_hh diff --git a/src/Makefile.am b/src/Makefile.am index d2ed4185..ac6a8908 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,7 +29,7 @@ CPPFLAGS=@CPPFLAGS@ @DEBUG@ \ bin_PROGRAMS= openbox -openbox_SOURCES= BaseDisplay.cc Basemenu.cc Clientmenu.cc Color.cc Configmenu.cc Configuration.cc GCCache.cc Iconmenu.cc Image.cc ImageControl.cc Netizen.cc Rootmenu.cc Screen.cc Slit.cc Texture.cc Timer.cc Toolbar.cc Util.cc Window.cc Windowmenu.cc Workspace.cc Workspacemenu.cc XAtom.cc blackbox.cc i18n.cc main.cc +openbox_SOURCES= BaseDisplay.cc Basemenu.cc Clientmenu.cc Color.cc Configmenu.cc Configuration.cc Font.cc GCCache.cc Iconmenu.cc Image.cc ImageControl.cc Netizen.cc Rootmenu.cc Screen.cc Slit.cc Texture.cc Timer.cc Toolbar.cc Util.cc Window.cc Windowmenu.cc Workspace.cc Workspacemenu.cc XAtom.cc blackbox.cc i18n.cc main.cc MAINTAINERCLEANFILES= Makefile.in @@ -42,8 +42,9 @@ BaseDisplay.o: BaseDisplay.cc i18n.hh ../nls/blackbox-nls.hh \ BaseDisplay.hh Timer.hh Util.hh GCCache.hh Color.hh Basemenu.o: Basemenu.cc i18n.hh ../nls/blackbox-nls.hh blackbox.hh \ BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh Basemenu.hh \ - GCCache.hh Color.hh Image.hh Screen.hh Texture.hh Configmenu.hh \ - Iconmenu.hh Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh + Font.hh Screen.hh Color.hh Texture.hh Image.hh Configmenu.hh \ + Iconmenu.hh Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh \ + GCCache.hh Clientmenu.o: Clientmenu.cc blackbox.hh i18n.hh ../nls/blackbox-nls.hh \ BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh \ Clientmenu.hh Basemenu.hh Screen.hh Color.hh Texture.hh Image.hh \ @@ -56,6 +57,11 @@ Configmenu.o: Configmenu.cc i18n.hh ../nls/blackbox-nls.hh \ Rootmenu.hh Workspace.hh Workspacemenu.hh blackbox.hh \ Configuration.hh XAtom.hh Window.hh Windowmenu.hh Configuration.o: Configuration.cc ../config.h Configuration.hh Util.hh +Font.o: Font.cc i18n.hh ../nls/blackbox-nls.hh Font.hh Screen.hh \ + Color.hh Texture.hh Util.hh Image.hh Timer.hh BaseDisplay.hh \ + Configmenu.hh Basemenu.hh Iconmenu.hh Netizen.hh Rootmenu.hh \ + Workspace.hh Workspacemenu.hh blackbox.hh Configuration.hh XAtom.hh \ + GCCache.hh GCCache.o: GCCache.cc GCCache.hh BaseDisplay.hh Timer.hh Util.hh \ Color.hh Iconmenu.o: Iconmenu.cc i18n.hh ../nls/blackbox-nls.hh Iconmenu.hh \ @@ -79,9 +85,9 @@ Rootmenu.o: Rootmenu.cc blackbox.hh i18n.hh ../nls/blackbox-nls.hh \ Iconmenu.hh Netizen.hh Workspace.hh Workspacemenu.hh Screen.o: Screen.cc ../config.h i18n.hh ../nls/blackbox-nls.hh \ blackbox.hh BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh \ - Clientmenu.hh Basemenu.hh GCCache.hh Color.hh Iconmenu.hh Image.hh \ - Screen.hh Texture.hh Configmenu.hh Netizen.hh Rootmenu.hh \ - Workspace.hh Workspacemenu.hh Slit.hh Toolbar.hh Window.hh \ + Clientmenu.hh Basemenu.hh Font.hh Screen.hh Color.hh Texture.hh \ + Image.hh Configmenu.hh Iconmenu.hh Netizen.hh Rootmenu.hh \ + Workspace.hh Workspacemenu.hh GCCache.hh Slit.hh Toolbar.hh Window.hh \ Windowmenu.hh Slit.o: Slit.cc i18n.hh ../nls/blackbox-nls.hh blackbox.hh \ BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh Image.hh \ @@ -95,16 +101,16 @@ Texture.o: Texture.cc Texture.hh Color.hh Util.hh BaseDisplay.hh \ Timer.o: Timer.cc BaseDisplay.hh Timer.hh Util.hh Toolbar.o: Toolbar.cc i18n.hh ../nls/blackbox-nls.hh blackbox.hh \ BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh \ - Clientmenu.hh Basemenu.hh GCCache.hh Color.hh Iconmenu.hh Image.hh \ - Rootmenu.hh Screen.hh Texture.hh Configmenu.hh Netizen.hh \ - Workspace.hh Workspacemenu.hh Toolbar.hh Window.hh Windowmenu.hh \ - Slit.hh + Clientmenu.hh Basemenu.hh Font.hh Screen.hh Color.hh Texture.hh \ + Image.hh Configmenu.hh Iconmenu.hh Netizen.hh Rootmenu.hh \ + Workspace.hh Workspacemenu.hh GCCache.hh Toolbar.hh Window.hh \ + Windowmenu.hh Slit.hh Util.o: Util.cc Util.hh Window.o: Window.cc i18n.hh ../nls/blackbox-nls.hh blackbox.hh \ - BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh GCCache.hh \ - Color.hh Iconmenu.hh Basemenu.hh Image.hh Screen.hh Texture.hh \ - Configmenu.hh Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh \ - Toolbar.hh Window.hh Windowmenu.hh Slit.hh + BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh Font.hh \ + Screen.hh Color.hh Texture.hh Image.hh Configmenu.hh Basemenu.hh \ + Iconmenu.hh Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh \ + GCCache.hh Toolbar.hh Window.hh Windowmenu.hh Slit.hh Windowmenu.o: Windowmenu.cc i18n.hh ../nls/blackbox-nls.hh blackbox.hh \ BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh Screen.hh \ Color.hh Texture.hh Image.hh Configmenu.hh Basemenu.hh Iconmenu.hh \ diff --git a/src/Screen.cc b/src/Screen.cc index dac5d6f8..a05c2386 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -27,11 +27,6 @@ extern "C" { #include #include -// for strcasestr() -#ifndef _GNU_SOURCE -# define _GNU_SOURCE -#endif // _GNU_SOURCE - #ifdef HAVE_STDLIB_H # include #endif // HAVE_STDLIB_H @@ -76,6 +71,7 @@ using std::string; #include "i18n.hh" #include "blackbox.hh" #include "Clientmenu.hh" +#include "Font.hh" #include "GCCache.hh" #include "Iconmenu.hh" #include "Image.hh" @@ -133,10 +129,8 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) { rootmenu = 0; - resource.mstyle.t_fontset = resource.mstyle.f_fontset = - resource.tstyle.fontset = resource.wstyle.fontset = (XFontSet) 0; resource.mstyle.t_font = resource.mstyle.f_font = resource.tstyle.font = - resource.wstyle.font = (XFontStruct *) 0; + resource.wstyle.font = (BFont *) 0; xatom->setSupported(this); // set-up netwm support #ifdef HAVE_GETPID @@ -168,9 +162,6 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) { LoadStyle(); XGCValues gcv; - unsigned long gc_value_mask = GCForeground; - if (! i18n.multibyte()) gc_value_mask |= GCFont; - gcv.foreground = WhitePixel(blackbox->getXDisplay(), getScreenNumber()) ^ BlackPixel(blackbox->getXDisplay(), getScreenNumber()); gcv.function = GXxor; @@ -180,23 +171,8 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) { const char *s = i18n(ScreenSet, ScreenPositionLength, "0: 0000 x 0: 0000"); - int l = strlen(s); - - if (i18n.multibyte()) { - XRectangle ink, logical; - XmbTextExtents(resource.wstyle.fontset, s, l, &ink, &logical); - geom_w = logical.width; - - geom_h = resource.wstyle.fontset_extents->max_ink_extent.height; - } else { - geom_h = resource.wstyle.font->ascent + - resource.wstyle.font->descent; - - geom_w = XTextWidth(resource.wstyle.font, s, l); - } - - geom_w += (resource.bevel_width * 2); - geom_h += (resource.bevel_width * 2); + geom_w = resource.wstyle.font->measureString(s) + resource.bevel_width * 2; + geom_h = resource.wstyle.font->height() + resource.bevel_width * 2; XSetWindowAttributes attrib; unsigned long mask = CWBorderPixel | CWColormap | CWSaveUnder; @@ -340,23 +316,14 @@ BScreen::~BScreen(void) { delete toolbar; delete image_control; - if (resource.wstyle.fontset) - XFreeFontSet(blackbox->getXDisplay(), resource.wstyle.fontset); - if (resource.mstyle.t_fontset) - XFreeFontSet(blackbox->getXDisplay(), resource.mstyle.t_fontset); - if (resource.mstyle.f_fontset) - XFreeFontSet(blackbox->getXDisplay(), resource.mstyle.f_fontset); - if (resource.tstyle.fontset) - XFreeFontSet(blackbox->getXDisplay(), resource.tstyle.fontset); - if (resource.wstyle.font) - XFreeFont(blackbox->getXDisplay(), resource.wstyle.font); + delete resource.wstyle.font; if (resource.mstyle.t_font) - XFreeFont(blackbox->getXDisplay(), resource.mstyle.t_font); + delete resource.mstyle.t_font; if (resource.mstyle.f_font) - XFreeFont(blackbox->getXDisplay(), resource.mstyle.f_font); + delete resource.mstyle.f_font; if (resource.tstyle.font) - XFreeFont(blackbox->getXDisplay(), resource.tstyle.font); + delete resource.tstyle.font; XFreeGC(blackbox->getXDisplay(), opGC); } @@ -669,9 +636,6 @@ void BScreen::reconfigure(void) { LoadStyle(); XGCValues gcv; - unsigned long gc_value_mask = GCForeground; - if (! i18n.multibyte()) gc_value_mask |= GCFont; - gcv.foreground = WhitePixel(blackbox->getXDisplay(), getScreenNumber()); gcv.function = GXinvert; @@ -681,22 +645,9 @@ void BScreen::reconfigure(void) { const char *s = i18n(ScreenSet, ScreenPositionLength, "0: 0000 x 0: 0000"); - int l = strlen(s); - - if (i18n.multibyte()) { - XRectangle ink, logical; - XmbTextExtents(resource.wstyle.fontset, s, l, &ink, &logical); - geom_w = logical.width; - - geom_h = resource.wstyle.fontset_extents->max_ink_extent.height; - } else { - geom_w = XTextWidth(resource.wstyle.font, s, l); - - geom_h = resource.wstyle.font->ascent + resource.wstyle.font->descent; - } - geom_w += (resource.bevel_width * 2); - geom_h += (resource.bevel_width * 2); + geom_w = resource.wstyle.font->measureString(s) + resource.bevel_width * 2; + geom_h = resource.wstyle.font->height() + resource.bevel_width * 2; BTexture* texture = &(resource.wstyle.l_focus); geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap); @@ -789,51 +740,21 @@ void BScreen::LoadStyle(void) { string s; // load fonts/fontsets - if (resource.wstyle.fontset) - XFreeFontSet(blackbox->getXDisplay(), resource.wstyle.fontset); - if (resource.tstyle.fontset) - XFreeFontSet(blackbox->getXDisplay(), resource.tstyle.fontset); - if (resource.mstyle.f_fontset) - XFreeFontSet(blackbox->getXDisplay(), resource.mstyle.f_fontset); - if (resource.mstyle.t_fontset) - XFreeFontSet(blackbox->getXDisplay(), resource.mstyle.t_fontset); - resource.wstyle.fontset = 0; - resource.tstyle.fontset = 0; - resource.mstyle.f_fontset = 0; - resource.mstyle.t_fontset = 0; if (resource.wstyle.font) - XFreeFont(blackbox->getXDisplay(), resource.wstyle.font); + delete resource.wstyle.font; if (resource.tstyle.font) - XFreeFont(blackbox->getXDisplay(), resource.tstyle.font); + delete resource.tstyle.font; if (resource.mstyle.f_font) - XFreeFont(blackbox->getXDisplay(), resource.mstyle.f_font); + delete resource.mstyle.f_font; if (resource.mstyle.t_font) - XFreeFont(blackbox->getXDisplay(), resource.mstyle.t_font); - resource.wstyle.font = 0; - resource.tstyle.font = 0; - resource.mstyle.f_font = 0; - resource.mstyle.t_font = 0; - - if (i18n.multibyte()) { - resource.wstyle.fontset = readDatabaseFontSet("window.font", style); - resource.tstyle.fontset = readDatabaseFontSet("toolbar.font", style); - resource.mstyle.t_fontset = readDatabaseFontSet("menu.title.font", style); - resource.mstyle.f_fontset = readDatabaseFontSet("menu.frame.font", style); - - resource.mstyle.t_fontset_extents = - XExtentsOfFontSet(resource.mstyle.t_fontset); - resource.mstyle.f_fontset_extents = - XExtentsOfFontSet(resource.mstyle.f_fontset); - resource.tstyle.fontset_extents = - XExtentsOfFontSet(resource.tstyle.fontset); - resource.wstyle.fontset_extents = - XExtentsOfFontSet(resource.wstyle.fontset); - } else { - resource.wstyle.font = readDatabaseFont("window.font", style); - resource.tstyle.font = readDatabaseFont("toolbar.font", style); - resource.mstyle.t_font = readDatabaseFont("menu.title.font", style); - resource.mstyle.f_font = readDatabaseFont("menu.frame.font", style); - } + delete resource.mstyle.t_font; + resource.wstyle.font = resource.tstyle.font = resource.mstyle.f_font = + resource.mstyle.t_font = (BFont *) 0; + + resource.wstyle.font = readDatabaseFont("window.font", style); + resource.tstyle.font = readDatabaseFont("toolbar.font", style); + resource.mstyle.t_font = readDatabaseFont("menu.title.font", style); + resource.mstyle.f_font = readDatabaseFont("menu.frame.font", style); // load window config resource.wstyle.t_focus = @@ -1981,19 +1902,10 @@ void BScreen::showPosition(int x, int y) { XClearWindow(blackbox->getXDisplay(), geom_window); - BPen pen(resource.wstyle.l_text_focus, resource.wstyle.font); - if (i18n.multibyte()) { - XmbDrawString(blackbox->getXDisplay(), geom_window, - resource.wstyle.fontset, pen.gc(), - resource.bevel_width, resource.bevel_width - - resource.wstyle.fontset_extents->max_ink_extent.y, - label, strlen(label)); - } else { - XDrawString(blackbox->getXDisplay(), geom_window, - pen.gc(), resource.bevel_width, - resource.wstyle.font->ascent + resource.bevel_width, - label, strlen(label)); - } + resource.wstyle.font->drawString(geom_window, + resource.bevel_width, resource.bevel_width, + resource.wstyle.l_text_focus, + label); } @@ -2015,19 +1927,10 @@ void BScreen::showGeometry(unsigned int gx, unsigned int gy) { XClearWindow(blackbox->getXDisplay(), geom_window); - BPen pen(resource.wstyle.l_text_focus, resource.wstyle.font); - if (i18n.multibyte()) { - XmbDrawString(blackbox->getXDisplay(), geom_window, - resource.wstyle.fontset, pen.gc(), - resource.bevel_width, resource.bevel_width - - resource.wstyle.fontset_extents->max_ink_extent.y, - label, strlen(label)); - } else { - XDrawString(blackbox->getXDisplay(), geom_window, - pen.gc(), resource.bevel_width, - resource.wstyle.font->ascent + - resource.bevel_width, label, strlen(label)); - } + resource.wstyle.font->drawString(geom_window, + resource.bevel_width, resource.bevel_width, + resource.wstyle.l_text_focus, + label); } @@ -2190,7 +2093,7 @@ void BScreen::updateFocusModel() BTexture BScreen::readDatabaseTexture(const string &rname, const string &default_color, - Configuration &style) { + const Configuration &style) { BTexture texture; string s; @@ -2220,8 +2123,8 @@ BTexture BScreen::readDatabaseTexture(const string &rname, BColor BScreen::readDatabaseColor(const string &rname, - const string &default_color, - Configuration &style) { + const string &default_color, + const Configuration &style) { BColor color; string s; if (style.getValue(rname, s)) @@ -2232,195 +2135,16 @@ BColor BScreen::readDatabaseColor(const string &rname, } -XFontSet BScreen::readDatabaseFontSet(const string &rname, - Configuration &style) { - char *defaultFont = "fixed"; +BFont *BScreen::readDatabaseFont(const string &rname, + const Configuration &style) { + string fontname; - bool load_default = True; string s; - XFontSet fontset = 0; - if (style.getValue(rname, s) && (fontset = createFontSet(s))) - load_default = False; - - if (load_default) { - fontset = createFontSet(defaultFont); - - if (! fontset) { - fprintf(stderr, - i18n(ScreenSet, ScreenDefaultFontLoadFail, - "BScreen::setCurrentStyle(): couldn't load default font.\n")); - exit(2); - } - } - - return fontset; -} - - -XFontStruct *BScreen::readDatabaseFont(const string &rname, - Configuration &style) { - char *defaultFont = "fixed"; - - bool load_default = False; - string s; - XFontStruct *font = 0; - if (style.getValue(rname, s)) { - if ((font = XLoadQueryFont(blackbox->getXDisplay(), s.c_str())) == NULL) { - fprintf(stderr, - i18n(ScreenSet, ScreenFontLoadFail, - "BScreen::setCurrentStyle(): couldn't load font '%s'\n"), - s.c_str()); - - load_default = True; - } - } else { - load_default = True; - } - - if (load_default) { - font = XLoadQueryFont(blackbox->getXDisplay(), defaultFont); - if (font == NULL) { - fprintf(stderr, - i18n(ScreenSet, ScreenDefaultFontLoadFail, - "BScreen::setCurrentStyle(): couldn't load default font.\n")); - exit(2); - } - } - - return font; -} - - -#ifndef HAVE_STRCASESTR -static const char * strcasestr(const char *str, const char *ptn) { - const char *s2, *p2; - for(; *str; str++) { - for(s2=str,p2=ptn; ; s2++,p2++) { - if (! *p2) return str; - if (toupper(*s2) != toupper(*p2)) break; - } - } - return NULL; -} -#endif // HAVE_STRCASESTR - - -static const char *getFontElement(const char *pattern, char *buf, - int bufsiz, ...) { - const char *p, *v; - char *p2; - va_list va; - - va_start(va, bufsiz); - buf[bufsiz-1] = 0; - buf[bufsiz-2] = '*'; - while((v = va_arg(va, char *)) != NULL) { - p = strcasestr(pattern, v); - if (p) { - strncpy(buf, p+1, bufsiz-2); - p2 = strchr(buf, '-'); - if (p2) *p2=0; - va_end(va); - return p; - } - } - va_end(va); - strncpy(buf, "*", bufsiz); - return NULL; -} - - -static const char *getFontSize(const char *pattern, int *size) { - const char *p; - const char *p2=NULL; - int n=0; - - for (p=pattern; 1; p++) { - if (! *p) { - if (p2!=NULL && n>1 && n<72) { - *size = n; return p2+1; - } else { - *size = 16; return NULL; - } - } else if (*p=='-') { - if (n>1 && n<72 && p2!=NULL) { - *size = n; - return p2+1; - } - p2=p; n=0; - } else if (*p>='0' && *p<='9' && p2!=NULL) { - n *= 10; - n += *p-'0'; - } else { - p2=NULL; n=0; - } - } -} - - -XFontSet BScreen::createFontSet(const string &fontname) { - XFontSet fs; - char **missing, *def = "-"; - int nmissing, pixel_size = 0, buf_size = 0; - char weight[FONT_ELEMENT_SIZE], slant[FONT_ELEMENT_SIZE]; - - fs = XCreateFontSet(blackbox->getXDisplay(), - fontname.c_str(), &missing, &nmissing, &def); - if (fs && (! nmissing)) - return fs; - - const char *nfontname = fontname.c_str(); -#ifdef HAVE_SETLOCALE - if (! fs) { - if (nmissing) XFreeStringList(missing); - - setlocale(LC_CTYPE, "C"); - fs = XCreateFontSet(blackbox->getXDisplay(), fontname.c_str(), - &missing, &nmissing, &def); - setlocale(LC_CTYPE, ""); - } -#endif // HAVE_SETLOCALE - - if (fs) { - XFontStruct **fontstructs; - char **fontnames; - XFontsOfFontSet(fs, &fontstructs, &fontnames); - nfontname = fontnames[0]; - } + style.getValue(rname, s); // if this fails, a blank string will be used, + // which will cause the fallback font to load. - getFontElement(nfontname, weight, FONT_ELEMENT_SIZE, - "-medium-", "-bold-", "-demibold-", "-regular-", NULL); - getFontElement(nfontname, slant, FONT_ELEMENT_SIZE, - "-r-", "-i-", "-o-", "-ri-", "-ro-", NULL); - getFontSize(nfontname, &pixel_size); - - if (! strcmp(weight, "*")) - strncpy(weight, "medium", FONT_ELEMENT_SIZE); - if (! strcmp(slant, "*")) - strncpy(slant, "r", FONT_ELEMENT_SIZE); - if (pixel_size < 3) - pixel_size = 3; - else if (pixel_size > 97) - pixel_size = 97; - - buf_size = strlen(nfontname) + (FONT_ELEMENT_SIZE * 2) + 64; - char *pattern2 = new char[buf_size]; - sprintf(pattern2, - "%s," - "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*," - "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*,*", - nfontname, weight, slant, pixel_size, pixel_size); - nfontname = pattern2; - - if (nmissing) - XFreeStringList(missing); - if (fs) - XFreeFontSet(blackbox->getXDisplay(), fs); - - fs = XCreateFontSet(blackbox->getXDisplay(), nfontname, &missing, - &nmissing, &def); - - delete [] pattern2; - - return fs; + BFont *b = new BFont(blackbox->getXDisplay(), this, s); + if (! b->valid()) + exit(2); // can't continue without a font + return b; } diff --git a/src/Screen.hh b/src/Screen.hh index 72e7dc0a..0fabe9a4 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -54,7 +54,9 @@ extern "C" { #include "Workspace.hh" #include "Workspacemenu.hh" #include "blackbox.hh" + class Slit; // forward reference +class BFont; class XAtom; enum TextJustify { LeftJustify = 1, RightJustify, CenterJustify }; @@ -65,37 +67,31 @@ struct WindowStyle { BTexture t_focus, t_unfocus, l_focus, l_unfocus, h_focus, h_unfocus, b_focus, b_unfocus, b_pressed, g_focus, g_unfocus; - XFontSet fontset; - XFontSetExtents *fontset_extents; - XFontStruct *font; + BFont *font; TextJustify justify; - int doJustify(const char *text, int &start_pos, unsigned int max_length, - unsigned int modifier, bool multibyte) const; + int doJustify(const std::string &text, int &start_pos, + unsigned int max_length, unsigned int modifier) const; }; struct ToolbarStyle { BColor l_text, w_text, c_text, b_pic; BTexture toolbar, label, window, button, pressed, clock; - XFontSet fontset; - XFontSetExtents *fontset_extents; - XFontStruct *font; + BFont *font; TextJustify justify; - int doJustify(const char *text, int &start_pos, unsigned int max_length, - unsigned int modifier, bool multibyte) const; + int doJustify(const std::string &text, int &start_pos, + unsigned int max_length, unsigned int modifier) const; }; struct MenuStyle { BColor t_text, f_text, h_text, d_text; BTexture title, frame, hilite; - XFontSet t_fontset, f_fontset; - XFontSetExtents *t_fontset_extents, *f_fontset_extents; - XFontStruct *t_font, *f_font; + BFont *t_font, *f_font; TextJustify t_justify, f_justify; int bullet, bullet_pos; @@ -180,13 +176,11 @@ private: BTexture readDatabaseTexture(const std::string &rname, const std::string &default_color, - Configuration &style); + const Configuration &style); BColor readDatabaseColor(const std::string &rname, const std::string &default_color, - Configuration &style); - XFontSet readDatabaseFontSet(const std::string &rname, Configuration &style); - XFontStruct *readDatabaseFont(const std::string &rname, Configuration &style); - XFontSet createFontSet(const std::string &fontname); + const Configuration &style); + BFont *readDatabaseFont(const std::string &rname, const Configuration &style); void InitMenu(void); void LoadStyle(void); diff --git a/src/Toolbar.cc b/src/Toolbar.cc index 55beb59d..0018e43f 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -54,6 +54,7 @@ using std::string; #include "i18n.hh" #include "blackbox.hh" #include "Clientmenu.hh" +#include "Font.hh" #include "GCCache.hh" #include "Iconmenu.hh" #include "Image.hh" @@ -289,14 +290,10 @@ void Toolbar::load_rc(void) { void Toolbar::reconfigure(void) { - unsigned int height = 0, - width = (screen->getWidth() * width_percent) / 100; - - if (i18n.multibyte()) - height = screen->getToolbarStyle()->fontset_extents->max_ink_extent.height; - else - height = screen->getToolbarStyle()->font->ascent + - screen->getToolbarStyle()->font->descent; + unsigned int width, height; + + width = (screen->getWidth() * width_percent) / 100; + height = screen->getToolbarStyle()->font->height(); frame.bevel_w = screen->getBevelWidth(); frame.button_w = height; @@ -362,47 +359,26 @@ void Toolbar::reconfigure(void) { int len = strftime(t, 1024, screen->getStrftimeFormat(), tt); if (len == 0) { // invalid time format found screen->saveStrftimeFormat("%I:%M %p"); // so use the default - len = strftime(t, 1024, screen->getStrftimeFormat(), tt); + strftime(t, 1024, screen->getStrftimeFormat(), tt); } // find the length of the rendered string and add room for two extra // characters to it. This allows for variable width output of the fonts - if (i18n.multibyte()) { - XRectangle ink, logical; - XmbTextExtents(screen->getToolbarStyle()->fontset, t, len, - &ink, &logical); - XFontSetExtents* extents = screen->getToolbarStyle()->fontset_extents; - frame.clock_w = logical.width + - (extents->max_logical_extent.width * 2); - } else { - XFontStruct* font = screen->getToolbarStyle()->font; - frame.clock_w = XTextWidth(font, t, len) + - ((font->max_bounds.rbearing - font->min_bounds.lbearing) * 2); - } + BFont *font = screen->getToolbarStyle()->font; + frame.clock_w = font->measureString(t) + font->maxCharWidth() * 2; } } #else // !HAVE_STRFTIME - frame.clock_w = - XTextWidth(screen->getToolbarStyle()->font, - i18n(ToolbarSet, ToolbarNoStrftimeLength, "00:00000"), - strlen(i18n(ToolbarSet, ToolbarNoStrftimeLength, - "00:00000"))); + { + string s = i18n(ToolbarSet, ToolbarNoStrftimeLength, "00:00000"); + frame.clock_w = screen->getToolbarStyle()->font->measureString(s); + } #endif // HAVE_STRFTIME frame.workspace_label_w = 0; for (unsigned int i = 0; i < screen->getWorkspaceCount(); i++) { const string& workspace_name = screen->getWorkspace(i)->getName(); - if (i18n.multibyte()) { - XRectangle ink, logical; - XmbTextExtents(screen->getToolbarStyle()->fontset, - workspace_name.c_str(), workspace_name.length(), - &ink, &logical); - width = logical.width; - } else { - width = XTextWidth(screen->getToolbarStyle()->font, - workspace_name.c_str(), workspace_name.length()); - } - + width = screen->getToolbarStyle()->font->measureString(workspace_name); if (width > frame.workspace_label_w) frame.workspace_label_w = width; } @@ -604,17 +580,9 @@ void Toolbar::checkClock(bool redraw, bool date) { ToolbarStyle *style = screen->getToolbarStyle(); - int pos = frame.bevel_w * 2, // this is modified by doJustify() - dlen = style->doJustify(t, pos, frame.clock_w, - frame.bevel_w * 4, i18n.multibyte()); - BPen pen(style->c_text, style->font); - if (i18n.multibyte()) - XmbDrawString(display, frame.clock, style->fontset, pen.gc(), - pos, (1 - style->fontset_extents->max_ink_extent.y), - t, dlen); - else - XDrawString(display, frame.clock, pen.gc(), pos, - (style->font->ascent + 1), t, dlen); + int pos = frame.bevel_w * 2; // this is modified by doJustify() + style->doJustify(t, pos, frame.clock_w, frame.bevel_w * 4); + style->font->drawString(frame.clock, pos, 1, style->c_text, t); } } @@ -634,17 +602,9 @@ void Toolbar::redrawWindowLabel(bool redraw) { const char *title = foc->getTitle(); ToolbarStyle *style = screen->getToolbarStyle(); - int pos = frame.bevel_w * 2, // modified by doJustify() - dlen = style->doJustify(title, pos, frame.window_label_w, - frame.bevel_w * 4, i18n.multibyte()); - BPen pen(style->w_text, style->font); - if (i18n.multibyte()) - XmbDrawString(display, frame.window_label, style->fontset, pen.gc(), pos, - (1 - style->fontset_extents->max_ink_extent.y), - title, dlen); - else - XDrawString(display, frame.window_label, pen.gc(), pos, - (style->font->ascent + 1), title, dlen); + int pos = frame.bevel_w * 2; // modified by doJustify() + style->doJustify(title, pos, frame.window_label_w, frame.bevel_w * 4); + style->font->drawString(frame.window_label, pos, 1, style->w_text, title); } @@ -656,18 +616,10 @@ void Toolbar::redrawWorkspaceLabel(bool redraw) { ToolbarStyle *style = screen->getToolbarStyle(); - int pos = frame.bevel_w * 2, - dlen = style->doJustify(name.c_str(), pos, frame.workspace_label_w, - frame.bevel_w * 4, i18n.multibyte()); - BPen pen(style->l_text, style->font); - if (i18n.multibyte()) - XmbDrawString(display, frame.workspace_label, style->fontset, pen.gc(), - pos, (1 - style->fontset_extents->max_ink_extent.y), - name.c_str(), dlen); - else - XDrawString(display, frame.workspace_label, pen.gc(), pos, - (style->font->ascent + 1), - name.c_str(), dlen); + int pos = frame.bevel_w * 2; + style->doJustify(name.c_str(), pos, frame.workspace_label_w, + frame.bevel_w * 4); + style->font->drawString(frame.workspace_label, pos, 1, style->l_text, name); } @@ -695,7 +647,7 @@ void Toolbar::redrawPrevWorkspaceButton(bool pressed, bool redraw) { pts[2].x = 0; pts[2].y = -4; ToolbarStyle *style = screen->getToolbarStyle(); - BPen pen(style->b_pic, style->font); + BPen pen(style->b_pic); XFillPolygon(display, frame.psbutton, pen.gc(), pts, 3, Convex, CoordModePrevious); } @@ -725,7 +677,7 @@ void Toolbar::redrawNextWorkspaceButton(bool pressed, bool redraw) { pts[2].x = -4; pts[2].y = 2; ToolbarStyle *style = screen->getToolbarStyle(); - BPen pen(style->b_pic, style->font); + BPen pen(style->b_pic); XFillPolygon(display, frame.nsbutton, pen.gc(), pts, 3, Convex, CoordModePrevious); } @@ -755,7 +707,7 @@ void Toolbar::redrawPrevWindowButton(bool pressed, bool redraw) { pts[2].x = 0; pts[2].y = -4; ToolbarStyle *style = screen->getToolbarStyle(); - BPen pen(style->b_pic, style->font); + BPen pen(style->b_pic); XFillPolygon(display, frame.pwbutton, pen.gc(), pts, 3, Convex, CoordModePrevious); } @@ -785,7 +737,7 @@ void Toolbar::redrawNextWindowButton(bool pressed, bool redraw) { pts[2].x = -4; pts[2].y = 2; ToolbarStyle *style = screen->getToolbarStyle(); - BPen pen(style->b_pic, style->font); + BPen pen(style->b_pic); XFillPolygon(display, frame.nwbutton, pen.gc(), pts, 3, Convex, CoordModePrevious); } @@ -809,7 +761,7 @@ void Toolbar::edit(void) { blackbox->getFocusedWindow()->setFocusFlag(False); ToolbarStyle *style = screen->getToolbarStyle(); - BPen pen(style->l_text, style->font); + BPen pen(style->l_text); XDrawRectangle(display, frame.workspace_label, pen.gc(), frame.workspace_label_w / 2, 0, 1, frame.label_h - 1); @@ -1020,32 +972,17 @@ void Toolbar::keyPressEvent(XKeyEvent *ke) { } XClearWindow(display, frame.workspace_label); - unsigned int l = new_workspace_name.length(), tw, x; + unsigned int tw, x; - if (i18n.multibyte()) { - XRectangle ink, logical; - XmbTextExtents(screen->getToolbarStyle()->fontset, - new_workspace_name.c_str(), l, &ink, &logical); - tw = logical.width; - } else { - tw = XTextWidth(screen->getToolbarStyle()->font, - new_workspace_name.c_str(), l); - } + tw = screen->getToolbarStyle()->font->measureString(new_workspace_name); x = (frame.workspace_label_w - tw) / 2; if (x < frame.bevel_w) x = frame.bevel_w; ToolbarStyle *style = screen->getToolbarStyle(); - BPen pen(style->l_text, style->font); - if (i18n.multibyte()) - XmbDrawString(display, frame.workspace_label, style->fontset, - pen.gc(), x, - (1 - style->fontset_extents->max_ink_extent.y), - new_workspace_name.c_str(), l); - else - XDrawString(display, frame.workspace_label, pen.gc(), x, - (style->font->ascent + 1), - new_workspace_name.c_str(), l); + style->font->drawString(frame.workspace_label, x, 1, style->l_text, + new_workspace_name); + BPen pen(style->l_text); XDrawRectangle(display, frame.workspace_label, pen.gc(), x + tw, 0, 1, frame.label_h - 1); } @@ -1235,21 +1172,14 @@ void Toolbarmenu::Placementmenu::itemSelected(int button, unsigned int index) { } -int ToolbarStyle::doJustify(const char *text, int &start_pos, - unsigned int max_length, unsigned int modifier, - bool multibyte) const { - size_t text_len = strlen(text); +int ToolbarStyle::doJustify(const std::string &text, int &start_pos, + unsigned int max_length, + unsigned int modifier) const { + size_t text_len = text.size(); unsigned int length; do { - if (multibyte) { - XRectangle ink, logical; - XmbTextExtents(fontset, text, text_len, &ink, &logical); - length = logical.width; - } else { - length = XTextWidth(font, text, text_len); - } - length += modifier; + length = font->measureString(string(text, 0, text_len)) + modifier; } while (length > max_length && text_len-- > 0); switch (justify) { diff --git a/src/Util.hh b/src/Util.hh index 2a40308d..a0acd4cd 100644 --- a/src/Util.hh +++ b/src/Util.hh @@ -101,11 +101,9 @@ struct PointerAssassin { std::string itostring(unsigned long i); std::string itostring(long i); -inline std::string itostring(unsigned int i) { - return itostring((unsigned long) i); -} -inline std::string itostring(int i) { - return itostring((long) i); -} - +inline std::string itostring(unsigned int i) + { return itostring((unsigned long) i); } +inline std::string itostring(int i) + { return itostring((long) i); } + #endif diff --git a/src/Window.cc b/src/Window.cc index 3816538d..e1798243 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -44,6 +44,7 @@ extern "C" { #include "i18n.hh" #include "blackbox.hh" +#include "Font.hh" #include "GCCache.hh" #include "Iconmenu.hh" #include "Image.hh" @@ -2323,20 +2324,12 @@ void BlackboxWindow::redrawLabel(void) const { WindowStyle *style = screen->getWindowStyle(); - int pos = frame.bevel_w * 2, - dlen = style->doJustify(client.title.c_str(), pos, frame.label_w, - frame.bevel_w * 4, i18n.multibyte()); - - BPen pen((flags.focused) ? style->l_text_focus : style->l_text_unfocus, - style->font); - if (i18n.multibyte()) - XmbDrawString(blackbox->getXDisplay(), frame.label, style->fontset, - pen.gc(), pos, - (1 - style->fontset_extents->max_ink_extent.y), - client.title.c_str(), dlen); - else - XDrawString(blackbox->getXDisplay(), frame.label, pen.gc(), pos, - (style->font->ascent + 1), client.title.c_str(), dlen); + int pos = frame.bevel_w * 2; + style->doJustify(client.title.c_str(), pos, frame.label_w, frame.bevel_w * 4); + style->font->drawString(frame.label, pos, 1, + (flags.focused ? style->l_text_focus : + style->l_text_unfocus), + client.title); } @@ -3406,12 +3399,7 @@ void BlackboxWindow::upsize(void) { // the height of the titlebar is based upon the height of the font being // used to display the window's title WindowStyle *style = screen->getWindowStyle(); - if (i18n.multibyte()) - frame.title_h = (style->fontset_extents->max_ink_extent.height + - (frame.bevel_w * 2) + 2); - else - frame.title_h = (style->font->ascent + style->font->descent + - (frame.bevel_w * 2) + 2); + frame.title_h = style->font->height() + (frame.bevel_w * 2) + 2; frame.label_h = frame.title_h - (frame.bevel_w * 2); frame.button_w = (frame.label_h - 2); @@ -3554,21 +3542,14 @@ void BlackboxWindow::constrain(Corner anchor, int *pw, int *ph) { } -int WindowStyle::doJustify(const char *text, int &start_pos, - unsigned int max_length, unsigned int modifier, - bool multibyte) const { - size_t text_len = strlen(text); +int WindowStyle::doJustify(const std::string &text, int &start_pos, + unsigned int max_length, + unsigned int modifier) const { + size_t text_len = text.size(); unsigned int length; do { - if (multibyte) { - XRectangle ink, logical; - XmbTextExtents(fontset, text, text_len, &ink, &logical); - length = logical.width; - } else { - length = XTextWidth(font, text, text_len); - } - length += modifier; + length = font->measureString(string(text, 0, text_len)) + modifier; } while (length > max_length && text_len-- > 0); switch (justify) { -- 2.45.2