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