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