]> Dogcows Code - chaz/openbox/blobdiff - src/Font.cc
merged with 2_1-merged-to-HEAD-2002-09-30
[chaz/openbox] / src / Font.cc
index f377c5ebf330626104738a0386b4d6f36da37fc8..fd7a0fbe3bb47111ca3aa650c53f62796f18a4a9 100644 (file)
@@ -44,94 +44,103 @@ using std::endl;
 #include "GCCache.hh"
 #include "Color.hh"
 
-//bool        BFont::_antialias       = False;
 string      BFont::_fallback_font   = "fixed";
 
-
+#ifdef XFT
 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();
+             bool bold, bool italic, bool shadow, bool antialias) :
+                                          _display(d),
+                                          _screen(screen),
+                                          _family(family),
+                                          _simplename(False),
+                                          _size(size),
+                                          _bold(bold),
+                                          _italic(italic),
+                                          _antialias(antialias),
+                                          _shadow(shadow),
+                                          _xftfont(0),
+                                          _font(0),
+                                          _fontset(0),
+                                          _fontset_extents(0) {
+  _valid = False;
+
+  _xftfont = XftFontOpen(_display, _screen->getScreenNumber(),
+                         XFT_FAMILY, XftTypeString,  _family.c_str(),
+                         XFT_SIZE,   XftTypeInteger, _size,
+                         XFT_WEIGHT, XftTypeInteger, (_bold ?
+                                                      XFT_WEIGHT_BOLD :
+                                                      XFT_WEIGHT_MEDIUM),
+                         XFT_SLANT,  XftTypeInteger, (_italic ?
+                                                      XFT_SLANT_ITALIC :
+                                                      XFT_SLANT_ROMAN),
+                         XFT_ANTIALIAS, XftTypeBool, _antialias,
+                         0);
+  if (! _xftfont)
+    return; // failure
+
+  _font = XLoadQueryFont(_display, buildXlfd().c_str()); 
+  if (! _font)
+    return; // failure
+
+  _valid = True;
 }
+#endif
 
 
 BFont::BFont(Display *d, BScreen *screen, const string &xlfd) :
                                        _display(d),
                                        _screen(screen),
 #ifdef    XFT
+                                       _antialias(False),
+                                       _shadow(False),
                                        _xftfont(0),
 #endif // XFT
                                        _font(0),
                                        _fontset(0),
