1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
|
//
// "$Id: fl_font_xft.cxx,v 1.4.2.7 2002/06/08 13:07:19 easysw Exp $"
//
// Xft font code for the Fast Light Tool Kit (FLTK).
//
// Copyright 2001-2002 Bill Spitzak and others.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems to "fltk-bugs@fltk.org".
//
//
// Draw fonts using Keith Packard's Xft library to provide anti-
// aliased text. Yow!
//
// Many thanks to Carl for making the original version of this.
//
// This font code only requires libXft to work. Contrary to popular
// belief there is no need to have FreeType, or the Xrender extension
// available to use this code. You will just get normal Xlib fonts
// (Xft calls them "core" fonts) The Xft algorithms for choosing
// these is about as good as the FLTK ones (I hope to fix it so it is
// exactly as good...), plus it can cache it's results and share them
// between programs, so using this should be a win in all cases. Also
// it should be obvious by comparing this file and fl_font_x.cxx that
// it is a lot easier to program with Xft than with Xlib.
//
// Also, Xft supports UTF-8 text rendering directly, which will allow
// us to support UTF-8 on all platforms more easily.
//
// To actually get antialiasing you need the following:
//
// 1. You have XFree86 4
// 2. You have the XRender extension
// 3. Your X device driver supports the render extension
// 4. You have libXft
// 5. Your libXft has FreeType2 support compiled in
// 6. You have the FreeType2 library
//
// Distributions that have XFree86 4.0.3 or later should have all of this...
//
// Unlike some other Xft packages, I tried to keep this simple and not
// to work around the current problems in Xft by making the "patterns"
// complicated. I belive doing this defeats our ability to improve Xft
// itself. You should edit the ~/.xftconfig file to "fix" things, there
// are several web pages of information on how to do this.
//
#include <X11/Xft/Xft.h>
// The predefined fonts that FLTK has:
static Fl_Fontdesc built_in_table[] = {
{" sans"},
{"Bsans"},
{"Isans"},
{"Psans"},
{" mono"},
{"Bmono"},
{"Imono"},
{"Pmono"},
{" serif"},
{"Bserif"},
{"Iserif"},
{"Pserif"},
{" symbol"},
{" screen"},
{"Bscreen"},
{" dingbats"},
};
Fl_Fontdesc* fl_fonts = built_in_table;
#define current_font (fl_fontsize->font)
int fl_font_ = 0;
int fl_size_ = 0;
XFontStruct* fl_xfont = 0;
const char* fl_encoding_ = "iso8859-1";
Fl_FontSize* fl_fontsize = 0;
void fl_font(int fnum, int size) {
if (fnum == fl_font_ && size == fl_size_ &&
!strcasecmp(fl_fontsize->encoding, fl_encoding_))
return;
fl_font_ = fnum; fl_size_ = size;
Fl_Fontdesc *font = fl_fonts + fnum;
Fl_FontSize* f;
// search the fontsizes we have generated already
for (f = font->first; f; f = f->next) {
if (f->size == size && !strcasecmp(f->encoding, fl_encoding_))
break;
}
if (!f) {
f = new Fl_FontSize(font->name);
f->next = font->first;
font->first = f;
}
fl_fontsize = f;
fl_xfont = f->font->u.core.font;
}
static XftFont* fontopen(const char* name, bool core) {
fl_open_display();
int slant = XFT_SLANT_ROMAN;
int weight = XFT_WEIGHT_MEDIUM;
// may be efficient, but this is non-obvious
switch (*name++) {
case 'I': slant = XFT_SLANT_ITALIC; break;
case 'P': slant = XFT_SLANT_ITALIC;
case 'B': weight = XFT_WEIGHT_BOLD; break;
case ' ': break;
default: name--;
}
// this call is extremely slow...
return XftFontOpen(fl_display, fl_screen,
XFT_FAMILY, XftTypeString, name,
XFT_WEIGHT, XftTypeInteger, weight,
XFT_SLANT, XftTypeInteger, slant,
XFT_ENCODING, XftTypeString, fl_encoding_,
XFT_PIXEL_SIZE, XftTypeDouble, (double)fl_size_,
core ? XFT_CORE : 0, XftTypeBool, true,
XFT_RENDER, XftTypeBool, false,
0);
}
Fl_FontSize::Fl_FontSize(const char* name) {
encoding = fl_encoding_;
size = fl_size_;
font = fontopen(name, false);
}
Fl_FontSize::~Fl_FontSize() {
if (this == fl_fontsize) fl_fontsize = 0;
// XftFontClose(fl_display, font);
}
int fl_height() { return current_font->ascent + current_font->descent; }
int fl_descent() { return current_font->descent; }
double fl_width(const char *str, int n) {
XGlyphInfo i;
XftTextExtents8(fl_display, current_font, (XftChar8 *)str, n, &i);
return i.xOff;
}
double fl_width(uchar c) {
return fl_width((const char *)(&c), 1);
}
#if USE_OVERLAY
// Currently Xft does not work with colormapped visuals, so this probably
// does not work unless you have a true-color overlay.
extern bool fl_overlay;
extern Colormap fl_overlay_colormap;
extern XVisualInfo* fl_overlay_visual;
#endif
// For some reason Xft produces errors if you destroy a window whose id
// still exists in an XftDraw structure. It would be nice if this is not
// true, a lot of junk is needed to try to stop this:
static XftDraw* draw;
static Window draw_window;
#if USE_OVERLAY
static XftDraw* draw_overlay;
static Window draw_overlay_window;
#endif
void fl_destroy_xft_draw(Window id) {
if (id == draw_window)
XftDrawChange(draw, draw_window = fl_message_window);
#if USE_OVERLAY
if (id == draw_overlay_window)
XftDrawChange(draw_overlay, draw_overlay_window = fl_message_window);
#endif
}
void fl_draw(const char *str, int n, int x, int y) {
#if USE_OVERLAY
XftDraw*& draw = fl_overlay ? draw_overlay : ::draw;
if (fl_overlay) {
if (!draw)
draw = XftDrawCreate(fl_display, draw_overlay_window = fl_window,
fl_overlay_visual->visual, fl_overlay_colormap);
else //if (draw_overlay_window != fl_window)
XftDrawChange(draw, draw_overlay_window = fl_window);
} else
#endif
if (!draw)
draw = XftDrawCreate(fl_display, draw_window = fl_window,
fl_visual->visual, fl_colormap);
else //if (draw_window != fl_window)
XftDrawChange(draw, draw_window = fl_window);
Region region = fl_clip_region();
if (region) {
if (XEmptyRegion(region)) return;
XftDrawSetClip(draw, region);
}
// Use fltk's color allocator, copy the results to match what
// XftCollorAllocValue returns:
XftColor color;
color.pixel = fl_xpixel(fl_color_);
uchar r,g,b; Fl::get_color(fl_color_, r,g,b);
color.color.red = ((int)r)*0x101;
color.color.green = ((int)g)*0x101;
color.color.blue = ((int)b)*0x101;
color.color.alpha = 0xffff;
XftDrawString8(draw, &color, current_font, x, y, (XftChar8 *)str, n);
}
//
// End of "$Id: fl_font_xft.cxx,v 1.4.2.7 2002/06/08 13:07:19 easysw Exp $"
//
|