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