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