diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Font.cc | 271 | ||||
-rw-r--r-- | src/Font.hh | 59 |
2 files changed, 91 insertions, 239 deletions
diff --git a/src/Font.cc b/src/Font.cc index 5203ccb..627a825 100644 --- a/src/Font.cc +++ b/src/Font.cc | |||
@@ -19,10 +19,20 @@ | |||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. | 20 | // DEALINGS IN THE SOFTWARE. |
21 | 21 | ||
22 | //$Id: Font.cc,v 1.10 2002/09/03 12:05:01 fluxgen Exp $ | 22 | //$Id: Font.cc,v 1.11 2002/10/13 22:27:21 fluxgen Exp $ |
23 | 23 | ||
24 | 24 | ||
25 | #include "Font.hh" | 25 | #include "Font.hh" |
26 | #include "FontImp.hh" | ||
27 | |||
28 | // for antialias | ||
29 | #ifdef USE_XFT | ||
30 | #include "XftFontImp.hh" | ||
31 | #endif // USE_XFT | ||
32 | |||
33 | // standard font system | ||
34 | #include "XFontImp.hh" | ||
35 | #include "XmbFontImp.hh" | ||
26 | 36 | ||
27 | #ifdef HAVE_CONFIG_H | 37 | #ifdef HAVE_CONFIG_H |
28 | #include "../config.h" | 38 | #include "../config.h" |
@@ -50,231 +60,92 @@ | |||
50 | 60 | ||
51 | #include "StringUtil.hh" | 61 | #include "StringUtil.hh" |
52 | 62 | ||
53 | namespace FbTk | 63 | namespace FbTk { |
54 | { | ||
55 | 64 | ||
56 | bool Font::m_multibyte = false; //TODO: fix multibyte | 65 | bool Font::m_multibyte = false; |
66 | bool Font::m_utf8mode = false; | ||
57 | 67 | ||
58 | Font::Font(Display *display, const char *name):m_loaded(false), | 68 | Font::Font(const char *name, bool antialias) { |
59 | m_display(display) { | ||
60 | m_font.fontstruct = 0; | ||
61 | m_font.set_extents = 0; | ||
62 | m_font.set = 0; | ||
63 | 69 | ||
64 | // MB_CUR_MAX returns the size of a char in the current locale | 70 | // MB_CUR_MAX returns the size of a char in the current locale |
65 | if (MB_CUR_MAX > 1) | 71 | if (MB_CUR_MAX > 1) // more than one byte, then we're multibyte |
66 | m_multibyte = true; | 72 | m_multibyte = true; |
73 | |||
74 | char *s; // temporary string for enviroment variable | ||
75 | // check for utf-8 mode | ||
76 | if (((s = getenv("LC_ALL")) && *s) || | ||
77 | ((s = getenv("LC_CTYPE")) && *s) || | ||
78 | ((s = getenv("LANG")) && *s)) { | ||
79 | if (strstr(s, "UTF-8")) | ||
80 | m_utf8mode = true; | ||
81 | } | ||
82 | |||
83 | // create the right font implementation | ||
84 | #ifdef USE_XFT | ||
85 | if (antialias) { | ||
86 | m_fontimp = new XftFontImp(); | ||
87 | } | ||
88 | #endif //USE_XFT | ||
89 | // if we didn't create a Xft font then create basic font | ||
90 | if (m_fontimp.get() == 0) { | ||
91 | if (m_multibyte || m_utf8mode) | ||
92 | m_fontimp = std::auto_ptr<FontImp>(new XmbFontImp(0, m_utf8mode)); | ||
93 | else // basic font implementation | ||
94 | m_fontimp = std::auto_ptr<FontImp>(new XFontImp(0)); | ||
95 | } | ||
67 | 96 | ||
68 | if (name!=0) { | 97 | if (name != 0) { |
69 | load(name); | 98 | load(name); |
70 | } | 99 | } |
71 | 100 | ||
72 | } | 101 | } |
73 | 102 | ||
74 | Font::~Font() { | 103 | Font::~Font() { |
75 | freeFont(); | ||
76 | } | ||
77 | |||
78 | bool Font::load(const char *name) { | ||
79 | if (m_multibyte) { | ||
80 | XFontSet set = createFontSet(m_display, name); | ||
81 | if (!set) | ||
82 | return false; | ||
83 | freeFont(); | ||
84 | |||
85 | m_font.set = set; | ||
86 | m_font.set_extents = XExtentsOfFontSet(m_font.set); | ||
87 | 104 | ||
88 | } else { | ||
89 | XFontStruct *font = XLoadQueryFont(m_display, name); | ||
90 | if (font==0) | ||
91 | return false; | ||
92 | freeFont(); //free old font | ||
93 | m_font.fontstruct = font; //set new font | ||
94 | } | ||
95 | |||
96 | m_loaded = true; //mark the font loaded | ||
97 | |||
98 | return true; | ||
99 | } | 105 | } |
100 | 106 | ||
101 | bool Font::loadFromDatabase(XrmDatabase &database, const char *rname, const char *rclass) { | 107 | void Font::setAntialias(bool flag) { |
102 | assert(rname); | ||
103 | assert(rclass); | ||
104 | 108 | ||
105 | XrmValue value; | 109 | #ifdef USE_XFT |
106 | char *value_type; | 110 | bool is_antialias = typeid(m_fontimp) == typeid(XftFontImp); |
107 | 111 | ||
108 | //This should probably be moved to a Database class so we can keep | 112 | if (flag && !is_antialias) { |
109 | //track of database init | 113 | m_fontimp = std::auto_ptr<FontImp>(new XftFontImp(m_fontstr.c_str())); |
110 | 114 | } else if (!flag && is_antialias) | |
111 | if (XrmGetResource(database, rname, rclass, &value_type, &value)) { | 115 | #endif // USE_XFT |
112 | #ifdef DEBUG | 116 | { |
113 | std::cerr<<__FILE__<<"("<<__LINE__<<"): Load font:"<<value.addr<<std::endl; | 117 | if (m_multibyte || m_utf8mode) |
114 | #endif | 118 | m_fontimp = std::auto_ptr<FontImp>(new XmbFontImp(m_fontstr.c_str(), m_utf8mode)); |
115 | return load(value.addr); | 119 | else |
120 | m_fontimp = std::auto_ptr<FontImp>(new XFontImp(m_fontstr.c_str())); | ||
116 | } | 121 | } |
117 | |||
118 | return false; | ||
119 | |||
120 | } | ||
121 | unsigned int Font::textWidth(const char *text, unsigned int size) const { | ||
122 | if (text==0) | ||
123 | return 0; | ||
124 | if (multibyte()) { | ||
125 | XRectangle ink, logical; | ||
126 | XmbTextExtents(m_font.set, text, size, | ||
127 | &ink, &logical); | ||
128 | return logical.width; | ||
129 | } else { | ||
130 | assert(m_font.fontstruct); | ||
131 | return XTextWidth(m_font.fontstruct, | ||
132 | text, size); | ||
133 | } | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | unsigned int Font::height() const { | ||
139 | if (!isLoaded()) | ||
140 | return 0; | ||
141 | |||
142 | if (multibyte() && fontSetExtents()) | ||
143 | return fontSetExtents()->max_ink_extent.height; | ||
144 | if (fontStruct()) | ||
145 | return fontStruct()->ascent + fontStruct()->descent; | ||
146 | |||
147 | return 0; | ||
148 | } | 122 | } |
149 | 123 | ||
150 | XFontSet Font::createFontSet(Display *display, const char *fontname) { | 124 | bool Font::load(const char *name) { |
151 | XFontSet fs; | 125 | if (name == 0) |
152 | const int FONT_ELEMENT_SIZE=50; | 126 | return false; |
153 | char **missing, *def = "-"; | 127 | bool ret_val = m_fontimp->load(name); |
154 | int nmissing, pixel_size = 0, buf_size = 0; | 128 | if (ret_val && name == 0) { //prevent from having a bad fontimp |
155 | char weight[FONT_ELEMENT_SIZE], slant[FONT_ELEMENT_SIZE]; | 129 | m_fontstr = name; // if the load really succeded then set font string |
156 | 130 | } else { | |
157 | fs = XCreateFontSet(display, | 131 | m_fontstr = ""; |
158 | fontname, &missing, &nmissing, &def); | ||
159 | if (fs && (! nmissing)) return fs; | ||
160 | |||
161 | #ifdef HAVE_SETLOCALE | ||
162 | if (! fs) { | ||
163 | if (nmissing) XFreeStringList(missing); | ||
164 | |||
165 | setlocale(LC_CTYPE, "C"); | ||
166 | fs = XCreateFontSet(display, fontname, | ||
167 | &missing, &nmissing, &def); | ||
168 | setlocale(LC_CTYPE, ""); | ||
169 | } | ||
170 | #endif // HAVE_SETLOCALE | ||
171 | |||
172 | if (fs) { | ||
173 | XFontStruct **fontstructs; | ||
174 | char **fontnames; | ||
175 | XFontsOfFontSet(fs, &fontstructs, &fontnames); | ||
176 | fontname = fontnames[0]; | ||
177 | } | 132 | } |
178 | 133 | ||
179 | getFontElement(fontname, weight, FONT_ELEMENT_SIZE, | 134 | return ret_val; |
180 | "-medium-", "-bold-", "-demibold-", "-regular-", 0); | ||
181 | getFontElement(fontname, slant, FONT_ELEMENT_SIZE, | ||
182 | "-r-", "-i-", "-o-", "-ri-", "-ro-", 0); | ||
183 | getFontSize(fontname, &pixel_size); | ||
184 | |||
185 | if (! strcmp(weight, "*")) | ||
186 | std::strncpy(weight, "medium", FONT_ELEMENT_SIZE); | ||
187 | if (! strcmp(slant, "*")) | ||
188 | std::strncpy(slant, "r", FONT_ELEMENT_SIZE); | ||
189 | if (pixel_size < 3) | ||
190 | pixel_size = 3; | ||
191 | else if (pixel_size > 97) | ||
192 | pixel_size = 97; | ||
193 | |||
194 | buf_size = strlen(fontname) + (FONT_ELEMENT_SIZE * 2) + 64; | ||
195 | char *pattern2 = new char[buf_size]; | ||
196 | snprintf(pattern2, buf_size - 1, | ||
197 | "%s," | ||
198 | "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*," | ||
199 | "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*,*", | ||
200 | fontname, weight, slant, pixel_size, pixel_size); | ||
201 | fontname = pattern2; | ||
202 | |||
203 | if (nmissing) | ||
204 | XFreeStringList(missing); | ||
205 | if (fs) | ||
206 | XFreeFontSet(display, fs); | ||
207 | |||
208 | fs = XCreateFontSet(display, fontname, | ||
209 | &missing, &nmissing, &def); | ||
210 | delete [] pattern2; | ||
211 | |||
212 | return fs; | ||
213 | } | 135 | } |
214 | 136 | ||
215 | const char *Font::getFontElement(const char *pattern, char *buf, int bufsiz, ...) { | 137 | unsigned int Font::textWidth(const char *text, unsigned int size) const { |
216 | const char *p, *v; | 138 | return m_fontimp->textWidth(text, size); |
217 | char *p2; | ||
218 | va_list va; | ||
219 | |||
220 | va_start(va, bufsiz); | ||
221 | buf[bufsiz-1] = 0; | ||
222 | buf[bufsiz-2] = '*'; | ||
223 | while((v = va_arg(va, char *)) != 0) { | ||
224 | p = StringUtil::strcasestr(pattern, v); | ||
225 | if (p) { | ||
226 | std::strncpy(buf, p+1, bufsiz-2); | ||
227 | p2 = strchr(buf, '-'); | ||
228 | if (p2) *p2=0; | ||
229 | va_end(va); | ||
230 | return p; | ||
231 | } | ||
232 | } | ||
233 | va_end(va); | ||
234 | std::strncpy(buf, "*", bufsiz); | ||
235 | return 0; | ||
236 | } | 139 | } |
237 | 140 | ||
238 | const char *Font::getFontSize(const char *pattern, int *size) { | 141 | unsigned int Font::height() const { |
239 | const char *p; | 142 | return m_fontimp->height(); |
240 | const char *p2=0; | ||
241 | int n=0; | ||
242 | |||
243 | for (p=pattern; 1; p++) { | ||
244 | if (!*p) { | ||
245 | if (p2!=0 && n>1 && n<72) { | ||
246 | *size = n; return p2+1; | ||
247 | } else { | ||
248 | *size = 16; return 0; | ||
249 | } | ||
250 | } else if (*p=='-') { | ||
251 | if (n>1 && n<72 && p2!=0) { | ||
252 | *size = n; | ||
253 | return p2+1; | ||
254 | } | ||
255 | p2=p; n=0; | ||
256 | } else if (*p>='0' && *p<='9' && p2!=0) { | ||
257 | n *= 10; | ||
258 | n += *p-'0'; | ||
259 | } else { | ||
260 | p2=0; n=0; | ||
261 | } | ||
262 | } | ||
263 | } | 143 | } |
264 | 144 | ||
265 | void Font::freeFont() { | 145 | void Font::drawText(Drawable w, int screen, GC gc, const char *text, size_t len, int x, int y) const { |
266 | //free memory | 146 | if (text == 0 || len == 0) |
267 | if (m_font.fontstruct!=0) | 147 | return; |
268 | XFreeFont(m_display, m_font.fontstruct); | 148 | m_fontimp->drawText(w, screen, gc, text, len, x, y); |
269 | if (m_font.set) | 149 | } |
270 | XFreeFontSet(m_display, m_font.set); | ||
271 | |||
272 | //clear struct | ||
273 | m_font.fontstruct = 0; | ||
274 | m_font.set = 0; | ||
275 | m_font.set_extents = 0; | ||
276 | |||
277 | m_loaded = false; //mark the font not loaded | ||
278 | } | ||
279 | 150 | ||
280 | }; | 151 | }; |
diff --git a/src/Font.hh b/src/Font.hh index 66cd6cf..0fa1b0e 100644 --- a/src/Font.hh +++ b/src/Font.hh | |||
@@ -19,7 +19,7 @@ | |||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. | 20 | // DEALINGS IN THE SOFTWARE. |
21 | 21 | ||
22 | //$Id: Font.hh,v 1.4 2002/08/04 15:55:13 fluxgen Exp $ | 22 | //$Id: Font.hh,v 1.5 2002/10/13 22:24:14 fluxgen Exp $ |
23 | 23 | ||
24 | #ifndef FBTK_FONT_HH | 24 | #ifndef FBTK_FONT_HH |
25 | #define FBTK_FONT_HH | 25 | #define FBTK_FONT_HH |
@@ -27,16 +27,19 @@ | |||
27 | #include <X11/Xlib.h> | 27 | #include <X11/Xlib.h> |
28 | #include <X11/Xresource.h> | 28 | #include <X11/Xresource.h> |
29 | 29 | ||
30 | namespace FbTk | 30 | #include <string> |
31 | { | 31 | #include <memory> |
32 | |||
33 | namespace FbTk { | ||
34 | |||
35 | class FontImp; | ||
32 | 36 | ||
33 | /** | 37 | /** |
34 | Handles loading of font. | 38 | Handles the client to fontimp bridge. |
35 | */ | 39 | */ |
36 | class Font | 40 | class Font { |
37 | { | ||
38 | public: | 41 | public: |
39 | Font(Display *display, const char *name=0); | 42 | Font(const char *name=0, bool antialias = false); |
40 | virtual ~Font(); | 43 | virtual ~Font(); |
41 | /** | 44 | /** |
42 | Load a font | 45 | Load a font |
@@ -44,23 +47,12 @@ public: | |||
44 | loaded font | 47 | loaded font |
45 | */ | 48 | */ |
46 | bool load(const char *name); | 49 | bool load(const char *name); |
47 | /** | 50 | |
48 | Loads a font from database | ||
49 | @return true on success, else false and it'll fall back on the last | ||
50 | loaded font | ||
51 | @see load(const char *name) | ||
52 | */ | ||
53 | bool loadFromDatabase(XrmDatabase &database, const char *rname, const char *rclass); | ||
54 | /// @return true if a font is loaded, else false | ||
55 | inline bool isLoaded() const { return m_loaded; } | ||
56 | /// @return XFontStruct of font, note: can be 0 | ||
57 | inline const XFontStruct *fontStruct() const { return m_font.fontstruct; } | ||
58 | /// @return XFontSet of font, note: check isLoaded | ||
59 | inline const XFontSet &fontSet() const { return m_font.set; } | ||
60 | /// @return XFontSetExtents of font, note: can be 0 | ||
61 | inline const XFontSetExtents *fontSetExtents() const { return m_font.set_extents; } | ||
62 | /// @return true if multibyte is enabled, else false | 51 | /// @return true if multibyte is enabled, else false |
63 | static inline bool multibyte() { return m_multibyte; } | 52 | static bool multibyte() { return m_multibyte; } |
53 | /// @return true if utf-8 mode is enabled, else false | ||
54 | static bool utf8() { return m_utf8mode; } | ||
55 | void setAntialias(bool flag); | ||
64 | /** | 56 | /** |
65 | @param text text to check size | 57 | @param text text to check size |
66 | @param size length of text in bytes | 58 | @param size length of text in bytes |
@@ -68,24 +60,13 @@ public: | |||
68 | */ | 60 | */ |
69 | unsigned int textWidth(const char *text, unsigned int size) const; | 61 | unsigned int textWidth(const char *text, unsigned int size) const; |
70 | unsigned int height() const; | 62 | unsigned int height() const; |
71 | /// @return display connection | 63 | void drawText(Drawable w, int screen, GC gc, const char *text, size_t len, int x, int y) const; |
72 | Display *display() const { return m_display; } | ||
73 | private: | 64 | private: |
74 | void freeFont(); | 65 | |
75 | static XFontSet createFontSet(Display *display, const char *fontname); | 66 | std::auto_ptr<FontImp> m_fontimp; |
76 | static const char *getFontSize(const char *pattern, int *size); | 67 | std::string m_fontstr; |
77 | static const char *getFontElement(const char *pattern, char *buf, int bufsiz, ...); | ||
78 | |||
79 | struct FontType | ||
80 | { | ||
81 | XFontSet set; | ||
82 | XFontSetExtents *set_extents; | ||
83 | XFontStruct *fontstruct; | ||
84 | } m_font; | ||
85 | |||
86 | bool m_loaded; | ||
87 | static bool m_multibyte; | 68 | static bool m_multibyte; |
88 | Display *m_display; | 69 | static bool m_utf8mode; |
89 | }; | 70 | }; |
90 | 71 | ||
91 | }; //end namespace FbTk | 72 | }; //end namespace FbTk |