extend the style format to use xft.(font|size|flags) to specify an xft font

This commit is contained in:
Dana Jansens 2002-07-08 02:28:24 +00:00
parent 5ba3ee6ec2
commit 1618ecc845
4 changed files with 138 additions and 85 deletions

View file

@ -44,26 +44,46 @@ using std::endl;
#include "GCCache.hh" #include "GCCache.hh"
#include "Color.hh" #include "Color.hh"
//bool BFont::_antialias = False; bool BFont::_antialias = True;
string BFont::_fallback_font = "fixed"; string BFont::_fallback_font = "fixed";
#ifdef XFT
BFont::BFont(Display *d, BScreen *screen, const string &family, int size, BFont::BFont(Display *d, BScreen *screen, const string &family, int size,
bool bold, bool italic) : _display(d), bool bold, bool italic) : _display(d),
_screen(screen), _screen(screen),
_name(family), _family(family),
_simplename(False), _simplename(False),
_size(size * 10), _size(size),
_bold(bold), _bold(bold),
_italic(italic), _italic(italic),
#ifdef XFT
_xftfont(0), _xftfont(0),
#endif // XFT
_font(0), _font(0),
_fontset(0), _fontset(0),
_fontset_extents(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) : BFont::BFont(Display *d, BScreen *screen, const string &xlfd) :
@ -81,53 +101,43 @@ BFont::BFont(Display *d, BScreen *screen, const string &xlfd) :
else else
int_xlfd = xlfd; int_xlfd = xlfd;
_valid = init(xlfd); if ((_valid = createXFont(int_xlfd)))
} return; // success
if (int_xlfd != _fallback_font) {
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 // 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; "Falling back to default '" << _fallback_font << "'" << endl;
if (parseFontString(_fallback_font))
if (createFont()) if ((_valid = createXFont(_fallback_font)))
return True; return; // success
} }
cerr << "BFont::BFont(): couldn't load font '" << _name << "'" << endl << cerr << "BFont::BFont(): couldn't load font '" << _family << "'" << endl <<
"Giving up!" << endl; "Giving up!" << endl;
return; // failure
return False;
} }
bool BFont::createFont(void) { bool BFont::createXFont(const std::string &xlfd) {
std::string fullname; /*
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 This is where _simplename, _bold, _italic, and _size are initialized, since
fullname = buildXlfdName(False); they are not initialized in the constructor. This needs to occur before
_xftfont = XftFontOpenXlfd(_display, _screen->getScreenNumber(), calling any Xlfd-building functions.
fullname.c_str()); */
if (_xftfont) if (! parseXlfd(xlfd))
return True; return False;
cerr << "BFont::BFont(): couldn't load font '" << _name <<
"' as an Xft font, trying as a standard X font." << endl;
#endif
if (i18n.multibyte()) { if (i18n.multibyte()) {
char **missing, *def = "-"; char **missing, *def = "-";
int nmissing; int nmissing;
fullname = buildXlfdName(True); _fontset = XCreateFontSet(_display, buildMultibyteXlfd().c_str(),
_fontset = XCreateFontSet(_display, fullname.c_str(), &missing, &nmissing, &missing, &nmissing, &def);
&def);
if (nmissing) XFreeStringList(missing); if (nmissing) XFreeStringList(missing);
if (_fontset) if (_fontset)
_fontset_extents = XExtentsOfFontSet(_fontset); _fontset_extents = XExtentsOfFontSet(_fontset);
@ -137,16 +147,14 @@ bool BFont::createFont(void) {
assert(_fontset_extents); assert(_fontset_extents);
} }
fullname = buildXlfdName(False); _font = XLoadQueryFont(_display, xlfd.c_str());
cerr << "loading font '" << fullname.c_str() << "'\n";
_font = XLoadQueryFont(_display, fullname.c_str());
if (! _font) if (! _font)
return False; return False;
return True; return True;
} }
BFont::~BFont() { BFont::~BFont(void) {
#ifdef XFT #ifdef XFT
if (_xftfont) if (_xftfont)
XftFontClose(_display, _xftfont); XftFontClose(_display, _xftfont);
@ -160,24 +168,34 @@ BFont::~BFont() {
/* /*
* 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 weight = _bold ? "bold" : "medium";
string slant = _italic ? "i" : "r"; string slant = _italic ? "i" : "r";
string sizestr= _size ? itostring(_size) : "*"; string sizestr= _size ? itostring(_size) : "*";
if (mb) return _family + ','
return _name + ',' + + "-*-*-" + weight + "-" + slant + "-*-*-*-" + sizestr +
"-*-*-" + weight + "-" + slant + "-*-*-" + sizestr + "-*-*-*-*-*-*" + ','
"-*-*-*-*-*-*-*" + ',' + + "-*-*-*-*-*-*-*-" + sizestr + "-*-*-*-*-*-*" + ',' +
"-*-*-*-*-*-*-" + sizestr + "-*-*-*-*-*-*-*" + ',' + + "*";
"*";
else if (_simplename)
return _name;
else
return "-*-" + _name + "-" + weight + "-" + slant + "-*-*-*-" +
sizestr + "-*-*-*-*-*-*";
} }
@ -185,9 +203,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 * Takes a full X font name and parses it out so we know if we're bold, our
* size, etc. * size, etc.
*/ */
bool BFont::parseFontString(const string &xlfd) { bool BFont::parseXlfd(const string &xlfd) {
if (xlfd.empty() || xlfd[0] != '-') { if (xlfd.empty() || xlfd[0] != '-') {
_name = xlfd; _family = xlfd;
_simplename = True; _simplename = True;
_bold = False; _bold = False;
_italic = False; _italic = False;
@ -203,10 +221,12 @@ bool BFont::parseFontString(const string &xlfd) {
while(1) { while(1) {
string::const_iterator tmp = it; // current string.begin() string::const_iterator tmp = it; // current string.begin()
it = std::find(tmp, end, '-'); // look for comma between tmp and end 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 == 3) weight = string(tmp, it);
if (i == 4) slant = 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) if (it == end || i >= 8)
break; break;
++it; ++it;
@ -216,15 +236,14 @@ bool BFont::parseFontString(const string &xlfd) {
return False; return False;
_bold = weight == "bold" || weight == "demibold"; _bold = weight == "bold" || weight == "demibold";
_italic = slant == "i" || slant == "o"; _italic = slant == "i" || slant == "o";
if (atoi(sizestr.c_str())) _size = atoi(sizestr.c_str()) / 10;
_size = atoi(sizestr.c_str());
} }
// min/max size restrictions for sanity, but 0 is the font's "default size" // min/max size restrictions for sanity, but 0 is the font's "default size"
if (_size && _size < 30) if (_size && _size < 3)
_size = 30; _size = 3;
else if (_size > 970) else if (_size > 97)
_size = 970; _size = 97;
return True; return True;
} }

View file

@ -47,13 +47,15 @@ class BFont {
* static members * static members
*/ */
private: private:
// static bool _antialias; static bool _antialias;
static std::string _fallback_font; static std::string _fallback_font;
public: public:
// inline static bool antialias(void) { return _antialias; } inline static bool antialias(void) { return _antialias; }
// inline static void setAntialias(bool a) { _antialias = a; } 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 std::string fallbackFont(void) { return _fallback_font; }
inline static void setFallbackFont(const std::string &f) inline static void setFallbackFont(const std::string &f)
{ _fallback_font = f; } { _fallback_font = f; }
@ -65,7 +67,7 @@ private:
Display *_display; Display *_display;
BScreen *_screen; BScreen *_screen;
std::string _name; std::string _family;
bool _simplename; // true if not spec'd as a -*-* string bool _simplename; // true if not spec'd as a -*-* string
int _size; int _size;
bool _bold; bool _bold;
@ -73,6 +75,8 @@ private:
#ifdef XFT #ifdef XFT
XftFont *_xftfont; XftFont *_xftfont;
bool createXftFont(void);
#endif #endif
// standard // standard
@ -81,24 +85,28 @@ private:
XFontSet _fontset; XFontSet _fontset;
XFontSetExtents *_fontset_extents; 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 createXFont(const std::string &xlfd);
bool createFont(void); bool parseXlfd(const std::string &xlfd);
bool parseFontString(const std::string &xlfd);
bool _valid; bool _valid;
public: public:
#ifdef XFT
// loads an Xft font
BFont(Display *d, BScreen *screen, const std::string &family, int size, BFont(Display *d, BScreen *screen, const std::string &family, int size,
bool bold, bool italic); bool bold, bool italic);
#endif
// loads a standard X font
BFont(Display *d, BScreen *screen, const std::string &xlfd); BFont(Display *d, BScreen *screen, const std::string &xlfd);
virtual ~BFont(); virtual ~BFont(void);
inline bool valid(void) const { return _valid; } inline bool valid(void) const { return _valid; }
inline std::string name(void) const { assert(_valid); return _name; } inline std::string family(void) const { assert(_valid); return _family; }
inline int size(void) const { assert(_valid); return _size / 10; } inline int size(void) const { assert(_valid); return _size; }
inline bool bold(void) const { assert(_valid); return _bold; } inline bool bold(void) const { assert(_valid); return _bold; }
inline bool italic(void) const { assert(_valid); return _italic; } inline bool italic(void) const { assert(_valid); return _italic; }

View file

@ -756,10 +756,10 @@ void BScreen::LoadStyle(void) {
resource.wstyle.font = resource.tstyle.font = resource.mstyle.f_font = resource.wstyle.font = resource.tstyle.font = resource.mstyle.f_font =
resource.mstyle.t_font = (BFont *) 0; resource.mstyle.t_font = (BFont *) 0;
resource.wstyle.font = readDatabaseFont("window.font", style); resource.wstyle.font = readDatabaseFont("window.", style);
resource.tstyle.font = readDatabaseFont("toolbar.font", style); resource.tstyle.font = readDatabaseFont("toolbar.", style);
resource.mstyle.t_font = readDatabaseFont("menu.title.font", style); resource.mstyle.t_font = readDatabaseFont("menu.title.", style);
resource.mstyle.f_font = readDatabaseFont("menu.frame.font", style); resource.mstyle.f_font = readDatabaseFont("menu.frame.", style);
// load window config // load window config
resource.wstyle.t_focus = resource.wstyle.t_focus =
@ -2137,13 +2137,38 @@ BColor BScreen::readDatabaseColor(const string &rname,
} }
BFont *BScreen::readDatabaseFont(const string &rname, BFont *BScreen::readDatabaseFont(const string &rbasename,
const Configuration &style) { const Configuration &style) {
string fontname; string fontname;
string s; 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); BFont *b = new BFont(blackbox->getXDisplay(), this, s);
if (! b->valid()) if (! b->valid())

View file

@ -180,7 +180,8 @@ private:
BColor readDatabaseColor(const std::string &rname, BColor readDatabaseColor(const std::string &rname,
const std::string &default_color, const std::string &default_color,
const Configuration &style); 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 InitMenu(void);
void LoadStyle(void); void LoadStyle(void);