-                                       _fontset_extents(0),
-                                       _cache(0),
-                                       _item(0) {
+                                       _fontset_extents(0) {
   string int_xlfd;
   if (xlfd.empty())
     int_xlfd = _fallback_font;
   else
     int_xlfd = xlfd;
   
-  _valid = init(xlfd);
-}
+  if ((_valid = createXFont(int_xlfd)))
+    return; // success
 
-
-bool BFont::init(const string &xlfd) {
-  // try load the specified font
-  if (xlfd.empty() || parseFontString(xlfd))
-    if (createFont())
-      return True;
-
-  if (xlfd != _fallback_font) {
+  if (int_xlfd != _fallback_font) {
     // try the fallback
-    cerr << "BFont::BFont(): couldn't load font '" << _name << "'" << endl <<
+    cerr << "BFont::BFont(): couldn't load font '" << _family << "'" << endl <<
       "Falling back to default '" << _fallback_font << "'" << endl;
-  if (parseFontString(_fallback_font))
-    if (createFont())
-      return True;
+
+    if ((_valid = createXFont(_fallback_font)))
+      return; // success
   }
 
-  cerr << "BFont::BFont(): couldn't load font '" << _name << "'" << endl <<
+  cerr << "BFont::BFont(): couldn't load font '" << _family << "'" << endl <<
     "Giving up!" << endl;
-  
-  return False;
+  return; // failure
 }
 
 
-bool BFont::createFont(void) {
-  std::string fullname;
-
-#ifdef    XFT
-  fullname = buildXlfdName(False);
-  _xftfont = XftFontOpenXlfd(_display, _screen->getScreenNumber(),
-                             fullname.c_str());
-  if (_xftfont)
-    return True;
+bool BFont::createXFont(const std::string &xlfd) {
+  /*
+     Even though this is only used for font sets (multibyte), it is still parsed
+     out so that the bold/italic/etc information is still available from the
+     class when using non-multibyte.
 
-  cerr << "BFont::BFont(): couldn't load font '" << _name << "'" << endl <<
-    "as an Xft font, trying as a standard X font." << endl;
-#endif
+     This is where _simplename, _bold, _italic, and _size are initialized, since
+     they are not initialized in the constructor. This needs to occur before
+     calling any Xlfd-building functions.
+  */
+  if (! parseXlfd(xlfd))
+    return False;
 
   if (i18n.multibyte()) {
     char **missing, *def = "-";
     int nmissing;
-  
-    fullname = buildXlfdName(True);
-    _fontset = XCreateFontSet(_display, fullname.c_str(), &missing, &nmissing,
-                              &def);
+    _fontset = XCreateFontSet(_display, buildMultibyteXlfd().c_str(),
+                              &missing, &nmissing, &def);
     if (nmissing) XFreeStringList(missing);
     if (_fontset)
       _fontset_extents = XExtentsOfFontSet(_fontset);
@@ -141,16 +150,14 @@ bool BFont::createFont(void) {
     assert(_fontset_extents);
   }
     
-  fullname = buildXlfdName(False);
-  cerr << "loading font '" << fullname.c_str() << "'\n";
-  _font = XLoadQueryFont(_display, fullname.c_str());
+  _font = XLoadQueryFont(_display, xlfd.c_str());
   if (! _font)
     return False;
   return True;
 }
 
 
-BFont::~BFont() {
+BFont::~BFont(void) {
 #ifdef    XFT
   if (_xftfont)
     XftFontClose(_display, _xftfont);
@@ -160,31 +167,38 @@ BFont::~BFont() {
     XFreeFontSet(_display, _fontset);
   if (_font)
     XFreeFont(_display, _font);
+}
+
+
+/*
+ * Takes _family, _size, _bold, _italic, etc and builds them into a full XLFD.
+ */
+string BFont::buildXlfd(void) const {
+  if (_simplename) 
+    return _family;
 
-  if (_item)
-    _cache->release(_item);
+  string weight = _bold ? "bold" : "medium";
+  string slant = _italic ? "i" : "r";
+  string sizestr= _size ? itostring(_size * 10) : "*";
+
+  return "-*-" + _family + "-" + weight + "-" + slant + "-*-*-*-" + sizestr +
+      "-*-*-*-*-*-*";
 }
 
 
 /*
- * Takes _name, _size, _bold, _italic, etc and builds them into a full XLFD.
+ * Takes _family, _size, _bold, _italic, etc and builds them into a full XLFD.
  */
-string BFont::buildXlfdName(bool mb) const {
+string BFont::buildMultibyteXlfd(void) 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 + "-*-*-*-*-*-*";
+  return _family + ','
+    + "-*-*-" + weight + "-" + slant + "-*-*-*-" + sizestr +
+      "-*-*-*-*-*-*" + ','
+    + "-*-*-*-*-*-*-*-" + sizestr + "-*-*-*-*-*-*" + ',' +
+    + "*";
 }
 
 
@@ -192,9 +206,9 @@ string BFont::buildXlfdName(bool mb) const {
  * 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) {
+bool BFont::parseXlfd(const string &xlfd) {
   if (xlfd.empty() || xlfd[0] != '-') {
-    _name = xlfd;
+    _family = xlfd;
     _simplename = True;
     _bold = False;
     _italic = False;
@@ -210,10 +224,12 @@ bool BFont::parseFontString(const string &xlfd) {
     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 == 2) _family = 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 (i == 7 && string(tmp, it) != "*") sizestr = string(tmp, it);
+      if (sizestr.empty() &&
+          i == 8 && string(tmp, it) != "*") sizestr = string(tmp, it);
       if (it == end || i >= 8)
         break;
       ++it;
@@ -223,15 +239,14 @@ bool BFont::parseFontString(const string &xlfd) {
       return False;
     _bold = weight == "bold" || weight == "demibold";
     _italic = slant == "i" || slant == "o";
-    if (atoi(sizestr.c_str()))
-      _size = atoi(sizestr.c_str());
+    _size = atoi(sizestr.c_str()) / 10;
   }
   
   // 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;
+  if (_size && _size < 3)
+    _size = 3;
+  else if (_size > 97)
+    _size = 97;
 
   return True;
 }
@@ -247,35 +262,51 @@ void BFont::drawString(Drawable d, int x, int y, const BColor &color,
                                   _screen->getColormap());
     assert(draw);
 
+    if (_shadow) {
+      XftColor c;
+      c.color.red = 0;
+      c.color.green = 0;
+      c.color.blue = 0;
+      c.color.alpha = 0x40 | 0x40 << 8; // transparent shadow
+      c.pixel = BlackPixel(_display, _screen->getScreenNumber());
+
+#ifdef XFT_UTF8
+      XftDrawStringUtf8(
+#else
+      XftDrawString8(
+#endif
+                     draw, &c, _xftfont, x + 1, _xftfont->ascent + y + 1,
+                     (XftChar8 *) string.c_str(), string.size());
+    }
+    
     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());
+    c.color.alpha = 0xff | 0xff << 8; // no transparency in BColor yet
+
+#ifdef XFT_UTF8
+    XftDrawStringUtf8(
+#else
+    XftDrawString8(
+#endif
+                   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);
+  BPen pen(color, _font);
 
   if (i18n.multibyte())
-    XmbDrawString(_display, d, _fontset, _item->gc(),
+    XmbDrawString(_display, d, _fontset, pen.gc(),
                   x, y - _fontset_extents->max_ink_extent.y,
                   string.c_str(), string.size());
   else
-    XDrawString(_display, d, _item->gc(),
+    XDrawString(_display, d, pen.gc(),
                 x, _font->ascent + y,
                 string.c_str(), string.size());
 }
@@ -287,9 +318,16 @@ unsigned int BFont::measureString(const string &string) const {
 #ifdef    XFT
   if (_xftfont) {
     XGlyphInfo info;
-    XftTextExtentsUtf8(_display, _xftfont, (XftChar8 *) string.c_str(),
-                       string.size(), &info);
-    return info.xOff;
+
+#ifdef XFT_UTF8
+    XftTextExtentsUtf8(
+#else
+    XftTextExtents8(
+#endif
+                    _display, _xftfont, (XftChar8 *) string.c_str(),
+                    string.size(), &info);
+
+    return info.xOff + (_shadow ? 1 : 0);
   }
 #endif // XFT
 
@@ -308,7 +346,7 @@ unsigned int BFont::height(void) const {
 
 #ifdef    XFT
   if (_xftfont)
-    return _xftfont->height;
+    return _xftfont->height + (_shadow ? 1 : 0);
 #endif // XFT
 
   if (i18n.multibyte())
This page took 0.030487 seconds and 4 git commands to generate.