]> git.saurik.com Git - wxWidgets.git/blame - src/unix/fontenum.cpp
Checked for stream validity in wxImage::GetImageCount.
[wxWidgets.git] / src / unix / fontenum.cpp
CommitLineData
d111a89a
VZ
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"
6fea4a7a 27#include "wx/regex.h"
d111a89a 28#include "wx/utils.h"
2b5f62a0 29#include "wx/app.h"
79e4b627 30#include "wx/fontmap.h"
d111a89a 31#include "wx/fontenum.h"
7beba2fc 32#include "wx/fontutil.h"
d111a89a 33
db16cab4 34// ----------------------------------------------------------------------------
2b5f62a0 35// Pango
db16cab4
RR
36// ----------------------------------------------------------------------------
37
2b5f62a0 38#if wxUSE_PANGO
db16cab4 39
2b5f62a0 40#include "pango/pango.h"
db16cab4 41
2b5f62a0
VZ
42#ifdef __WXGTK20__
43#include "gtk/gtk.h"
db16cab4 44extern GtkWidget *wxGetRootWindow();
2b5f62a0 45#endif
db16cab4
RR
46
47static int
48cmp_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
57bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
58 bool fixedWidthOnly)
59{
60 if ( fixedWidthOnly )
61 {
d0a6ad19 62 OnFacename( wxT("monospace") );
db16cab4
RR
63 }
64 else
65 {
66 PangoFontFamily **families = NULL;
67 gint n_families = 0;
68 pango_context_list_families (
2b5f62a0 69#ifdef __WXGTK20__
db16cab4 70 gtk_widget_get_pango_context( wxGetRootWindow() ),
2b5f62a0
VZ
71#else
72 wxTheApp->GetPangoContext(),
73#endif
db16cab4
RR
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
89bool wxFontEnumerator::EnumerateEncodings(const wxString& family)
90{
91 return FALSE;
92}
93
94
95#else
2b5f62a0 96 // Pango
db16cab4 97
3fa056ab
JJ
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
d111a89a 102#include <X11/Xlib.h>
3fa056ab
JJ
103#ifdef __VMS__
104#pragma message enable nosimpint
105#endif
d111a89a
VZ
106
107// ----------------------------------------------------------------------------
108// private functions
109// ----------------------------------------------------------------------------
110
36f210c8
VZ
111// create the list of all fonts with the given spacing and encoding
112static char **CreateFontList(wxChar spacing, wxFontEncoding encoding,
113 int *nFonts);
d111a89a
VZ
114
115// extract all font families from the given font list and call our
3c1866e8 116// OnFacename() for each of them
d111a89a
VZ
117static 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
461e93f9 134#if !wxUSE_NANOX
36f210c8
VZ
135static char **CreateFontList(wxChar spacing,
136 wxFontEncoding encoding,
137 int *nFonts)
d111a89a 138{
7beba2fc
VZ
139 wxNativeEncodingInfo info;
140 wxGetNativeFontEncoding(encoding, &info);
36f210c8 141
1e6feb95 142#if wxUSE_FONTMAP
79e4b627
VZ
143 if ( !wxTestFontEncoding(info) )
144 {
145 // ask font mapper for a replacement
142b3bc2 146 (void)wxFontMapper::Get()->GetAltForEncoding(encoding, &info);
79e4b627 147 }
1e6feb95 148#endif // wxUSE_FONTMAP
79e4b627 149
d111a89a 150 wxString pattern;
36f210c8 151 pattern.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-%c-*-%s-%s"),
7beba2fc
VZ
152 spacing,
153 info.xregistry.c_str(),
154 info.xencoding.c_str());
d111a89a
VZ
155
156 // get the list of all fonts
7dd62924 157 return XListFonts((Display *)wxGetDisplay(), pattern.mb_str(), 32767, nFonts);
d111a89a
VZ
158}
159
160static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
161 char **fonts,
162 int nFonts)
163{
f1d7cbac
VZ
164#if wxUSE_REGEX
165 wxRegEx re(wxT("^(-[^-]*){14}$"), wxRE_NOSUB);
166#endif // wxUSE_REGEX
167
d111a89a
VZ
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];
f1d7cbac 173#if wxUSE_REGEX
32a2fbc8 174 if ( !re.Matches(font) )
f1d7cbac 175#else // !wxUSE_REGEX
7dd62924 176 if ( !wxString(font).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
f1d7cbac 177#endif // wxUSE_REGEX/!wxUSE_REGEX
d111a89a
VZ
178 {
179 // it's not a full font name (probably an alias)
180 continue;
181 }
3c1866e8 182
d111a89a
VZ
183 char *dash = strchr(font + 1, '-');
184 char *family = dash + 1;
185 dash = strchr(family, '-');
186 *dash = '\0'; // !NULL because Matches() above succeeded
7dd62924 187 wxString fam(family);
d111a89a 188
7dd62924 189 if ( families.Index(fam) == wxNOT_FOUND )
d111a89a 190 {
3c1866e8 191 if ( !This->OnFacename(fam) )
d111a89a
VZ
192 {
193 // stop enumerating
194 return FALSE;
195 }
196
7dd62924 197 families.Add(fam);
d111a89a
VZ
198 }
199 //else: already seen
200 }
201
202 return TRUE;
203}
461e93f9
JS
204#endif
205 // wxUSE_NANOX
d111a89a
VZ
206
207// ----------------------------------------------------------------------------
208// wxFontEnumerator
209// ----------------------------------------------------------------------------
210
3c1866e8
VZ
211bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
212 bool fixedWidthOnly)
d111a89a 213{
461e93f9
JS
214#if wxUSE_NANOX
215 return FALSE;
216#else
d111a89a
VZ
217 int nFonts;
218 char **fonts;
219
220 if ( fixedWidthOnly )
221 {
222 bool cont = TRUE;
36f210c8 223 fonts = CreateFontList(wxT('m'), encoding, &nFonts);
d111a89a
VZ
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
36f210c8 236 fonts = CreateFontList(wxT('c'), encoding, &nFonts);
d111a89a
VZ
237 if ( !fonts )
238 {
239 return TRUE;
240 }
241 }
242 else
243 {
36f210c8 244 fonts = CreateFontList(wxT('*'), encoding, &nFonts);
d111a89a
VZ
245
246 if ( !fonts )
247 {
36f210c8
VZ
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?"));
d111a89a
VZ
252
253 return FALSE;
254 }
255 }
256
257 (void)ProcessFamiliesFromFontList(this, fonts, nFonts);
258
259 XFreeFontNames(fonts);
d111a89a 260 return TRUE;
461e93f9
JS
261#endif
262 // wxUSE_NANOX
d111a89a
VZ
263}
264
265bool wxFontEnumerator::EnumerateEncodings(const wxString& family)
266{
461e93f9
JS
267#if wxUSE_NANOX
268 return FALSE;
269#else
d111a89a
VZ
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;
7dd62924 276 char **fonts = XListFonts((Display *)wxGetDisplay(), pattern.mb_str(),
d111a89a
VZ
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];
7dd62924 290 if ( !wxString(font).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
d111a89a
VZ
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;
461e93f9
JS
334#endif
335 // wxUSE_NANOX
d111a89a 336}
db16cab4
RR
337
338#endif
339 // __WXGTK20__