]> Dogcows Code - chaz/openbox/commitdiff
add BFont class, with Xft support
authorDana Jansens <danakj@orodu.net>
Wed, 3 Jul 2002 06:34:25 +0000 (06:34 +0000)
committerDana Jansens <danakj@orodu.net>
Wed, 3 Jul 2002 06:34:25 +0000 (06:34 +0000)
configure.in
src/Basemenu.cc
src/Font.cc [new file with mode: 0644]
src/Font.hh [new file with mode: 0644]
src/Makefile.am
src/Screen.cc
src/Screen.hh
src/Toolbar.cc
src/Util.hh
src/Window.cc

index 1da34f1bac521738477a4f824cedad6a1f884f64..be260e6b838412f3110f8c651cd1d21f33113560 100644 (file)
@@ -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 <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <X11/extensions/shape.h>
 , 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 <X11/Xlib.h>
+#include <X11/Xft/Xft.h>
+, 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])
index 7358df3c3a6c814791ed62416a4b67cf89d788f4..2dd6af7049f07993011e2b925e490c88a7eec192 100644 (file)
@@ -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 (file)
index 0000000..f377c5e
--- /dev/null
@@ -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 <shaleh@debian.org>
+// 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 <stdlib.h>
+#endif // HAVE_STDLIB_H
+}
+
+#include <iostream>
+#include <algorithm>
+
+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 (file)
index 0000000..38c4b4f
--- /dev/null
@@ -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 <shaleh@debian.org>
+// 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 <X11/Xlib.h>
+
+#ifdef XFT
+#  include <X11/Xft/Xft.h>
+#endif
+}
+
+#include <assert.h>
+
+#include <string>
+
+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
index d2ed418587d610ff447577299d219ebf04976d5d..ac6a8908a07ae4a4a04a088e0bfe37bb70e1847f 100644 (file)
@@ -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 \
index dac5d6f8938421579ec4b3b2bb86761f66257a3d..a05c23865ee8380d0a1f565d2bd3e45ebad79069 100644 (file)
@@ -27,11 +27,6 @@ extern "C" {
 #include <X11/Xatom.h>
 #include <X11/keysym.h>
 
-// for strcasestr()
-#ifndef _GNU_SOURCE
-#  define   _GNU_SOURCE
-#endif // _GNU_SOURCE
-
 #ifdef HAVE_STDLIB_H
 #  include <stdlib.h>
 #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;
 }
index 72e7dc0aca91f229a689297a0587e843279b5d11..0fabe9a461fa688da37acce94edb71e52d2ea53b 100644 (file)
@@ -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);
index 55beb59de8898204a18aea5194ea5e90a227ff5d..0018e43ff96c73972f648c17f35acf45096ec46e 100644 (file)
@@ -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) {
index 2a40308d8c34ad84e44ca4d39b071df82ea16024..a0acd4cd758bcf3147225117e1ba5987a2a1db69 100644 (file)
@@ -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
index 3816538da4fc4f9fa56d6ca781ef270d743dee9f..e179824365885361661ea9dee601236a28c5b21b 100644 (file)
@@ -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) {
This page took 0.06568 seconds and 4 git commands to generate.