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