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