X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2FFont.cc;h=e2649f10ae3e056ac7609e233cff365ef6e37b07;hb=402e229e76dfd8b4cda8b7cf1fccaec5acf7570c;hp=f377c5ebf330626104738a0386b4d6f36da37fc8;hpb=08d793bb796f608774d6fdefd1950df54477e2c6;p=chaz%2Fopenbox diff --git a/src/Font.cc b/src/Font.cc index f377c5eb..e2649f10 100644 --- a/src/Font.cc +++ b/src/Font.cc @@ -44,94 +44,106 @@ 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, unsigned char offset, + unsigned char tint, bool antialias) : + _display(d), + _screen(screen), + _family(family), + _simplename(False), + _size(size), + _bold(bold), + _italic(italic), + _antialias(antialias), + _shadow(shadow), + _offset(offset), + _tint(tint), + _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 +153,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 +170,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 +209,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 +227,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 +242,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 +265,52 @@ 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 = _tint | _tint << 8; // transparent shadow + c.pixel = BlackPixel(_display, _screen->getScreenNumber()); + +#ifdef XFT_UTF8 + XftDrawStringUtf8( +#else + XftDrawString8( +#endif + draw, &c, _xftfont, x + _offset, + _xftfont->ascent + y + _offset, (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 +322,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 +350,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())