#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);
-}
-
-
-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 << "'" << 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);
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);
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;
+
+ string weight = _bold ? "bold" : "medium";
+ string slant = _italic ? "i" : "r";
+ string sizestr= _size ? itostring(_size * 10) : "*";
- if (_item)
- _cache->release(_item);
+ 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 + "-*-*-*-*-*-*" + ',' +
+ + "*";
}
* 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;
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;
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;
}
_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());
+
+
+ XftDrawStringUtf8(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();
-
+ c.color.alpha = 0xff | 0xff << 8; // no transparency in BColor yet
+
XftDrawStringUtf8(draw, &c, _xftfont, x, _xftfont->ascent + y,
(XftChar8 *) string.c_str(), string.size());
}
#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());
}
XGlyphInfo info;
XftTextExtentsUtf8(_display, _xftfont, (XftChar8 *) string.c_str(),
string.size(), &info);
- return info.xOff;
+ return info.xOff + (_shadow ? 1 : 0);
}
#endif // XFT
#ifdef XFT
if (_xftfont)
- return _xftfont->height;
+ return _xftfont->height + (_shadow ? 1 : 0);
#endif // XFT
if (i18n.multibyte())