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