aboutsummaryrefslogtreecommitdiff
path: root/src/XmbFontImp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/XmbFontImp.cc')
-rw-r--r--src/XmbFontImp.cc225
1 files changed, 225 insertions, 0 deletions
diff --git a/src/XmbFontImp.cc b/src/XmbFontImp.cc
new file mode 100644
index 0000000..b39e463
--- /dev/null
+++ b/src/XmbFontImp.cc
@@ -0,0 +1,225 @@
1// XmbFontImp.cc for FbTk fluxbox toolkit
2// Copyright (c) 2002 Henrik Kinnunen (fluxgen@linuxmail.org)
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.1 2002/10/13 22:22:14 fluxgen Exp $
23
24#include "XmbFontImp.hh"
25
26#include "BaseDisplay.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#include <cstdarg>
38
39namespace {
40
41const char *getFontSize(const char *pattern, int *size) {
42 const char *p;
43 const char *p2=0;
44 int n=0;
45
46 for (p=pattern; 1; p++) {
47 if (!*p) {
48 if (p2!=0 && n>1 && n<72) {
49 *size = n; return p2+1;
50 } else {
51 *size = 16; return 0;
52 }
53 } else if (*p=='-') {
54 if (n>1 && n<72 && p2!=0) {
55 *size = n;
56 return p2+1;
57 }
58 p2=p; n=0;
59 } else if (*p>='0' && *p<='9' && p2!=0) {
60 n *= 10;
61 n += *p-'0';
62 } else {
63 p2=0; n=0;
64 }
65 }
66}
67
68const char *getFontElement(const char *pattern, char *buf, int bufsiz, ...) {
69 const char *p, *v;
70 char *p2;
71 va_list va;
72
73 va_start(va, bufsiz);
74 buf[bufsiz-1] = 0;
75 buf[bufsiz-2] = '*';
76 while((v = va_arg(va, char *)) != 0) {
77 p = StringUtil::strcasestr(pattern, v);
78 if (p) {
79 std::strncpy(buf, p+1, bufsiz-2);
80 p2 = strchr(buf, '-');
81 if (p2) *p2=0;
82 va_end(va);
83 return p;
84 }
85 }
86 va_end(va);
87 std::strncpy(buf, "*", bufsiz);
88 return 0;
89}
90
91XFontSet createFontSet(const char *fontname) {
92 Display *display = BaseDisplay::getXDisplay();
93 XFontSet fs;
94 const int FONT_ELEMENT_SIZE=50;
95 char **missing, *def = "-";
96 int nmissing, pixel_size = 0, buf_size = 0;
97 char weight[FONT_ELEMENT_SIZE], slant[FONT_ELEMENT_SIZE];
98
99 fs = XCreateFontSet(display,
100 fontname, &missing, &nmissing, &def);
101 if (fs && (! nmissing)) return fs;
102
103#ifdef HAVE_SETLOCALE
104 if (! fs) {
105 if (nmissing) XFreeStringList(missing);
106
107 setlocale(LC_CTYPE, "C");
108 fs = XCreateFontSet(display, fontname,
109 &missing, &nmissing, &def);
110 setlocale(LC_CTYPE, "");
111 }
112#endif // HAVE_SETLOCALE
113
114 if (fs) {
115 XFontStruct **fontstructs;
116 char **fontnames;
117 XFontsOfFontSet(fs, &fontstructs, &fontnames);
118 fontname = fontnames[0];
119 }
120
121 getFontElement(fontname, weight, FONT_ELEMENT_SIZE,
122 "-medium-", "-bold-", "-demibold-", "-regular-", 0);
123 getFontElement(fontname, slant, FONT_ELEMENT_SIZE,
124 "-r-", "-i-", "-o-", "-ri-", "-ro-", 0);
125 getFontSize(fontname, &pixel_size);
126
127 if (! strcmp(weight, "*"))
128 std::strncpy(weight, "medium", FONT_ELEMENT_SIZE);
129 if (! strcmp(slant, "*"))
130 std::strncpy(slant, "r", FONT_ELEMENT_SIZE);
131 if (pixel_size < 3)
132 pixel_size = 3;
133 else if (pixel_size > 97)
134 pixel_size = 97;
135
136 buf_size = strlen(fontname) + (FONT_ELEMENT_SIZE * 2) + 64;
137 char *pattern2 = new char[buf_size];
138 snprintf(pattern2, buf_size - 1,
139 "%s,"
140 "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*,"
141 "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*,*",
142 fontname, weight, slant, pixel_size, pixel_size);
143 fontname = pattern2;
144
145 if (nmissing)
146 XFreeStringList(missing);
147 if (fs)
148 XFreeFontSet(display, fs);
149
150 fs = XCreateFontSet(display, fontname,
151 &missing, &nmissing, &def);
152 delete [] pattern2;
153
154 return fs;
155}
156
157};
158
159XmbFontImp::XmbFontImp(const char *filename, bool utf8):m_fontset(0), m_utf8mode(utf8) {
160 if (filename != 0)
161 load(filename);
162}
163
164XmbFontImp::~XmbFontImp() {
165 if (m_fontset != 0)
166 XFreeFontSet(BaseDisplay::getXDisplay(), m_fontset);
167}
168
169bool XmbFontImp::load(const std::string &fontname) {
170 if (fontname.size() == 0)
171 return false;
172 XFontSet set = createFontSet(fontname.c_str());
173 if (set == 0)
174 return false;
175 if (m_fontset != 0)
176 XFreeFontSet(BaseDisplay::getXDisplay(), m_fontset);
177 m_fontset = set;
178 m_setextents = XExtentsOfFontSet(m_fontset);
179
180 return true;
181}
182
183void XmbFontImp::drawText(Drawable w, int screen, GC gc, const char *text,
184 size_t len, int x, int y) const {
185
186 if (text == 0 || len == 0 || w == 0 || m_fontset == 0)
187 return;
188#ifdef X_HAVE_UTF8_STRING
189 if (m_utf8mode) {
190 Xutf8DrawString(BaseDisplay::getXDisplay(), w, m_fontset,
191 gc, x, y,
192 text, len);
193 } else
194#endif //X_HAVE_UTF8_STRING
195 {
196 XmbDrawString(BaseDisplay::getXDisplay(), w, m_fontset,
197 gc, x, y,
198 text, len);
199 }
200}
201
202unsigned int XmbFontImp::textWidth(const char *text, unsigned int len) const {
203 if (m_fontset == 0)
204 return 0;
205 XRectangle ink, logical;
206#ifdef X_HAVE_UTF8_STRING
207 if (m_utf8mode) {
208 Xutf8TextExtents(m_fontset, text, len,
209 &ink, &logical);
210 } else
211#endif // X_HAVE_UTF8_STRING
212 {
213 XmbTextExtents(m_fontset, text, len,
214 &ink, &logical);
215 }
216
217 return logical.width;
218}
219
220unsigned int XmbFontImp::height() const {
221 if (m_fontset == 0)
222 return 0;
223 return m_setextents->max_ink_extent.height;
224}
225