1. moved fontenum.cpp to unix because implementation is common to X and GTK+
[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, 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("-*-*-*-*-*-*-*-*-*-*-*-*-*-*") )
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
88 if ( families.Index(family) == wxNOT_FOUND )
89 {
90 if ( !This->OnFontFamily(family) )
91 {
92 // stop enumerating
93 return FALSE;
94 }
95
96 families.Add(family);
97 }
98 //else: already seen
99 }
100
101 return TRUE;
102 }
103
104 // ----------------------------------------------------------------------------
105 // wxFontEnumerator
106 // ----------------------------------------------------------------------------
107
108 bool wxFontEnumerator::EnumerateFamilies(bool fixedWidthOnly)
109 {
110 int nFonts;
111 char **fonts;
112
113 if ( fixedWidthOnly )
114 {
115 bool cont = TRUE;
116 fonts = CreateFontList(wxT('m'), &nFonts);
117 if ( fonts )
118 {
119 cont = ProcessFamiliesFromFontList(this, fonts, nFonts);
120
121 XFreeFontNames(fonts);
122 }
123
124 if ( !cont )
125 {
126 return TRUE;
127 }
128
129 fonts = CreateFontList(wxT('c'), &nFonts);
130 if ( !fonts )
131 {
132 return TRUE;
133 }
134 }
135 else
136 {
137 fonts = CreateFontList(wxT('*'), &nFonts);
138
139 if ( !fonts )
140 {
141 wxFAIL_MSG(wxT("No fonts at all on this system?"));
142
143 return FALSE;
144 }
145 }
146
147 (void)ProcessFamiliesFromFontList(this, fonts, nFonts);
148
149 XFreeFontNames(fonts);
150
151 return TRUE;
152 }
153
154 bool wxFontEnumerator::EnumerateEncodings(const wxString& family)
155 {
156 wxString pattern;
157 pattern.Printf(wxT("-*-%s-*-*-*-*-*-*-*-*-*-*-*-*"),
158 family.IsEmpty() ? wxT("*") : family.c_str());
159
160 // get the list of all fonts
161 int nFonts;
162 char **fonts = XListFonts((Display *)wxGetDisplay(), pattern,
163 32767, &nFonts);
164
165 if ( !fonts )
166 {
167 // unknown family?
168 return FALSE;
169 }
170
171 // extract the list of (unique) encodings
172 wxSortedArrayString encodings;
173 for ( int n = 0; n < nFonts; n++ )
174 {
175 char *font = fonts[n];
176 if ( !wxString(font).Matches("-*-*-*-*-*-*-*-*-*-*-*-*-*-*") )
177 {
178 // it's not a full font name (probably an alias)
179 continue;
180 }
181
182 // extract the family
183 char *dash = strchr(font + 1, '-');
184 char *familyFont = dash + 1;
185 dash = strchr(familyFont, '-');
186 *dash = '\0'; // !NULL because Matches() above succeeded
187
188 if ( !family.IsEmpty() && (family != familyFont) )
189 {
190 // family doesn't match
191 continue;
192 }
193
194 // now extract the registry/encoding
195 char *p = dash + 1; // just after the dash after family
196 dash = strrchr(p, '-');
197
198 wxString registry(dash + 1);
199 *dash = '\0';
200
201 dash = strrchr(p, '-');
202 wxString encoding(dash + 1);
203
204 encoding << wxT('-') << registry;
205 if ( encodings.Index(encoding) == wxNOT_FOUND )
206 {
207 if ( !OnFontEncoding(familyFont, encoding) )
208 {
209 break;
210 }
211
212 encodings.Add(encoding);
213 }
214 //else: already had this one
215 }
216
217 XFreeFontNames(fonts);
218
219 return TRUE;
220 }