]> git.saurik.com Git - wxWidgets.git/blame - src/unix/fontenum.cpp
avoid duplicating wxWindow::HandleCommand() in wxFrame, only handle the commands...
[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
ff427585
VZ
23#if wxUSE_FONTENUM
24
df91131c
WS
25#include "wx/fontenum.h"
26
ad9835c9
WS
27#ifndef WX_PRECOMP
28 #include "wx/dynarray.h"
df91131c 29 #include "wx/string.h"
670f9935 30 #include "wx/app.h"
de6185e2 31 #include "wx/utils.h"
ad9835c9
WS
32#endif
33
6fea4a7a 34#include "wx/regex.h"
79e4b627 35#include "wx/fontmap.h"
7beba2fc 36#include "wx/fontutil.h"
e4ffab29 37#include "wx/encinfo.h"
d111a89a 38
db16cab4 39// ----------------------------------------------------------------------------
2b5f62a0 40// Pango
db16cab4
RR
41// ----------------------------------------------------------------------------
42
2b5f62a0 43#if wxUSE_PANGO
db16cab4 44
2b5f62a0 45#include "pango/pango.h"
db16cab4 46
2b5f62a0
VZ
47#ifdef __WXGTK20__
48#include "gtk/gtk.h"
db16cab4 49extern GtkWidget *wxGetRootWindow();
55034339 50#endif // __WXGTK20__
db16cab4 51
17a1ebd1
VZ
52extern "C" int wxCMPFUNC_CONV
53wxCompareFamilies (const void *a, const void *b)
db16cab4
RR
54{
55 const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
56 const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
b578601e 57
db16cab4
RR
58 return g_utf8_collate (a_name, b_name);
59}
60
db16cab4
RR
61bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
62 bool fixedWidthOnly)
63{
1acca470
VZ
64 if ( encoding != wxFONTENCODING_SYSTEM && encoding != wxFONTENCODING_UTF8 )
65 {
66 // Pango supports only UTF-8 encoding (and system means any, so we
67 // accept it too)
68 return false;
69 }
70
ff654490
VZ
71 PangoFontFamily **families = NULL;
72 gint n_families = 0;
73 pango_context_list_families (
2b5f62a0 74#ifdef __WXGTK20__
ff654490 75 gtk_widget_get_pango_context( wxGetRootWindow() ),
2b5f62a0 76#else
ff654490 77 wxTheApp->GetPangoContext(),
2b5f62a0 78#endif
ff654490
VZ
79 &families, &n_families );
80 qsort (families, n_families, sizeof (PangoFontFamily *), wxCompareFamilies);
db16cab4 81
ff654490
VZ
82 for ( int i = 0; i < n_families; i++ )
83 {
84#if defined(__WXGTK20__) || defined(HAVE_PANGO_FONT_FAMILY_IS_MONOSPACE)
85 if ( !fixedWidthOnly ||
86 pango_font_family_is_monospace(families[i]) )
304205f1 87#endif
ff654490
VZ
88 {
89 const gchar *name = pango_font_family_get_name(families[i]);
90 OnFacename(wxString(name, wxConvUTF8));
db16cab4
RR
91 }
92 }
ff654490 93 g_free(families);
2696b11c 94
55034339 95 return true;
db16cab4
RR
96}
97
1acca470 98bool wxFontEnumerator::EnumerateEncodings(const wxString& facename)
db16cab4 99{
4e1d79d3 100 return EnumerateEncodingsUTF8(facename);
db16cab4
RR
101}
102
103
1acca470 104#else // !wxUSE_PANGO
db16cab4 105
3fa056ab
JJ
106#ifdef __VMS__ // Xlib.h for VMS is not (yet) compatible with C++
107 // The resulting warnings are switched off here
108#pragma message disable nosimpint
109#endif
d111a89a 110#include <X11/Xlib.h>
3fa056ab
JJ
111#ifdef __VMS__
112#pragma message enable nosimpint
113#endif
d111a89a
VZ
114
115// ----------------------------------------------------------------------------
116// private functions
117// ----------------------------------------------------------------------------
118
36f210c8
VZ
119// create the list of all fonts with the given spacing and encoding
120static char **CreateFontList(wxChar spacing, wxFontEncoding encoding,
121 int *nFonts);
d111a89a
VZ
122
123// extract all font families from the given font list and call our
3c1866e8 124// OnFacename() for each of them
d111a89a
VZ
125static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
126 char **fonts,
127 int nFonts);
128
129
130// ----------------------------------------------------------------------------
131// private types
132// ----------------------------------------------------------------------------
133
134// ============================================================================
135// implementation
136// ============================================================================
137
138// ----------------------------------------------------------------------------
139// helpers
140// ----------------------------------------------------------------------------
141
461e93f9 142#if !wxUSE_NANOX
36f210c8
VZ
143static char **CreateFontList(wxChar spacing,
144 wxFontEncoding encoding,
145 int *nFonts)
d111a89a 146{
7beba2fc
VZ
147 wxNativeEncodingInfo info;
148 wxGetNativeFontEncoding(encoding, &info);
36f210c8 149
1e6feb95 150#if wxUSE_FONTMAP
79e4b627
VZ
151 if ( !wxTestFontEncoding(info) )
152 {
153 // ask font mapper for a replacement
142b3bc2 154 (void)wxFontMapper::Get()->GetAltForEncoding(encoding, &info);
79e4b627 155 }
1e6feb95 156#endif // wxUSE_FONTMAP
79e4b627 157
d111a89a 158 wxString pattern;
36f210c8 159 pattern.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-%c-*-%s-%s"),
7beba2fc
VZ
160 spacing,
161 info.xregistry.c_str(),
162 info.xencoding.c_str());
d111a89a
VZ
163
164 // get the list of all fonts
7dd62924 165 return XListFonts((Display *)wxGetDisplay(), pattern.mb_str(), 32767, nFonts);
d111a89a
VZ
166}
167
168static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
169 char **fonts,
170 int nFonts)
171{
f1d7cbac
VZ
172#if wxUSE_REGEX
173 wxRegEx re(wxT("^(-[^-]*){14}$"), wxRE_NOSUB);
174#endif // wxUSE_REGEX
175
d111a89a
VZ
176 // extract the list of (unique) font families
177 wxSortedArrayString families;
178 for ( int n = 0; n < nFonts; n++ )
179 {
180 char *font = fonts[n];
f1d7cbac 181#if wxUSE_REGEX
32a2fbc8 182 if ( !re.Matches(font) )
f1d7cbac 183#else // !wxUSE_REGEX
7dd62924 184 if ( !wxString(font).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
f1d7cbac 185#endif // wxUSE_REGEX/!wxUSE_REGEX
d111a89a
VZ
186 {
187 // it's not a full font name (probably an alias)
188 continue;
189 }
3c1866e8 190
40a0dc1b 191 // coverity[returned_null]
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
55034339 203 return false;
d111a89a
VZ
204 }
205
7dd62924 206 families.Add(fam);
d111a89a
VZ
207 }
208 //else: already seen
209 }
210
55034339 211 return true;
d111a89a 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 223#if wxUSE_NANOX
55034339 224 return false;
461e93f9 225#else
d111a89a
VZ
226 int nFonts;
227 char **fonts;
228
229 if ( fixedWidthOnly )
230 {
55034339 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 {
55034339 242 return true;
d111a89a
VZ
243 }
244
36f210c8 245 fonts = CreateFontList(wxT('c'), encoding, &nFonts);
d111a89a
VZ
246 if ( !fonts )
247 {
55034339 248 return true;
d111a89a
VZ
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 261
55034339 262 return false;
d111a89a
VZ
263 }
264 }
265
266 (void)ProcessFamiliesFromFontList(this, fonts, nFonts);
267
268 XFreeFontNames(fonts);
55034339 269 return true;
461e93f9
JS
270#endif
271 // wxUSE_NANOX
d111a89a
VZ
272}
273
274bool wxFontEnumerator::EnumerateEncodings(const wxString& family)
275{
461e93f9 276#if wxUSE_NANOX
55034339 277 return false;
461e93f9 278#else
d111a89a
VZ
279 wxString pattern;
280 pattern.Printf(wxT("-*-%s-*-*-*-*-*-*-*-*-*-*-*-*"),
55034339 281 family.empty() ? wxT("*") : family.c_str());
d111a89a
VZ
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?
55034339 291 return false;
d111a89a
VZ
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
55034339 311 if ( !family.empty() && (family != familyFont) )
d111a89a
VZ
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
55034339 342 return true;
461e93f9
JS
343#endif
344 // wxUSE_NANOX
d111a89a 345}
db16cab4 346
55034339 347#endif // !wxUSE_PANGO
ff427585
VZ
348
349#endif // wxUSE_FONTENUM