1
/////////////////////////////////////////////////////////////////////////////
2
// Name: src/unix/fontenum.cpp
3
// Purpose: wxFontEnumerator class for X11/GDK
4
// Author: Vadim Zeitlin
7
// Copyright: (c) Vadim Zeitlin
8
// Licence: wxWindows licence
9
/////////////////////////////////////////////////////////////////////////////
11
// ============================================================================
13
// ============================================================================
15
// ----------------------------------------------------------------------------
17
// ----------------------------------------------------------------------------
19
// for compilers that support precompilation, includes "wx.h".
20
#include "wx/wxprec.h"
24
#include "wx/fontenum.h"
27
#include "wx/dynarray.h"
28
#include "wx/string.h"
34
#include "wx/fontmap.h"
35
#include "wx/fontutil.h"
36
#include "wx/encinfo.h"
38
// ----------------------------------------------------------------------------
40
// ----------------------------------------------------------------------------
44
#include "pango/pango.h"
48
extern GtkWidget *wxGetRootWindow();
53
static int wxCMPFUNC_CONV
54
wxCompareFamilies (const void *a, const void *b)
56
const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
57
const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
59
return g_utf8_collate (a_name, b_name);
63
bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
66
if ( encoding != wxFONTENCODING_SYSTEM && encoding != wxFONTENCODING_UTF8 )
68
// Pango supports only UTF-8 encoding (and system means any, so we
73
PangoFontFamily **families = NULL;
75
pango_context_list_families (
77
gtk_widget_get_pango_context( wxGetRootWindow() ),
79
wxTheApp->GetPangoContext(),
81
&families, &n_families );
82
qsort (families, n_families, sizeof (PangoFontFamily *), wxCompareFamilies);
84
for ( int i = 0; i < n_families; i++ )
86
#if defined(__WXGTK20__) || defined(HAVE_PANGO_FONT_FAMILY_IS_MONOSPACE)
87
if ( !fixedWidthOnly ||
88
pango_font_family_is_monospace(families[i]) )
91
const gchar *name = pango_font_family_get_name(families[i]);
92
OnFacename(wxString(name, wxConvUTF8));
100
bool wxFontEnumerator::EnumerateEncodings(const wxString& facename)
102
return EnumerateEncodingsUTF8(facename);
106
#else // !wxUSE_PANGO
108
#ifdef __VMS__ // Xlib.h for VMS is not (yet) compatible with C++
109
// The resulting warnings are switched off here
110
#pragma message disable nosimpint
112
#include <X11/Xlib.h>
114
#pragma message enable nosimpint
117
// ----------------------------------------------------------------------------
119
// ----------------------------------------------------------------------------
121
// create the list of all fonts with the given spacing and encoding
122
static char **CreateFontList(wxChar spacing, wxFontEncoding encoding,
125
// extract all font families from the given font list and call our
126
// OnFacename() for each of them
127
static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
132
// ----------------------------------------------------------------------------
134
// ----------------------------------------------------------------------------
136
// ============================================================================
138
// ============================================================================
140
// ----------------------------------------------------------------------------
142
// ----------------------------------------------------------------------------
145
static char **CreateFontList(wxChar spacing,
146
wxFontEncoding encoding,
149
wxNativeEncodingInfo info;
150
wxGetNativeFontEncoding(encoding, &info);
153
if ( !wxTestFontEncoding(info) )
155
// ask font mapper for a replacement
156
(void)wxFontMapper::Get()->GetAltForEncoding(encoding, &info);
158
#endif // wxUSE_FONTMAP
161
pattern.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-%c-*-%s-%s"),
163
info.xregistry.c_str(),
164
info.xencoding.c_str());
166
// get the list of all fonts
167
return XListFonts((Display *)wxGetDisplay(), pattern.mb_str(), 32767, nFonts);
170
static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
175
wxRegEx re(wxT("^(-[^-]*){14}$"), wxRE_NOSUB);
176
#endif // wxUSE_REGEX
178
// extract the list of (unique) font families
179
wxSortedArrayString families;
180
for ( int n = 0; n < nFonts; n++ )
182
char *font = fonts[n];
184
if ( !re.Matches(font) )
185
#else // !wxUSE_REGEX
186
if ( !wxString(font).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
187
#endif // wxUSE_REGEX/!wxUSE_REGEX
189
// it's not a full font name (probably an alias)
193
// coverity[returned_null]
194
char *dash = strchr(font + 1, '-');
195
char *family = dash + 1;
196
dash = strchr(family, '-');
197
*dash = '\0'; // !NULL because Matches() above succeeded
198
wxString fam(family);
200
if ( families.Index(fam) == wxNOT_FOUND )
202
if ( !This->OnFacename(fam) )
218
// ----------------------------------------------------------------------------
220
// ----------------------------------------------------------------------------
222
bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
231
if ( fixedWidthOnly )
234
fonts = CreateFontList(wxT('m'), encoding, &nFonts);
237
cont = ProcessFamiliesFromFontList(this, fonts, nFonts);
239
XFreeFontNames(fonts);
247
fonts = CreateFontList(wxT('c'), encoding, &nFonts);
255
fonts = CreateFontList(wxT('*'), encoding, &nFonts);
259
// it's ok if there are no fonts in given encoding - but it's not
260
// ok if there are no fonts at all
261
wxASSERT_MSG(encoding != wxFONTENCODING_SYSTEM,
262
wxT("No fonts at all on this system?"));
268
(void)ProcessFamiliesFromFontList(this, fonts, nFonts);
270
XFreeFontNames(fonts);
276
bool wxFontEnumerator::EnumerateEncodings(const wxString& family)
282
pattern.Printf(wxT("-*-%s-*-*-*-*-*-*-*-*-*-*-*-*"),
283
family.empty() ? wxT("*") : family.c_str());
285
// get the list of all fonts
287
char **fonts = XListFonts((Display *)wxGetDisplay(), pattern.mb_str(),
296
// extract the list of (unique) encodings
297
wxSortedArrayString encodings;
298
for ( int n = 0; n < nFonts; n++ )
300
char *font = fonts[n];
301
if ( !wxString(font).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
303
// it's not a full font name (probably an alias)
307
// extract the family
308
char *dash = strchr(font + 1, '-');
309
char *familyFont = dash + 1;
310
dash = strchr(familyFont, '-');
311
*dash = '\0'; // !NULL because Matches() above succeeded
313
if ( !family.empty() && (family != familyFont) )
315
// family doesn't match
319
// now extract the registry/encoding
320
char *p = dash + 1; // just after the dash after family
321
dash = strrchr(p, '-');
323
wxString registry(dash + 1);
326
dash = strrchr(p, '-');
327
wxString encoding(dash + 1);
329
encoding << wxT('-') << registry;
330
if ( encodings.Index(encoding) == wxNOT_FOUND )
332
if ( !OnFontEncoding(familyFont, encoding) )
337
encodings.Add(encoding);
339
//else: already had this one
342
XFreeFontNames(fonts);
349
#endif // !wxUSE_PANGO
351
#endif // wxUSE_FONTENUM