]> git.saurik.com Git - wxWidgets.git/blob - src/unix/fontenum.cpp
Lots of Unix/Unicode compile fixes, some of which
[wxWidgets.git] / src / unix / fontenum.cpp
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"
27 #include "wx/regex.h"
28 #include "wx/utils.h"
29
30 #include "wx/fontmap.h"
31 #include "wx/fontenum.h"
32 #include "wx/fontutil.h"
33
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
38 #include <X11/Xlib.h>
39 #ifdef __VMS__
40 #pragma message enable nosimpint
41 #endif
42
43 // ----------------------------------------------------------------------------
44 // private functions
45 // ----------------------------------------------------------------------------
46
47 // create the list of all fonts with the given spacing and encoding
48 static char **CreateFontList(wxChar spacing, wxFontEncoding encoding,
49 int *nFonts);
50
51 // extract all font families from the given font list and call our
52 // OnFacename() for each of them
53 static 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
70 #if !wxUSE_NANOX
71 static char **CreateFontList(wxChar spacing,
72 wxFontEncoding encoding,
73 int *nFonts)
74 {
75 wxNativeEncodingInfo info;
76 wxGetNativeFontEncoding(encoding, &info);
77
78 #if wxUSE_FONTMAP
79 if ( !wxTestFontEncoding(info) )
80 {
81 // ask font mapper for a replacement
82 (void)wxFontMapper::Get()->GetAltForEncoding(encoding, &info);
83 }
84 #endif // wxUSE_FONTMAP
85
86 wxString pattern;
87 pattern.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-%c-*-%s-%s"),
88 spacing,
89 info.xregistry.c_str(),
90 info.xencoding.c_str());
91
92 // get the list of all fonts
93 return XListFonts((Display *)wxGetDisplay(), pattern.mb_str(), 32767, nFonts);
94 }
95
96 static bool ProcessFamiliesFromFontList(wxFontEnumerator *This,
97 char **fonts,
98 int nFonts)
99 {
100 #if wxUSE_REGEX
101 wxRegEx re(wxT("^(-[^-]*){14}$"), wxRE_NOSUB);
102 #endif // wxUSE_REGEX
103
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];
109 #if wxUSE_REGEX
110 #if wxUSE_UNICODE
111 wxString sfont( wxConvLocal.cMB2WC( font ) );
112 if ( !re.Matches(sfont) )
113 #else
114 if ( !re.Matches(font) )
115 #endif
116 #else // !wxUSE_REGEX
117 if ( !wxString(font).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
118 #endif // wxUSE_REGEX/!wxUSE_REGEX
119 {
120 // it's not a full font name (probably an alias)
121 continue;
122 }
123
124 char *dash = strchr(font + 1, '-');
125 char *family = dash + 1;
126 dash = strchr(family, '-');
127 *dash = '\0'; // !NULL because Matches() above succeeded
128 #if wxUSE_UNICODE
129 wxString fam( wxConvLocal.cMB2WC( family ) );
130 #else
131 wxString fam(family);
132 #endif
133
134 if ( families.Index(fam) == wxNOT_FOUND )
135 {
136 if ( !This->OnFacename(fam) )
137 {
138 // stop enumerating
139 return FALSE;
140 }
141
142 families.Add(fam);
143 }
144 //else: already seen
145 }
146
147 return TRUE;
148 }
149 #endif
150 // wxUSE_NANOX
151
152 // ----------------------------------------------------------------------------
153 // wxFontEnumerator
154 // ----------------------------------------------------------------------------
155
156 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
157 bool fixedWidthOnly)
158 {
159 #if wxUSE_NANOX
160 return FALSE;
161 #else
162 int nFonts;
163 char **fonts;
164
165 if ( fixedWidthOnly )
166 {
167 bool cont = TRUE;
168 fonts = CreateFontList(wxT('m'), encoding, &nFonts);
169 if ( fonts )
170 {
171 cont = ProcessFamiliesFromFontList(this, fonts, nFonts);
172
173 XFreeFontNames(fonts);
174 }
175
176 if ( !cont )
177 {
178 return TRUE;
179 }
180
181 fonts = CreateFontList(wxT('c'), encoding, &nFonts);
182 if ( !fonts )
183 {
184 return TRUE;
185 }
186 }
187 else
188 {
189 fonts = CreateFontList(wxT('*'), encoding, &nFonts);
190
191 if ( !fonts )
192 {
193 // it's ok if there are no fonts in given encoding - but it's not
194 // ok if there are no fonts at all
195 wxASSERT_MSG(encoding != wxFONTENCODING_SYSTEM,
196 wxT("No fonts at all on this system?"));
197
198 return FALSE;
199 }
200 }
201
202 (void)ProcessFamiliesFromFontList(this, fonts, nFonts);
203
204 XFreeFontNames(fonts);
205 return TRUE;
206 #endif
207 // wxUSE_NANOX
208 }
209
210 bool wxFontEnumerator::EnumerateEncodings(const wxString& family)
211 {
212 #if wxUSE_NANOX
213 return FALSE;
214 #else
215 wxString pattern;
216 pattern.Printf(wxT("-*-%s-*-*-*-*-*-*-*-*-*-*-*-*"),
217 family.IsEmpty() ? wxT("*") : family.c_str());
218
219 // get the list of all fonts
220 int nFonts;
221 char **fonts = XListFonts((Display *)wxGetDisplay(), pattern.mb_str(),
222 32767, &nFonts);
223
224 if ( !fonts )
225 {
226 // unknown family?
227 return FALSE;
228 }
229
230 // extract the list of (unique) encodings
231 wxSortedArrayString encodings;
232 for ( int n = 0; n < nFonts; n++ )
233 {
234 char *font = fonts[n];
235 if ( !wxString(font).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
236 {
237 // it's not a full font name (probably an alias)
238 continue;
239 }
240
241 // extract the family
242 char *dash = strchr(font + 1, '-');
243 char *familyFont = dash + 1;
244 dash = strchr(familyFont, '-');
245 *dash = '\0'; // !NULL because Matches() above succeeded
246
247 if ( !family.IsEmpty() && (family != familyFont) )
248 {
249 // family doesn't match
250 continue;
251 }
252
253 // now extract the registry/encoding
254 char *p = dash + 1; // just after the dash after family
255 dash = strrchr(p, '-');
256
257 wxString registry(dash + 1);
258 *dash = '\0';
259
260 dash = strrchr(p, '-');
261 wxString encoding(dash + 1);
262
263 encoding << wxT('-') << registry;
264 if ( encodings.Index(encoding) == wxNOT_FOUND )
265 {
266 if ( !OnFontEncoding(familyFont, encoding) )
267 {
268 break;
269 }
270
271 encodings.Add(encoding);
272 }
273 //else: already had this one
274 }
275
276 XFreeFontNames(fonts);
277
278 return TRUE;
279 #endif
280 // wxUSE_NANOX
281 }