aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/XmbFontImp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk/XmbFontImp.cc')
-rw-r--r--src/FbTk/XmbFontImp.cc263
1 files changed, 263 insertions, 0 deletions
diff --git a/src/FbTk/XmbFontImp.cc b/src/FbTk/XmbFontImp.cc
new file mode 100644
index 0000000..6a3ffed
--- /dev/null
+++ b/src/FbTk/XmbFontImp.cc
@@ -0,0 +1,263 @@
1// XmbFontImp.cc for FbTk fluxbox toolkit
2// Copyright (c) 2002-2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22// $Id: XmbFontImp.cc,v 1.6 2003/04/26 18:57:51 fluxgen Exp $
23
24#include "XmbFontImp.hh"
25
26#include "App.hh"
27#include "StringUtil.hh"
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif //HAVE_CONFIG_H
32
33#ifdef HAVE_SETLOCALE
34#include <locale.h>
35#endif // HAVE_SETLOCALE
36
37#ifndef _GNU_SOURCE
38#define _GNU_SOURCE
39#endif // _GNU_SOURCE
40
41#include <cstdio>
42#include <cstdarg>
43#include <iostream>
44#include <cstring>
45
46using namespace std;
47
48namespace {
49
50#ifndef HAVE_STRCASESTR
51//!! TODO this is moved to StringUtil
52// Tries to find a string in another and
53// ignoring the case of the characters
54// Returns 0 on success else pointer to str.
55const char *strcasestr(const char *str, const char *ptn) {
56 const char *s2, *p2;
57 for( ; *str; str++) {
58 for(s2=str, p2=ptn; ; s2++,p2++) {
59 // check if we reached the end of ptn, if so, return str
60 if (!*p2) return str;
61 // check if the chars match(ignoring case)
62 if (toupper(*s2) != toupper(*p2)) break;
63 }
64 }
65 return 0;
66}
67#endif //HAVE_STRCASESTR
68
69const char *getFontSize(const char *pattern, int *size) {
70 const char *p;
71 const char *p2=0;
72 int n=0;
73
74 for (p=pattern; 1; p++) {
75 if (!*p) {
76 if (p2!=0 && n>1 && n<72) {
77 *size = n; return p2+1;
78 } else {
79 *size = 16; return 0;
80 }
81 } else if (*p=='-') {
82 if (n>1 && n<72 && p2!=0) {
83 *size = n;
84 return p2+1;
85 }
86 p2=p; n=0;
87 } else if (*p>='0' && *p<='9' && p2!=0) {
88 n *= 10;
89 n += *p-'0';
90 } else {
91 p2=0; n=0;
92 }
93 }
94}
95
96const char *getFontElement(const char *pattern, char *buf, int bufsiz, ...) {
97 const char *p, *v;
98 char *p2;
99 va_list va;
100
101 va_start(va, bufsiz);
102 buf[bufsiz-1] = 0;
103 buf[bufsiz-2] = '*';
104 while((v = va_arg(va, char *)) != 0) {
105 p = FbTk::StringUtil::strcasestr(pattern, v);
106 if (p) {
107 std::strncpy(buf, p+1, bufsiz-2);
108 p2 = strchr(buf, '-');
109 if (p2) *p2=0;
110 va_end(va);
111 return p;
112 }
113 }
114 va_end(va);
115 std::strncpy(buf, "*", bufsiz);
116 return 0;
117}
118
119XFontSet createFontSet(const char *fontname) {
120 Display *display = FbTk::App::instance()->display();
121 XFontSet fs;
122 const int FONT_ELEMENT_SIZE=50;
123 char **missing, *def = "-";
124 int nmissing, pixel_size = 0, buf_size = 0;
125 char weight[FONT_ELEMENT_SIZE], slant[FONT_ELEMENT_SIZE];
126
127 fs = XCreateFontSet(display,
128 fontname, &missing, &nmissing, &def);
129 if (fs && (! nmissing)) return fs;
130
131#ifdef HAVE_SETLOCALE
132 if (! fs) {
133 if (nmissing) XFreeStringList(missing);
134
135 setlocale(LC_CTYPE, "C");
136 fs = XCreateFontSet(display, fontname,
137 &missing, &nmissing, &def);
138 setlocale(LC_CTYPE, "");
139 }
140#endif // HAVE_SETLOCALE
141
142 if (fs) {
143 XFontStruct **fontstructs;
144 char **fontnames;
145 XFontsOfFontSet(fs, &fontstructs, &fontnames);
146 fontname = fontnames[0];
147 }
148
149 getFontElement(fontname, weight, FONT_ELEMENT_SIZE,
150 "-medium-", "-bold-", "-demibold-", "-regular-", 0);
151 getFontElement(fontname, slant, FONT_ELEMENT_SIZE,
152 "-r-", "-i-", "-o-", "-ri-", "-ro-", 0);
153 getFontSize(fontname, &pixel_size);
154
155 if (! strcmp(weight, "*"))
156 std::strncpy(weight, "medium", FONT_ELEMENT_SIZE);
157 if (! strcmp(slant, "*"))
158 std::strncpy(slant, "r", FONT_ELEMENT_SIZE);
159 if (pixel_size < 3)
160 pixel_size = 3;
161 else if (pixel_size > 97)
162 pixel_size = 97;
163
164 buf_size = strlen(fontname) + (FONT_ELEMENT_SIZE * 2) + 64;
165 char *pattern2 = new char[buf_size];
166 snprintf(pattern2, buf_size - 1,
167 "%s,"
168 "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*,"
169 "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*,*",
170 fontname, weight, slant, pixel_size, pixel_size);
171 fontname = pattern2;
172
173 if (nmissing)
174 XFreeStringList(missing);
175 if (fs)
176 XFreeFontSet(display, fs);
177
178 fs = XCreateFontSet(display, fontname,
179 &missing, &nmissing, &def);
180 delete [] pattern2;
181
182 return fs;
183}
184
185};
186namespace FbTk {
187
188XmbFontImp::XmbFontImp(const char *filename, bool utf8):m_fontset(0), m_utf8mode(utf8) {
189#ifdef DEBUG
190#ifdef X_HAVE_UTF8_STRING
191 cerr<<"Using utf8 = "<<utf8<<endl;
192#else // X_HAVE_UTF8_STRING
193 cerr<<"Using uft8 = false"<<endl;
194#endif //X_HAVE_UTF8_STRING
195#endif // DEBUG
196 if (filename != 0)
197 load(filename);
198}
199
200XmbFontImp::~XmbFontImp() {
201 if (m_fontset != 0)
202 XFreeFontSet(App::instance()->display(), m_fontset);
203}
204
205bool XmbFontImp::load(const std::string &fontname) {
206 if (fontname.size() == 0)
207 return false;
208 XFontSet set = createFontSet(fontname.c_str());
209 if (set == 0)
210 return false;
211 if (m_fontset != 0)
212 XFreeFontSet(App::instance()->display(), m_fontset);
213 m_fontset = set;
214 m_setextents = XExtentsOfFontSet(m_fontset);
215
216 return true;
217}
218
219void XmbFontImp::drawText(Drawable w, int screen, GC gc, const char *text,
220 size_t len, int x, int y) const {
221
222 if (text == 0 || len == 0 || w == 0 || m_fontset == 0)
223 return;
224#ifdef X_HAVE_UTF8_STRING
225 if (m_utf8mode) {
226 Xutf8DrawString(App::instance()->display(), w, m_fontset,
227 gc, x, y,
228 text, len);
229 } else
230#endif //X_HAVE_UTF8_STRING
231 {
232 XmbDrawString(App::instance()->display(), w, m_fontset,
233 gc, x, y,
234 text, len);
235 }
236}
237
238unsigned int XmbFontImp::textWidth(const char * const text, unsigned int len) const {
239 if (m_fontset == 0)
240 return 0;
241 XRectangle ink, logical;
242#ifdef X_HAVE_UTF8_STRING
243 if (m_utf8mode) {
244 Xutf8TextExtents(m_fontset, text, len,
245 &ink, &logical);
246 } else
247#endif // X_HAVE_UTF8_STRING
248 {
249 XmbTextExtents(m_fontset, text, len,
250 &ink, &logical);
251 }
252
253 return logical.width;
254}
255
256unsigned int XmbFontImp::height() const {
257 if (m_fontset == 0)
258 return 0;
259 return m_setextents->max_ink_extent.height;
260}
261
262}; // end namespace FbTk
263