aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/Font.cc
diff options
context:
space:
mode:
authorMathias Gumz <akira at fluxbox dot org>2012-10-02 12:24:47 (GMT)
committerMathias Gumz <akira at fluxbox dot org>2012-10-03 08:27:16 (GMT)
commit7b6ab828c7e5453a2720462156d165707935c9ef (patch)
tree3b641791b20b1994935e149fd7461decb11bef8c /src/FbTk/Font.cc
parent032a23d1e790c5224194562a837cc80fc157ce9b (diff)
downloadfluxbox-7b6ab828c7e5453a2720462156d165707935c9ef.zip
fluxbox-7b6ab828c7e5453a2720462156d165707935c9ef.tar.bz2
Improved vertical alignment of text in FbTk::TextButton
The old formula for vertical align text inside FbTk::TextButton ('height/2 + font_ascent/2 - 1') produced not always good looking results, escpecially when different fonts are involved (eg, ClockTool and WorkspaceName have different fonts and font-sizes). '(height - font_ascent) / 2 - 1' produces better results. Additional changes: * added ASCII-Art to document the involved entities when calculating the baseline * rewritten tests/testFont.cc to accept multiples texts and multiple fonts * removed some internal parts of FbTk::Font from the public interface
Diffstat (limited to 'src/FbTk/Font.cc')
-rw-r--r--src/FbTk/Font.cc75
1 files changed, 48 insertions, 27 deletions
diff --git a/src/FbTk/Font.cc b/src/FbTk/Font.cc
index 37621a8..544ddc2 100644
--- a/src/FbTk/Font.cc
+++ b/src/FbTk/Font.cc
@@ -66,6 +66,7 @@
66#include <map> 66#include <map>
67#include <typeinfo> 67#include <typeinfo>
68#include <langinfo.h> 68#include <langinfo.h>
69#include <cstdio>
69 70
70#include <errno.h> 71#include <errno.h>
71 72
@@ -83,12 +84,10 @@ namespace {
83// use to map <font1>|<font2>|<font3> => <fontthatworks> 84// use to map <font1>|<font2>|<font3> => <fontthatworks>
84typedef map<string, string> StringMap; 85typedef map<string, string> StringMap;
85typedef StringMap::iterator StringMapIt; 86typedef StringMap::iterator StringMapIt;
86StringMap lookup_map;
87 87
88// stores <fontthatworks and the fontimp 88// stores <fontthatworks and the fontimp
89typedef map<string, FbTk::FontImp* > FontCache; 89typedef map<string, FbTk::FontImp* > FontCache;
90typedef FontCache::iterator FontCacheIt; 90typedef FontCache::iterator FontCacheIt;
91FontCache font_cache;
92 91
93 92
94void resetEffects(FbTk::Font& font) { 93void resetEffects(FbTk::Font& font) {
@@ -100,24 +99,30 @@ void resetEffects(FbTk::Font& font) {
100 font.setShadowOffX(2); 99 font.setShadowOffX(2);
101} 100}
102 101
102
103StringMap s_lookup_map;
104FontCache s_font_cache;
105bool s_multibyte = false; // if the fontimp should be a multibyte font
106bool s_utf8mode = false; // should the font use utf8 font imp
107
108
103} // end nameless namespace 109} // end nameless namespace
104 110
105 111
106 112
107namespace FbTk { 113namespace FbTk {
108 114
109bool Font::s_multibyte = false; 115const char Font::DEFAULT_FONT[] = "__DEFAULT__";
110bool Font::s_utf8mode = false;
111 116
112 117
113void Font::shutdown() { 118void Font::shutdown() {
114 119
115 FontCacheIt fit; 120 FontCacheIt fit;
116 for (fit = font_cache.begin(); fit != font_cache.end(); fit++) { 121 for (fit = s_font_cache.begin(); fit != s_font_cache.end(); ++fit) {
117 FontImp* font = fit->second; 122 FontImp* font = fit->second;
118 if (font) { 123 if (font) {
119 FontCacheIt it; 124 FontCacheIt it;
120 for (it = fit; it != font_cache.end(); ++it) 125 for (it = fit; it != s_font_cache.end(); ++it)
121 if (it->second == font) 126 if (it->second == font)
122 it->second = 0; 127 it->second = 0;
123 delete font; 128 delete font;
@@ -125,6 +130,15 @@ void Font::shutdown() {
125 } 130 }
126} 131}
127 132
133bool Font::multibyte() {
134 return s_multibyte;
135}
136
137bool Font::utf8() {
138 return s_utf8mode;
139}
140
141
128Font::Font(const char *name): 142Font::Font(const char *name):
129 m_fontimp(0), 143 m_fontimp(0),
130 m_shadow(false), m_shadow_color("black", DefaultScreen(App::instance()->display())), 144 m_shadow(false), m_shadow_color("black", DefaultScreen(App::instance()->display())),
@@ -135,13 +149,15 @@ Font::Font(const char *name):
135 if (MB_CUR_MAX > 1) // more than one byte, then we're multibyte 149 if (MB_CUR_MAX > 1) // more than one byte, then we're multibyte
136 s_multibyte = true; 150 s_multibyte = true;
137 151
138 // check for utf-8 mode 152
139#if defined(CODESET) && !defined(_WIN32)
140 char *locale_codeset = nl_langinfo(CODESET);
141#else // openbsd doesnt have this (yet?)
142 char *locale_codeset = 0; 153 char *locale_codeset = 0;
143#endif // defined(CODESET) && !defined(_WIN32)
144 154
155 // openbsd doesnt have this (yet?)
156#if defined(CODESET) && !defined(_WIN32)
157 locale_codeset = nl_langinfo(CODESET);
158#endif
159
160 // check for utf-8 mode
145 if (locale_codeset && strcmp("UTF-8", locale_codeset) == 0) { 161 if (locale_codeset && strcmp("UTF-8", locale_codeset) == 0) {
146 s_utf8mode = true; 162 s_utf8mode = true;
147 } else if (locale_codeset != 0) { 163 } else if (locale_codeset != 0) {
@@ -159,15 +175,15 @@ Font::~Font() {
159 175
160bool Font::load(const string &name) { 176bool Font::load(const string &name) {
161 177
162 if (name.size() == 0) 178 if (name.empty())
163 return false; 179 return false;
164 180
165 StringMapIt lookup_entry; 181 StringMapIt lookup_entry;
166 FontCacheIt cache_entry; 182 FontCacheIt cache_entry;
167 183
168 // check if one of <font1>|<font2>|<font3> is already there 184 // check if one of <font1>|<font2>|<font3> is already there
169 if ((lookup_entry = lookup_map.find(name)) != lookup_map.end() && 185 if ((lookup_entry = s_lookup_map.find(name)) != s_lookup_map.end() &&
170 (cache_entry = font_cache.find(lookup_entry->second)) != font_cache.end()) { 186 (cache_entry = s_font_cache.find(lookup_entry->second)) != s_font_cache.end()) {
171 m_fontstr = cache_entry->first; 187 m_fontstr = cache_entry->first;
172 m_fontimp = cache_entry->second; 188 m_fontimp = cache_entry->second;
173 resetEffects(*this); 189 resetEffects(*this);
@@ -185,10 +201,10 @@ bool Font::load(const string &name) {
185 FbTk::StringUtil::removeTrailingWhitespace(*name_it); 201 FbTk::StringUtil::removeTrailingWhitespace(*name_it);
186 FbTk::StringUtil::removeFirstWhitespace(*name_it); 202 FbTk::StringUtil::removeFirstWhitespace(*name_it);
187 203
188 if ((cache_entry = font_cache.find(*name_it)) != font_cache.end()) { 204 if ((cache_entry = s_font_cache.find(*name_it)) != s_font_cache.end()) {
189 m_fontstr = cache_entry->first; 205 m_fontstr = cache_entry->first;
190 m_fontimp = cache_entry->second; 206 m_fontimp = cache_entry->second;
191 lookup_map[name] = m_fontstr; 207 s_lookup_map[name] = m_fontstr;
192 resetEffects(*this); 208 resetEffects(*this);
193 return true; 209 return true;
194 } 210 }
@@ -210,32 +226,33 @@ bool Font::load(const string &name) {
210#ifdef USE_XFT 226#ifdef USE_XFT
211 if ((*name_it)[0] != '-') { 227 if ((*name_it)[0] != '-') {
212 228
213 if (*name_it == "__DEFAULT__") 229 if (*name_it == Font::DEFAULT_FONT)
214 realname = "monospace"; 230 realname = "monospace";
215 231
216 tmp_font = new XftFontImp(0, s_utf8mode); 232 tmp_font = new XftFontImp(0, utf8());
217 } 233 }
218#endif // USE_XFT 234#endif // USE_XFT
219 235
220 if (!tmp_font) { 236 if (!tmp_font) {
221 if (*name_it == "__DEFAULT__") 237 if (*name_it == Font::DEFAULT_FONT)
222 realname = "fixed"; 238 realname = "fixed";
223 239
224#ifdef USE_XMB 240#ifdef USE_XMB
225 241
226 if (s_multibyte || s_utf8mode) { 242 if (multibyte() || utf8()) {
227 tmp_font = new XmbFontImp(0, s_utf8mode); 243 tmp_font = new XmbFontImp(0, utf8());
228 } else // basic font implementation 244 }
229#endif // USE_XMB 245#endif // USE_XMB
230 { 246 }
231 tmp_font = new XFontImp(); 247
232 } 248 if (!tmp_font) {
249 tmp_font = new XFontImp();
233 } 250 }
234 251
235 if (tmp_font && tmp_font->load(realname.c_str())) { 252 if (tmp_font && tmp_font->load(realname.c_str())) {
236 lookup_map[name] = (*name_it); 253 s_lookup_map[name] = (*name_it);
237 m_fontimp = tmp_font; 254 m_fontimp = tmp_font;
238 font_cache[(*name_it)] = tmp_font; 255 s_font_cache[(*name_it)] = tmp_font;
239 m_fontstr = name; 256 m_fontstr = name;
240 resetEffects(*this); 257 resetEffects(*this);
241 return true; 258 return true;
@@ -251,6 +268,10 @@ unsigned int Font::textWidth(const char* text, unsigned int size) const {
251 return m_fontimp->textWidth(text, size); 268 return m_fontimp->textWidth(text, size);
252} 269}
253 270
271unsigned int Font::textWidth(const BiDiString &text) const {
272 return textWidth(text.visual().c_str(), text.visual().size());
273}
274
254unsigned int Font::height() const { 275unsigned int Font::height() const {
255 return m_fontimp->height(); 276 return m_fontimp->height();
256} 277}