big fat commit..
[mikachu/openbox.git] / src / font.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2
3 #ifdef    HAVE_CONFIG_H
4 #  include "../config.h"
5 #endif // HAVE_CONFIG_H
6
7 extern "C" {
8 #ifdef HAVE_STDLIB_H
9 #  include <stdlib.h>
10 #endif // HAVE_STDLIB_H
11 }
12
13 #include <iostream>
14 #include <algorithm>
15
16 using std::string;
17 using std::cerr;
18 using std::endl;
19
20 #include "font.hh"
21 #include "util.hh"
22 #include "gccache.hh"
23 #include "color.hh"
24
25 string      BFont::_fallback_font   = "fixed";
26
27 BFont::BFont(Display *d, BScreen *screen, const string &family, int size,
28              bool bold, bool italic, bool shadow, unsigned char offset, 
29              unsigned char tint, bool antialias) :
30                                           _display(d),
31                                           _screen(screen),
32                                           _family(family),
33                                           _simplename(False),
34                                           _size(size),
35                                           _bold(bold),
36                                           _italic(italic),
37                                           _antialias(antialias),
38                                           _shadow(shadow),
39                                           _offset(offset),
40                                           _tint(tint),
41                                           _xftfont(0) {
42   _valid = False;
43
44   _xftfont = XftFontOpen(_display, _screen->getScreenNumber(),
45                          XFT_FAMILY, XftTypeString,  _family.c_str(),
46                          XFT_SIZE,   XftTypeInteger, _size,
47                          XFT_WEIGHT, XftTypeInteger, (_bold ?
48                                                       XFT_WEIGHT_BOLD :
49                                                       XFT_WEIGHT_MEDIUM),
50                          XFT_SLANT,  XftTypeInteger, (_italic ?
51                                                       XFT_SLANT_ITALIC :
52                                                       XFT_SLANT_ROMAN),
53                          XFT_ANTIALIAS, XftTypeBool, _antialias,
54                          0);
55   if (! _xftfont)
56     return; // failure
57
58   _valid = True;
59 }
60
61
62 BFont::~BFont(void) {
63   if (_xftfont)
64     XftFontClose(_display, _xftfont);
65 }
66
67
68 void BFont::drawString(Drawable d, int x, int y, const BColor &color,
69                        const string &string) const {
70   assert(_valid);
71
72   XftDraw *draw = XftDrawCreate(_display, d, _screen->getVisual(),
73                                 _screen->getColormap());
74   assert(draw);
75
76   if (_shadow) {
77     XftColor c;
78     c.color.red = 0;
79     c.color.green = 0;
80     c.color.blue = 0;
81     c.color.alpha = _tint | _tint << 8; // transparent shadow
82     c.pixel = BlackPixel(_display, _screen->getScreenNumber());
83
84     XftDrawStringUtf8(draw, &c, _xftfont, x + _offset,
85                       _xftfont->ascent + y + _offset,
86                       (XftChar8 *) string.c_str(),
87                       string.size());
88   }
89     
90   XftColor c;
91   c.color.red = color.red() | color.red() << 8;
92   c.color.green = color.green() | color.green() << 8;
93   c.color.blue = color.blue() | color.blue() << 8;
94   c.pixel = color.pixel();
95   c.color.alpha = 0xff | 0xff << 8; // no transparency in BColor yet
96
97   XftDrawStringUtf8(draw, &c, _xftfont, x, _xftfont->ascent + y,
98                     (XftChar8 *) string.c_str(), string.size());
99
100   XftDrawDestroy(draw);
101   return;
102 }
103
104
105 unsigned int BFont::measureString(const string &string) const {
106   assert(_valid);
107
108   XGlyphInfo info;
109
110   XftTextExtentsUtf8(_display, _xftfont, (XftChar8 *) string.c_str(),
111                      string.size(), &info);
112
113   return info.xOff + (_shadow ? _offset : 0);
114 }
115
116
117 unsigned int BFont::height(void) const {
118   assert(_valid);
119
120   return _xftfont->height + (_shadow ? _offset : 0);
121 }
122
123
124 unsigned int BFont::maxCharWidth(void) const {
125   assert(_valid);
126
127   return _xftfont->max_advance_width;
128 }