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