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