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