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