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