]> git.saurik.com Git - wxWidgets.git/blob - src/unix/fontenum.cpp
added support for gcc precompiled headers
[wxWidgets.git] / src / unix / fontenum.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/unix/fontenum.cpp
3 // Purpose: wxFontEnumerator class for X11/GDK
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 01.10.99
7 // RCS-ID: $Id$
8 // Copyright: (c) Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "fontenum.h"
22 #endif
23
24 #include "wx/defs.h"
25 #include "wx/dynarray.h"
26 #include "wx/string.h"
27 #include "wx/regex.h"
28 #include "wx/utils.h"
29 #include "wx/app.h"
30 #include "wx/fontmap.h"
31 #include "wx/fontenum.h"
32 #include "wx/fontutil.h"
33
34 // ----------------------------------------------------------------------------
35 // Pango
36 // ----------------------------------------------------------------------------
37
38 #if wxUSE_PANGO
39
40 #include "pango/pango.h"
41
42 #ifdef __WXGTK20__
43 #include "gtk/gtk.h"
44 extern GtkWidget *wxGetRootWindow();
45 #endif
46
47 static int
48 cmp_families (const void *a, const void *b)
49 {
50 const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
51 const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
52
53 return g_utf8_collate (a_name, b_name);
54 }
55
56 // I admit I don't yet understand encodings with Pango
57 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
58 bool fixedWidthOnly)
59 {
60 if ( fixedWidthOnly )
61 {
62 OnFacename( wxT("monospace") );
63 }
64 else
65 {
66 PangoFontFamily **families = NULL;
67 gint n_families = 0;
68 pango_context_list_families (
69 #ifdef __WXGTK20__
70 gtk_widget_get_pango_context( wxGetRootWindow() ),
71 #else
72 wxTheApp->GetPangoContext(),
73 #endif
74 &families, &n_families );
75 qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
76
77 for (int i=0; i<n_families; i++)
78 {
79 const gchar *name = pango_font_family_get_name( families[i] );
80
81 wxString tmp( name, wxConvUTF8 );
82 OnFacename( tmp );
83 }
84 }
85
86 return TRUE;
87 }
88
89 bool wxFontEnumerator::EnumerateEncodings(const wxString& family)
90 {
91 return FALSE;
92 }
93
94
95 #else
96 // Pango
97
98 #ifdef __VMS__ // Xlib.h for VMS is not (yet) compatible with C++
99 // The resulting warnings are switched off here
100 #pragma message disable nosimpint
101 #endif
102 #include <X11/Xlib.h>
103 #ifdef __VMS__
104 #pragma message enable nosimpint
105 #endif
106
107 // ----------------------------------------------------------------------------
108 // private functions
109 // ----------------------------------------------------------------------------
110
111 // create the list of all fonts with the given spacing and encoding
112 static char **CreateFontList(wxChar spacing, wxFontEncoding encoding,
113 int *nFonts);
114
115 // extract all font families from the given font list and call our
116 // OnFacename() for each of them
117 static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
118 char **fonts,
119 int nFonts);
120
121
122 // ----------------------------------------------------------------------------
123 // private types
124 // ----------------------------------------------------------------------------
125
126 // ============================================================================
127 // implementation
128 // ============================================================================
129
130 // ----------------------------------------------------------------------------
131 // helpers
132 // ----------------------------------------------------------------------------
133
134 #if !wxUSE_NANOX
135 static char **CreateFontList(wxChar spacing,
136 wxFontEncoding encoding,
137 int *nFonts)
138 {
139 wxNativeEncodingInfo info;
140 wxGetNativeFontEncoding(encoding, &info);
141
142 #if wxUSE_FONTMAP
143 if ( !wxTestFontEncoding(info) )
144 {
145 // ask font mapper for a replacement
146 (void)wxFontMapper::Get()->GetAltForEncoding(encoding, &info);
147 }
148 #endif // wxUSE_FONTMAP
149
150 wxString pattern;
151 pattern.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-%c-*-%s-%s"),
152 spacing,
153 info.xregistry.c_str(),
154 info.xencoding.c_str());
155
156 // get the list of all fonts
157 return XListFonts((Display *)wxGetDisplay(), pattern.mb_str(), 32767, nFonts);
158 }
159
160 static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
161 char **fonts,
162 int nFonts)
163 {
164 #if wxUSE_REGEX
165 wxRegEx re(wxT("^(-[^-]*){14}$"), wxRE_NOSUB);
166 #endif // wxUSE_REGEX
167
168 // extract the list of (unique) font families
169 wxSortedArrayString families;
170 for ( int n = 0; n < nFonts; n++ )
171 {
172 char *font = fonts[n];
173 #if wxUSE_REGEX
174 if ( !re.Matches(font) )
175 #else // !wxUSE_REGEX
176 if ( !wxString(font).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
177 #endif // wxUSE_REGEX/!wxUSE_REGEX
178 {
179 // it's not a full font name (probably an alias)
180 continue;
181 }
182
183 char *dash = strchr(font + 1, '-');
184 char *family = dash + 1;
185 dash = strchr(family, '-');
186 *dash = '\0'; // !NULL because Matches() above succeeded
187 wxString fam(family);
188
189 if ( families.Index(fam) == wxNOT_FOUND )
190 {
191 if ( !This->OnFacename(fam) )
192 {
193 // stop enumerating
194 return FALSE;
195 }
196
197 families.Add(fam);
198 }
199 //else: already seen
200 }
201
202 return TRUE;
203 }
204 #endif
205 // wxUSE_NANOX
206
207 // ----------------------------------------------------------------------------
208 // wxFontEnumerator
209 // ----------------------------------------------------------------------------
210
211 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
212 bool fixedWidthOnly)
213 {
214 #if wxUSE_NANOX
215 return FALSE;
216 #else
217 int nFonts;
218 char **fonts;
219
220 if ( fixedWidthOnly )
221 {
222 bool cont = TRUE;
223 fonts = CreateFontList(wxT('m'), encoding, &nFonts);
224 if ( fonts )
225 {
226 cont = ProcessFamiliesFromFontList(this, fonts, nFonts);
227
228 XFreeFontNames(fonts);
229 }
230
231 if ( !cont )
232 {
233 return TRUE;
234 }
235
236 fonts = CreateFontList(wxT('c'), encoding, &nFonts);
237 if ( !fonts )
238 {
239 return TRUE;
240 }
241 }
242 else
243 {
244 fonts = CreateFontList(wxT('*'), encoding, &nFonts);
245
246 if ( !fonts )
247 {
248 // it's ok if there are no fonts in given encoding - but it's not
249 // ok if there are no fonts at all
250 wxASSERT_MSG(encoding != wxFONTENCODING_SYSTEM,
251 wxT("No fonts at all on this system?"));
252
253 return FALSE;
254 }
255 }
256
257 (void)ProcessFamiliesFromFontList(this, fonts, nFonts);
258
259 XFreeFontNames(fonts);
260 return TRUE;
261 #endif
262 // wxUSE_NANOX
263 }
264
265 bool wxFontEnumerator::EnumerateEncodings(const wxString& family)
266 {
267 #if wxUSE_NANOX
268 return FALSE;
269 #else
270 wxString pattern;
271 pattern.Printf(wxT("-*-%s-*-*-*-*-*-*-*-*-*-*-*-*"),
272 family.IsEmpty() ? wxT("*") : family.c_str());
273
274 // get the list of all fonts
275 int nFonts;
276 char **fonts = XListFonts((Display *)wxGetDisplay(), pattern.mb_str(),
277 32767, &nFonts);
278
279 if ( !fonts )
280 {
281 // unknown family?
282 return FALSE;
283 }
284
285 // extract the list of (unique) encodings
286 wxSortedArrayString encodings;
287 for ( int n = 0; n < nFonts; n++ )
288 {
289 char *font = fonts[n];
290 if ( !wxString(font).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
291 {
292 // it's not a full font name (probably an alias)
293 continue;
294 }
295
296 // extract the family
297 char *dash = strchr(font + 1, '-');
298 char *familyFont = dash + 1;
299 dash = strchr(familyFont, '-');
300 *dash = '\0'; // !NULL because Matches() above succeeded
301
302 if ( !family.IsEmpty() && (family != familyFont) )
303 {
304 // family doesn't match
305 continue;
306 }
307
308 // now extract the registry/encoding
309 char *p = dash + 1; // just after the dash after family
310 dash = strrchr(p, '-');
311
312 wxString registry(dash + 1);
313 *dash = '\0';
314
315 dash = strrchr(p, '-');
316 wxString encoding(dash + 1);
317
318 encoding << wxT('-') << registry;
319 if ( encodings.Index(encoding) == wxNOT_FOUND )
320 {
321 if ( !OnFontEncoding(familyFont, encoding) )
322 {
323 break;
324 }
325
326 encodings.Add(encoding);
327 }
328 //else: already had this one
329 }
330
331 XFreeFontNames(fonts);
332
333 return TRUE;
334 #endif
335 // wxUSE_NANOX
336 }
337
338 #endif
339 // __WXGTK20__