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