]> git.saurik.com Git - wxWidgets.git/blame - src/unix/fontenum.cpp
no significant changes
[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
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#ifdef __GNUG__
21 #pragma implementation "fontenum.h"
22#endif
23
24#include "wx/defs.h"
25#include "wx/dynarray.h"
26#include "wx/string.h"
6fea4a7a 27#include "wx/regex.h"
d111a89a
VZ
28#include "wx/utils.h"
29
79e4b627 30#include "wx/fontmap.h"
d111a89a 31#include "wx/fontenum.h"
7beba2fc 32#include "wx/fontutil.h"
d111a89a 33
3fa056ab
JJ
34#ifdef __VMS__ // Xlib.h for VMS is not (yet) compatible with C++
35 // The resulting warnings are switched off here
36#pragma message disable nosimpint
37#endif
d111a89a 38#include <X11/Xlib.h>
3fa056ab
JJ
39#ifdef __VMS__
40#pragma message enable nosimpint
41#endif
d111a89a
VZ
42
43// ----------------------------------------------------------------------------
44// private functions
45// ----------------------------------------------------------------------------
46
36f210c8
VZ
47// create the list of all fonts with the given spacing and encoding
48static char **CreateFontList(wxChar spacing, wxFontEncoding encoding,
49 int *nFonts);
d111a89a
VZ
50
51// extract all font families from the given font list and call our
3c1866e8 52// OnFacename() for each of them
d111a89a
VZ
53static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
54 char **fonts,
55 int nFonts);
56
57
58// ----------------------------------------------------------------------------
59// private types
60// ----------------------------------------------------------------------------
61
62// ============================================================================
63// implementation
64// ============================================================================
65
66// ----------------------------------------------------------------------------
67// helpers
68// ----------------------------------------------------------------------------
69
461e93f9 70#if !wxUSE_NANOX
36f210c8
VZ
71static char **CreateFontList(wxChar spacing,
72 wxFontEncoding encoding,
73 int *nFonts)
d111a89a 74{
7beba2fc
VZ
75 wxNativeEncodingInfo info;
76 wxGetNativeFontEncoding(encoding, &info);
36f210c8 77
1e6feb95 78#if wxUSE_FONTMAP
79e4b627
VZ
79 if ( !wxTestFontEncoding(info) )
80 {
81 // ask font mapper for a replacement
142b3bc2 82 (void)wxFontMapper::Get()->GetAltForEncoding(encoding, &info);
79e4b627 83 }
1e6feb95 84#endif // wxUSE_FONTMAP
79e4b627 85
d111a89a 86 wxString pattern;
36f210c8 87 pattern.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-%c-*-%s-%s"),
7beba2fc
VZ
88 spacing,
89 info.xregistry.c_str(),
90 info.xencoding.c_str());
d111a89a
VZ
91
92 // get the list of all fonts
7dd62924 93 return XListFonts((Display *)wxGetDisplay(), pattern.mb_str(), 32767, nFonts);
d111a89a
VZ
94}
95
96static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
97 char **fonts,
98 int nFonts)
99{
f1d7cbac
VZ
100#if wxUSE_REGEX
101 wxRegEx re(wxT("^(-[^-]*){14}$"), wxRE_NOSUB);
102#endif // wxUSE_REGEX
103
d111a89a
VZ
104 // extract the list of (unique) font families
105 wxSortedArrayString families;
106 for ( int n = 0; n < nFonts; n++ )
107 {
108 char *font = fonts[n];
f1d7cbac 109#if wxUSE_REGEX
32a2fbc8 110 if ( !re.Matches(font) )
f1d7cbac 111#else // !wxUSE_REGEX
7dd62924 112 if ( !wxString(font).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
f1d7cbac 113#endif // wxUSE_REGEX/!wxUSE_REGEX
d111a89a
VZ
114 {
115 // it's not a full font name (probably an alias)
116 continue;
117 }
3c1866e8 118
d111a89a
VZ
119 char *dash = strchr(font + 1, '-');
120 char *family = dash + 1;
121 dash = strchr(family, '-');
122 *dash = '\0'; // !NULL because Matches() above succeeded
7dd62924 123 wxString fam(family);
d111a89a 124
7dd62924 125 if ( families.Index(fam) == wxNOT_FOUND )
d111a89a 126 {
3c1866e8 127 if ( !This->OnFacename(fam) )
d111a89a
VZ
128 {
129 // stop enumerating
130 return FALSE;
131 }
132
7dd62924 133 families.Add(fam);
d111a89a
VZ
134 }
135 //else: already seen
136 }
137
138 return TRUE;
139}
461e93f9
JS
140#endif
141 // wxUSE_NANOX
d111a89a
VZ
142
143// ----------------------------------------------------------------------------
144// wxFontEnumerator
145// ----------------------------------------------------------------------------
146
3c1866e8
VZ
147bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
148 bool fixedWidthOnly)
d111a89a 149{
461e93f9
JS
150#if wxUSE_NANOX
151 return FALSE;
152#else
d111a89a
VZ
153 int nFonts;
154 char **fonts;
155
156 if ( fixedWidthOnly )
157 {
158 bool cont = TRUE;
36f210c8 159 fonts = CreateFontList(wxT('m'), encoding, &nFonts);
d111a89a
VZ
160 if ( fonts )
161 {
162 cont = ProcessFamiliesFromFontList(this, fonts, nFonts);
163
164 XFreeFontNames(fonts);
165 }
166
167 if ( !cont )
168 {
169 return TRUE;
170 }
171
36f210c8 172 fonts = CreateFontList(wxT('c'), encoding, &nFonts);
d111a89a
VZ
173 if ( !fonts )
174 {
175 return TRUE;
176 }
177 }
178 else
179 {
36f210c8 180 fonts = CreateFontList(wxT('*'), encoding, &nFonts);
d111a89a
VZ
181
182 if ( !fonts )
183 {
36f210c8
VZ
184 // it's ok if there are no fonts in given encoding - but it's not
185 // ok if there are no fonts at all
186 wxASSERT_MSG(encoding != wxFONTENCODING_SYSTEM,
187 wxT("No fonts at all on this system?"));
d111a89a
VZ
188
189 return FALSE;
190 }
191 }
192
193 (void)ProcessFamiliesFromFontList(this, fonts, nFonts);
194
195 XFreeFontNames(fonts);
d111a89a 196 return TRUE;
461e93f9
JS
197#endif
198 // wxUSE_NANOX
d111a89a
VZ
199}
200
201bool wxFontEnumerator::EnumerateEncodings(const wxString& family)
202{
461e93f9
JS
203#if wxUSE_NANOX
204 return FALSE;
205#else
d111a89a
VZ
206 wxString pattern;
207 pattern.Printf(wxT("-*-%s-*-*-*-*-*-*-*-*-*-*-*-*"),
208 family.IsEmpty() ? wxT("*") : family.c_str());
209
210 // get the list of all fonts
211 int nFonts;
7dd62924 212 char **fonts = XListFonts((Display *)wxGetDisplay(), pattern.mb_str(),
d111a89a
VZ
213 32767, &nFonts);
214
215 if ( !fonts )
216 {
217 // unknown family?
218 return FALSE;
219 }
220
221 // extract the list of (unique) encodings
222 wxSortedArrayString encodings;
223 for ( int n = 0; n < nFonts; n++ )
224 {
225 char *font = fonts[n];
7dd62924 226 if ( !wxString(font).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
d111a89a
VZ
227 {
228 // it's not a full font name (probably an alias)
229 continue;
230 }
231
232 // extract the family
233 char *dash = strchr(font + 1, '-');
234 char *familyFont = dash + 1;
235 dash = strchr(familyFont, '-');
236 *dash = '\0'; // !NULL because Matches() above succeeded
237
238 if ( !family.IsEmpty() && (family != familyFont) )
239 {
240 // family doesn't match
241 continue;
242 }
243
244 // now extract the registry/encoding
245 char *p = dash + 1; // just after the dash after family
246 dash = strrchr(p, '-');
247
248 wxString registry(dash + 1);
249 *dash = '\0';
250
251 dash = strrchr(p, '-');
252 wxString encoding(dash + 1);
253
254 encoding << wxT('-') << registry;
255 if ( encodings.Index(encoding) == wxNOT_FOUND )
256 {
257 if ( !OnFontEncoding(familyFont, encoding) )
258 {
259 break;
260 }
261
262 encodings.Add(encoding);
263 }
264 //else: already had this one
265 }
266
267 XFreeFontNames(fonts);
268
269 return TRUE;
461e93f9
JS
270#endif
271 // wxUSE_NANOX
d111a89a 272}