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