all repos — openbox @ 1618ecc845e9191a383ea9ffd1e6ab7e31caec15

openbox fork - make it a bit more like ryudo

extend the style format to use xft.(font|size|flags) to specify an xft font
Dana Jansens danakj@orodu.net
commit

1618ecc845e9191a383ea9ffd1e6ab7e31caec15

parent

5ba3ee6ec29cf3b54a1e3cc3233a37c0c7fdedee

4 files changed, 138 insertions(+), 85 deletions(-)

jump to
M src/Font.ccsrc/Font.cc

@@ -44,26 +44,46 @@ #include "Util.hh"

#include "GCCache.hh" #include "Color.hh" -//bool BFont::_antialias = False; +bool BFont::_antialias = True; 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), + _family(family), _simplename(False), - _size(size * 10), + _size(size), _bold(bold), _italic(italic), -#ifdef XFT _xftfont(0), -#endif // XFT _font(0), _fontset(0), _fontset_extents(0) { - _valid = init(); + _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) :

@@ -81,53 +101,43 @@ 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 ((_valid = createXFont(int_xlfd))) + return; // success - 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; +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. -#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 << - "' 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);

@@ -137,16 +147,14 @@

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,24 +168,34 @@ }

/* - * 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::buildXlfd(void) const { + if (_simplename) + return _family; + + string weight = _bold ? "bold" : "medium"; + string slant = _italic ? "i" : "r"; + string sizestr= _size ? itostring(_size * 10) : "*"; + + return "-*-" + _family + "-" + weight + "-" + slant + "-*-*-*-" + sizestr + + "-*-*-*-*-*-*"; +} + + +/* + * Takes _family, _size, _bold, _italic, etc and builds them into a full XLFD. + */ +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 + "-*-*-*-*-*-*" + ',' + + + "*"; }

@@ -185,9 +203,9 @@ /*

* 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;

@@ -203,10 +221,12 @@ 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 == 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;

@@ -216,15 +236,14 @@ 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()); + _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; }
M src/Font.hhsrc/Font.hh

@@ -47,13 +47,15 @@ /*

* static members */ private: -// static bool _antialias; + 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 bool antialias(void) { return _antialias; } + inline static void setAntialias(bool a) { _antialias = a; } + // the fallback is only used for X fonts, not for Xft fonts, since it is + // assumed that X fonts will be the fallback from Xft. inline static std::string fallbackFont(void) { return _fallback_font; } inline static void setFallbackFont(const std::string &f) { _fallback_font = f; }

@@ -65,7 +67,7 @@ private:

Display *_display; BScreen *_screen; - std::string _name; + std::string _family; bool _simplename; // true if not spec'd as a -*-* string int _size; bool _bold;

@@ -73,6 +75,8 @@ bool _italic;

#ifdef XFT XftFont *_xftfont; + + bool createXftFont(void); #endif // standard

@@ -81,24 +85,28 @@ // multibyte

XFontSet _fontset; XFontSetExtents *_fontset_extents; - std::string buildXlfdName(bool mb) const; + std::string buildXlfd(void) const; + std::string buildMultibyteXlfd(void) const; - bool init(const std::string &xlfd = ""); - bool createFont(void); - bool parseFontString(const std::string &xlfd); + bool createXFont(const std::string &xlfd); + bool parseXlfd(const std::string &xlfd); bool _valid; public: +#ifdef XFT + // loads an Xft font BFont(Display *d, BScreen *screen, const std::string &family, int size, bool bold, bool italic); +#endif + // loads a standard X font BFont(Display *d, BScreen *screen, const std::string &xlfd); - virtual ~BFont(); + virtual ~BFont(void); 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 std::string family(void) const { assert(_valid); return _family; } + inline int size(void) const { assert(_valid); return _size; } inline bool bold(void) const { assert(_valid); return _bold; } inline bool italic(void) const { assert(_valid); return _italic; }
M src/Screen.ccsrc/Screen.cc

@@ -756,10 +756,10 @@ 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); + resource.wstyle.font = readDatabaseFont("window.", style); + resource.tstyle.font = readDatabaseFont("toolbar.", style); + resource.mstyle.t_font = readDatabaseFont("menu.title.", style); + resource.mstyle.f_font = readDatabaseFont("menu.frame.", style); // load window config resource.wstyle.t_focus =

@@ -2137,13 +2137,38 @@ return color;

} -BFont *BScreen::readDatabaseFont(const string &rname, +BFont *BScreen::readDatabaseFont(const string &rbasename, const Configuration &style) { string fontname; string s; - style.getValue(rname, s); // if this fails, a blank string will be used, - // which will cause the fallback font to load. + +#ifdef XFT + int i; + if (style.getValue(rbasename + "xft.font", s) && + style.getValue(rbasename + "xft.size", i)) { + string family = s; + bool bold = False; + bool italic = False; + if (style.getValue(rbasename + "xft.flags", s)) { + if (s.find("bold") != string::npos) + bold = True; + if (s.find("italic") != string::npos) + italic = True; + } + + BFont *b = new BFont(blackbox->getXDisplay(), this, family, i, bold, + italic); + if (b->valid()) + return b; + else + delete b; // fall back to the normal X font stuff + } +#endif // XFT + + style.getValue(rbasename + "font", s); + // if this fails, a blank string will be used, which will cause the fallback + // font to load. BFont *b = new BFont(blackbox->getXDisplay(), this, s); if (! b->valid())
M src/Screen.hhsrc/Screen.hh

@@ -180,7 +180,8 @@ const Configuration &style);

BColor readDatabaseColor(const std::string &rname, const std::string &default_color, const Configuration &style); - BFont *readDatabaseFont(const std::string &rname, const Configuration &style); + BFont *readDatabaseFont(const std::string &rbasename, + const Configuration &style); void InitMenu(void); void LoadStyle(void);