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