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