aboutsummaryrefslogtreecommitdiff
path: root/src/XmbFontImp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/XmbFontImp.cc')
-rw-r--r--src/XmbFontImp.cc239
1 files changed, 239 insertions, 0 deletions
diff --git a/src/XmbFontImp.cc b/src/XmbFontImp.cc
new file mode 100644
index 0000000..2a80900
--- /dev/null
+++ b/src/XmbFontImp.cc
@@ -0,0 +1,239 @@
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.3 2002/10/24 11:40:36 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#ifndef _GNU_SOURCE
38#define _GNU_SOURCE
39#endif // _GNU_SOURCE
40
41#include <cstdio>
42#include <cstdarg>
43#include <iostream>
44using namespace std;
45
46namespace {
47
48const char *getFontSize(const char *pattern, int *size) {
49 const char *p;
50 const char *p2=0;
51 int n=0;
52
53 for (p=pattern; 1; p++) {
54 if (!*p) {
55 if (p2!=0 && n>1 && n<72) {
56 *size = n; return p2+1;
57 } else {
58 *size = 16; return 0;
59 }
60 } else if (*p=='-') {
61 if (n>1 && n<72 && p2!=0) {
62 *size = n;
63 return p2+1;
64 }
65 p2=p; n=0;
66 } else if (*p>='0' && *p<='9' && p2!=0) {
67 n *= 10;
68 n += *p-'0';
69 } else {
70 p2=0; n=0;
71 }
72 }
73}
74
75const char *getFontElement(const char *pattern, char *buf, int bufsiz, ...) {
76 const char *p, *v;
77 char *p2;
78 va_list va;
79
80 va_start(va, bufsiz);
81 buf[bufsiz-1] = 0;
82 buf[bufsiz-2] = '*';
83 while((v = va_arg(va, char *)) != 0) {
84 p = StringUtil::strcasestr(pattern, v);
85 if (p) {
86 std::strncpy(buf, p+1, bufsiz-2);
87 p2 = strchr(buf, '-');
88 if (p2) *p2=0;
89 va_end(va);
90 return p;
91 }
92 }
93 va_end(va);
94 std::strncpy(buf, "*", bufsiz);
95 return 0;
96}
97
98XFontSet createFontSet(const char *fontname) {
99 Display *display = BaseDisplay::getXDisplay();
100 XFontSet fs;
101 const int FONT_ELEMENT_SIZE=50;
102 char **missing, *def = "-";
103 int nmissing, pixel_size = 0, buf_size = 0;
104 char weight[FONT_ELEMENT_SIZE], slant[FONT_ELEMENT_SIZE];
105
106 fs = XCreateFontSet(display,
107 fontname, &missing, &nmissing, &def);
108 if (fs && (! nmissing)) return fs;
109
110#ifdef HAVE_SETLOCALE
111 if (! fs) {
112 if (nmissing) XFreeStringList(missing);
113
114 setlocale(LC_CTYPE, "C");
115 fs = XCreateFontSet(display, fontname,
116 &missing, &nmissing, &def);
117 setlocale(LC_CTYPE, "");
118 }
119#endif // HAVE_SETLOCALE
120
121 if (fs) {
122 XFontStruct **fontstructs;
123 char **fontnames;
124 XFontsOfFontSet(fs, &fontstructs, &fontnames);
125 fontname = fontnames[0];
126 }
127
128 getFontElement(fontname, weight, FONT_ELEMENT_SIZE,
129 "-medium-", "-bold-", "-demibold-", "-regular-", 0);
130 getFontElement(fontname, slant, FONT_ELEMENT_SIZE,
131 "-r-", "-i-", "-o-", "-ri-", "-ro-", 0);
132 getFontSize(fontname, &pixel_size);
133
134 if (! strcmp(weight, "*"))
135 std::strncpy(weight, "medium", FONT_ELEMENT_SIZE);
136 if (! strcmp(slant, "*"))
137 std::strncpy(slant, "r", FONT_ELEMENT_SIZE);
138 if (pixel_size < 3)
139 pixel_size = 3;
140 else if (pixel_size > 97)
141 pixel_size = 97;
142
143 buf_size = strlen(fontname) + (FONT_ELEMENT_SIZE * 2) + 64;
144 char *pattern2 = new char[buf_size];
145 snprintf(pattern2, buf_size - 1,
146 "%s,"
147 "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*,"
148 "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*,*",
149 fontname, weight, slant, pixel_size, pixel_size);
150 fontname = pattern2;
151
152 if (nmissing)
153 XFreeStringList(missing);
154 if (fs)
155 XFreeFontSet(display, fs);
156
157 fs = XCreateFontSet(display, fontname,
158 &missing, &nmissing, &def);
159 delete [] pattern2;
160
161 return fs;
162}
163
164};
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(BaseDisplay::getXDisplay(), 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(BaseDisplay::getXDisplay(), 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(BaseDisplay::getXDisplay(), w, m_fontset,
205 gc, x, y,
206 text, len);
207 } else
208#endif //X_HAVE_UTF8_STRING
209 {
210 XmbDrawString(BaseDisplay::getXDisplay(), 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