]> git.saurik.com Git - wxWidgets.git/blob - src/msw/fontenum.cpp
07a79b78f4909e289fc78f99b9a753ae646a43f2
[wxWidgets.git] / src / msw / fontenum.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: msw/fontenum.cpp
3 // Purpose: wxFontEnumerator class for Windows
4 // Author: Julian Smart
5 // Modified by: Vadim Zeitlin to add support for font encodings
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "fontenum.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #if wxUSE_FONTMAP
32
33 #ifndef WX_PRECOMP
34 #include "wx/gdicmn.h"
35 #include "wx/font.h"
36 #include "wx/encinfo.h"
37 #endif
38
39 #include "wx/msw/private.h"
40
41 #include "wx/fontutil.h"
42 #include "wx/fontenum.h"
43 #include "wx/fontmap.h"
44
45 // ----------------------------------------------------------------------------
46 // private classes
47 // ----------------------------------------------------------------------------
48
49 // the helper class which calls ::EnumFontFamilies() and whose OnFont() is
50 // called from the callback passed to this function and, in its turn, calls the
51 // appropariate wxFontEnumerator method
52 class wxFontEnumeratorHelper
53 {
54 public:
55 wxFontEnumeratorHelper(wxFontEnumerator *fontEnum);
56
57 // control what exactly are we enumerating
58 // we enumerate fonts with given enocding
59 bool SetEncoding(wxFontEncoding encoding);
60 // we enumerate fixed-width fonts
61 void SetFixedOnly(bool fixedOnly) { m_fixedOnly = fixedOnly; }
62 // we enumerate the encodings available in this family
63 void SetFamily(const wxString& family);
64
65 // call to start enumeration
66 void DoEnumerate();
67
68 // called by our font enumeration proc
69 bool OnFont(const LPLOGFONT lf, const LPTEXTMETRIC tm) const;
70
71 private:
72 // the object we forward calls to OnFont() to
73 wxFontEnumerator *m_fontEnum;
74
75 // if != -1, enum only fonts which have this encoding
76 int m_charset;
77
78 // if not empty, enum only the fonts with this facename
79 wxString m_facename;
80
81 // if not empty, enum only the fonts in this family
82 wxString m_family;
83
84 // if true, enum only fixed fonts
85 bool m_fixedOnly;
86
87 // if true, we enumerate the encodings, not fonts
88 bool m_enumEncodings;
89
90 // the list of charsets we already found while enumerating charsets
91 wxArrayInt m_charsets;
92
93 // the list of facenames we already found while enumerating facenames
94 wxArrayString m_facenames;
95
96 DECLARE_NO_COPY_CLASS(wxFontEnumeratorHelper)
97 };
98
99 // ----------------------------------------------------------------------------
100 // private functions
101 // ----------------------------------------------------------------------------
102
103 #ifndef __WXMICROWIN__
104 int CALLBACK wxFontEnumeratorProc(LPLOGFONT lplf, LPTEXTMETRIC lptm,
105 DWORD dwStyle, LONG lParam);
106 #endif
107
108 // ============================================================================
109 // implementation
110 // ============================================================================
111
112 // ----------------------------------------------------------------------------
113 // wxFontEnumeratorHelper
114 // ----------------------------------------------------------------------------
115
116 wxFontEnumeratorHelper::wxFontEnumeratorHelper(wxFontEnumerator *fontEnum)
117 {
118 m_fontEnum = fontEnum;
119 m_charset = DEFAULT_CHARSET;
120 m_fixedOnly = false;
121 m_enumEncodings = false;
122 }
123
124 void wxFontEnumeratorHelper::SetFamily(const wxString& family)
125 {
126 m_enumEncodings = true;
127 m_family = family;
128 }
129
130 bool wxFontEnumeratorHelper::SetEncoding(wxFontEncoding encoding)
131 {
132 if ( encoding != wxFONTENCODING_SYSTEM )
133 {
134 wxNativeEncodingInfo info;
135 if ( !wxGetNativeFontEncoding(encoding, &info) )
136 {
137 #if wxUSE_FONTMAP
138 if ( !wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
139 #endif // wxUSE_FONTMAP
140 {
141 // no such encodings at all
142 return false;
143 }
144 }
145
146 m_charset = info.charset;
147 m_facename = info.facename;
148 }
149
150 return true;
151 }
152
153 #if defined(__GNUWIN32__) && !defined(__CYGWIN10__) && !wxCHECK_W32API_VERSION( 1, 1 ) && !wxUSE_NORLANDER_HEADERS
154 #define wxFONTENUMPROC int(*)(ENUMLOGFONTEX *, NEWTEXTMETRICEX*, int, LPARAM)
155 #else
156 #define wxFONTENUMPROC FONTENUMPROC
157 #endif
158
159 void wxFontEnumeratorHelper::DoEnumerate()
160 {
161 #ifndef __WXMICROWIN__
162 HDC hDC = ::GetDC(NULL);
163
164 #ifdef __WXWINCE__
165 ::EnumFontFamilies(hDC, m_facename, (wxFONTENUMPROC)wxFontEnumeratorProc,
166 (LPARAM)this) ;
167 #else // __WIN32__
168 LOGFONT lf;
169 lf.lfCharSet = m_charset;
170 wxStrncpy(lf.lfFaceName, m_facename, WXSIZEOF(lf.lfFaceName));
171 lf.lfPitchAndFamily = 0;
172 ::EnumFontFamiliesEx(hDC, &lf, (wxFONTENUMPROC)wxFontEnumeratorProc,
173 (LPARAM)this, 0 /* reserved */) ;
174 #endif // Win32/CE
175
176 ::ReleaseDC(NULL, hDC);
177 #endif
178 }
179
180 bool wxFontEnumeratorHelper::OnFont(const LPLOGFONT lf,
181 const LPTEXTMETRIC tm) const
182 {
183 if ( m_enumEncodings )
184 {
185 // is this a new charset?
186 int cs = lf->lfCharSet;
187 if ( m_charsets.Index(cs) == wxNOT_FOUND )
188 {
189 wxConstCast(this, wxFontEnumeratorHelper)->m_charsets.Add(cs);
190
191 wxFontEncoding enc = wxGetFontEncFromCharSet(cs);
192 return m_fontEnum->OnFontEncoding(lf->lfFaceName,
193 wxFontMapper::GetEncodingName(enc));
194 }
195 else
196 {
197 // continue enumeration
198 return true;
199 }
200 }
201
202 if ( m_fixedOnly )
203 {
204 // check that it's a fixed pitch font (there is *no* error here, the
205 // flag name is misleading!)
206 if ( tm->tmPitchAndFamily & TMPF_FIXED_PITCH )
207 {
208 // not a fixed pitch font
209 return true;
210 }
211 }
212
213 if ( m_charset != DEFAULT_CHARSET )
214 {
215 // check that we have the right encoding
216 if ( lf->lfCharSet != m_charset )
217 {
218 return true;
219 }
220 }
221 else // enumerating fonts in all charsets
222 {
223 // we can get the same facename twice or more in this case because it
224 // may exist in several charsets but we only want to return one copy of
225 // it (note that this can't happen for m_charset != DEFAULT_CHARSET)
226 if ( m_facenames.Index(lf->lfFaceName) != wxNOT_FOUND )
227 {
228 // continue enumeration
229 return true;
230 }
231
232 wxConstCast(this, wxFontEnumeratorHelper)->
233 m_facenames.Add(lf->lfFaceName);
234 }
235
236 return m_fontEnum->OnFacename(lf->lfFaceName);
237 }
238
239 // ----------------------------------------------------------------------------
240 // wxFontEnumerator
241 // ----------------------------------------------------------------------------
242
243 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
244 bool fixedWidthOnly)
245 {
246 wxFontEnumeratorHelper fe(this);
247 if ( fe.SetEncoding(encoding) )
248 {
249 fe.SetFixedOnly(fixedWidthOnly);
250
251 fe.DoEnumerate();
252 }
253 // else: no such fonts, unknown encoding
254
255 return true;
256 }
257
258 bool wxFontEnumerator::EnumerateEncodings(const wxString& family)
259 {
260 wxFontEnumeratorHelper fe(this);
261 fe.SetFamily(family);
262 fe.DoEnumerate();
263
264 return true;
265 }
266
267 // ----------------------------------------------------------------------------
268 // Windows callbacks
269 // ----------------------------------------------------------------------------
270
271 #ifndef __WXMICROWIN__
272 int CALLBACK wxFontEnumeratorProc(LPLOGFONT lplf, LPTEXTMETRIC lptm,
273 DWORD WXUNUSED(dwStyle), LONG lParam)
274 {
275
276 // we used to process TrueType fonts only, but there doesn't seem to be any
277 // reasons to restrict ourselves to them here
278 #if 0
279 // Get rid of any fonts that we don't want...
280 if ( dwStyle != TRUETYPE_FONTTYPE )
281 {
282 // continue enumeration
283 return TRUE;
284 }
285 #endif // 0
286
287 wxFontEnumeratorHelper *fontEnum = (wxFontEnumeratorHelper *)lParam;
288
289 return fontEnum->OnFont(lplf, lptm);
290 }
291 #endif
292
293 #endif // wxUSE_FONTMAP