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