]> git.saurik.com Git - wxWidgets.git/blame - src/msw/fontutil.cpp
Mac-ify wxTreeCtrl further.
[wxWidgets.git] / src / msw / fontutil.cpp
CommitLineData
11c7d5b6
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: msw/fontutil.cpp
3// Purpose: font-related helper functions for wxMSW
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 05.11.99
7// RCS-ID: $Id$
8// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9// Licence: wxWindows license
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#ifdef __GNUG__
21 #pragma implementation "fontutil.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#ifndef WX_PRECOMP
32 #include "wx/string.h"
33 #include "wx/log.h"
34 #include "wx/intl.h"
35#endif //WX_PRECOMP
36
37#include "wx/msw/private.h"
38
39#include "wx/fontutil.h"
40#include "wx/fontmap.h"
41
42#include "wx/tokenzr.h"
43
44// ============================================================================
45// implementation
46// ============================================================================
47
48// ----------------------------------------------------------------------------
49// wxNativeEncodingInfo
50// ----------------------------------------------------------------------------
51
52// convert to/from the string representation: format is
1e1d0be1 53// encodingid;facename[;charset]
11c7d5b6
VZ
54
55bool wxNativeEncodingInfo::FromString(const wxString& s)
56{
57 wxStringTokenizer tokenizer(s, _T(";"));
58
1e1d0be1
VS
59 wxString encid = tokenizer.GetNextToken();
60 long enc;
61 if ( !encid.ToLong(&enc) )
62 return FALSE;
63 encoding = (wxFontEncoding)enc;
64
11c7d5b6
VZ
65 facename = tokenizer.GetNextToken();
66 if ( !facename )
67 return FALSE;
68
69 wxString tmp = tokenizer.GetNextToken();
70 if ( !tmp )
71 {
72 // default charset (don't use DEFAULT_CHARSET though because of subtle
73 // Windows 9x/NT differences in handling it)
74 charset = ANSI_CHARSET;
75 }
76 else
77 {
78 if ( wxSscanf(tmp, _T("%u"), &charset) != 1 )
79 {
80 // should be a number!
81 return FALSE;
82 }
83 }
84
85 return TRUE;
86}
87
88wxString wxNativeEncodingInfo::ToString() const
89{
1e1d0be1 90 wxString s;
f6bcfd97 91
1e1d0be1 92 s << (long)encoding << _T(';') << facename;
11c7d5b6
VZ
93 if ( charset != ANSI_CHARSET )
94 {
1e1d0be1 95 s << _T(';') << charset;
11c7d5b6
VZ
96 }
97
98 return s;
99}
100
101// ----------------------------------------------------------------------------
102// helper functions
103// ----------------------------------------------------------------------------
104
105bool wxGetNativeFontEncoding(wxFontEncoding encoding,
106 wxNativeEncodingInfo *info)
107{
108 wxCHECK_MSG( info, FALSE, _T("bad pointer in wxGetNativeFontEncoding") );
109
110 if ( encoding == wxFONTENCODING_DEFAULT )
111 {
112 encoding = wxFont::GetDefaultEncoding();
113 }
114
115 switch ( encoding )
116 {
117 // although this function is supposed to return an exact match, do do
118 // some mappings here for the most common case of "standard" encoding
119 case wxFONTENCODING_SYSTEM:
120 case wxFONTENCODING_ISO8859_1:
121 case wxFONTENCODING_ISO8859_15:
122 case wxFONTENCODING_CP1252:
123 info->charset = ANSI_CHARSET;
124 break;
125
04ef50df 126#if !defined(__WIN16__) && !defined(__WXMICROWIN__)
11c7d5b6
VZ
127 case wxFONTENCODING_CP1250:
128 info->charset = EASTEUROPE_CHARSET;
129 break;
130
131 case wxFONTENCODING_CP1251:
132 info->charset = RUSSIAN_CHARSET;
133 break;
134
135 case wxFONTENCODING_CP1253:
136 info->charset = GREEK_CHARSET;
137 break;
138
139 case wxFONTENCODING_CP1254:
140 info->charset = TURKISH_CHARSET;
141 break;
142
143 case wxFONTENCODING_CP1255:
144 info->charset = HEBREW_CHARSET;
145 break;
146
147 case wxFONTENCODING_CP1256:
148 info->charset = ARABIC_CHARSET;
149 break;
150
151 case wxFONTENCODING_CP1257:
152 info->charset = BALTIC_CHARSET;
153 break;
f3314fbc
JS
154
155 case wxFONTENCODING_CP874:
156 info->charset = THAI_CHARSET;
157 break;
11c7d5b6
VZ
158#endif // !Win16
159
160 case wxFONTENCODING_CP437:
161 info->charset = OEM_CHARSET;
162 break;
163
164 default:
165 // no way to translate this encoding into a Windows charset
166 return FALSE;
167 }
168
6b0eebc5 169 info->encoding = encoding;
f6bcfd97 170
11c7d5b6
VZ
171 return TRUE;
172}
173
174bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
175{
176 // try to create such font
177 LOGFONT lf;
178 wxZeroMemory(lf); // all default values
179
180 lf.lfCharSet = info.charset;
0e89bb17 181 wxStrncpy(lf.lfFaceName, info.facename, sizeof(lf.lfFaceName));
11c7d5b6
VZ
182
183 HFONT hfont = ::CreateFontIndirect(&lf);
184 if ( !hfont )
185 {
186 // no such font
187 return FALSE;
188 }
189
190 ::DeleteObject((HGDIOBJ)hfont);
191
192 return TRUE;
193}
194
f6bcfd97
BP
195// ----------------------------------------------------------------------------
196// wxFontEncoding <-> CHARSET_XXX
197// ----------------------------------------------------------------------------
198
199wxFontEncoding wxGetFontEncFromCharSet(int cs)
200{
201 wxFontEncoding fontEncoding;
202
203 switch ( cs )
204 {
205 default:
206 // JACS: Silently using ANSI_CHARSET
207 // apparently works for Chinese Windows. Assume it works
208 // for all/most other languages.
209 //wxFAIL_MSG(wxT("unsupported charset"));
210 // fall through
211
212 case ANSI_CHARSET:
213 fontEncoding = wxFONTENCODING_CP1252;
214 break;
215
04ef50df 216#if defined(__WIN32__) && !defined(__WXMICROWIN__)
f6bcfd97
BP
217 case EASTEUROPE_CHARSET:
218 fontEncoding = wxFONTENCODING_CP1250;
219 break;
220
221 case BALTIC_CHARSET:
222 fontEncoding = wxFONTENCODING_CP1257;
223 break;
224
225 case RUSSIAN_CHARSET:
226 fontEncoding = wxFONTENCODING_CP1251;
227 break;
228
229 case ARABIC_CHARSET:
230 fontEncoding = wxFONTENCODING_CP1256;
231 break;
232
233 case GREEK_CHARSET:
234 fontEncoding = wxFONTENCODING_CP1253;
235 break;
236
237 case HEBREW_CHARSET:
238 fontEncoding = wxFONTENCODING_CP1255;
239 break;
240
241 case TURKISH_CHARSET:
242 fontEncoding = wxFONTENCODING_CP1254;
243 break;
244
245 case THAI_CHARSET:
246 fontEncoding = wxFONTENCODING_CP437;
247 break;
248#endif // Win32
249
250 case OEM_CHARSET:
251 fontEncoding = wxFONTENCODING_CP437;
252 break;
253 }
254
255 return fontEncoding;
256}
257
11c7d5b6
VZ
258// ----------------------------------------------------------------------------
259// wxFont <-> LOGFONT conversion
260// ----------------------------------------------------------------------------
261
262void wxFillLogFont(LOGFONT *logFont, const wxFont *font)
263{
264 int ff_family;
265 wxString ff_face;
266
267 switch ( font->GetFamily() )
268 {
269 case wxSCRIPT:
270 ff_family = FF_SCRIPT;
271 ff_face = _T("Script");
272 break;
273
274 case wxDECORATIVE:
275 ff_family = FF_DECORATIVE;
276 break;
277
278 case wxROMAN:
279 ff_family = FF_ROMAN;
280 ff_face = _T("Times New Roman");
281 break;
282
283 case wxTELETYPE:
284 case wxMODERN:
285 ff_family = FF_MODERN;
286 ff_face = _T("Courier New");
287 break;
288
289 case wxSWISS:
290 ff_family = FF_SWISS;
291 ff_face = _T("Arial");
292 break;
293
294 case wxDEFAULT:
295 default:
296 ff_family = FF_SWISS;
297 ff_face = _T("MS Sans Serif");
298 }
299
300 BYTE ff_italic;
301 switch ( font->GetStyle() )
302 {
303 case wxITALIC:
304 case wxSLANT:
305 ff_italic = 1;
306 break;
307
308 default:
309 wxFAIL_MSG(wxT("unknown font slant"));
310 // fall through
311
312 case wxNORMAL:
313 ff_italic = 0;
314 }
315
316 int ff_weight;
317 switch ( font->GetWeight() )
318 {
319 default:
320 wxFAIL_MSG(_T("unknown font weight"));
321 // fall through
322
323 case wxNORMAL:
324 ff_weight = FW_NORMAL;
325 break;
326
327 case wxLIGHT:
328 ff_weight = FW_LIGHT;
329 break;
330
331 case wxBOLD:
332 ff_weight = FW_BOLD;
333 break;
334 }
335
55bd3f34
VZ
336 // VZ: I'm reverting this as we clearly must use the real screen
337 // resolution instead of hardcoded one or it surely will fail to work
338 // in some cases.
339 //
340 // If there are any problems with this code, please let me know about
341 // it instead of reverting this change, thanks!
342#if 1 // wxUSE_SCREEN_DPI
343 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
344#else // 0
11c7d5b6
VZ
345 // New behaviour: apparently ppInch varies according to Large/Small Fonts
346 // setting in Windows. This messes up fonts. So, set ppInch to a constant
347 // 96 dpi.
348 static const int ppInch = 96;
55bd3f34 349#endif // 1/0
11c7d5b6 350
55bd3f34 351 int pointSize = font->GetPointSize();
11c7d5b6
VZ
352#if wxFONT_SIZE_COMPATIBILITY
353 // Incorrect, but compatible with old wxWindows behaviour
55bd3f34 354 int nHeight = (pointSize*ppInch)/72;
11c7d5b6
VZ
355#else
356 // Correct for Windows compatibility
55bd3f34 357 int nHeight = -(int)((pointSize*((double)ppInch)/72.0) + 0.5);
11c7d5b6
VZ
358#endif
359
360 wxString facename = font->GetFaceName();
361 if ( !!facename )
362 {
363 ff_face = facename;
364 }
365 //else: ff_face is a reasonable default facename for this font family
366
367 // deal with encoding now
368 wxNativeEncodingInfo info;
369 wxFontEncoding encoding = font->GetEncoding();
370 if ( !wxGetNativeFontEncoding(encoding, &info) )
371 {
1e6feb95 372#if wxUSE_FONTMAP
11c7d5b6 373 if ( !wxTheFontMapper->GetAltForEncoding(encoding, &info) )
1e6feb95 374#endif // wxUSE_FONTMAP
11c7d5b6
VZ
375 {
376 // unsupported encoding, replace with the default
377 info.charset = ANSI_CHARSET;
378 }
379 }
380
381 if ( !info.facename.IsEmpty() )
382 {
383 // the facename determined by the encoding overrides everything else
384 ff_face = info.facename;
385 }
386
387 // transfer all the data to LOGFONT
388 logFont->lfHeight = nHeight;
389 logFont->lfWidth = 0;
390 logFont->lfEscapement = 0;
391 logFont->lfOrientation = 0;
392 logFont->lfWeight = ff_weight;
393 logFont->lfItalic = ff_italic;
394 logFont->lfUnderline = (BYTE)font->GetUnderlined();
395 logFont->lfStrikeOut = 0;
396 logFont->lfCharSet = info.charset;
397 logFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
398 logFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
399 logFont->lfQuality = PROOF_QUALITY;
400 logFont->lfPitchAndFamily = DEFAULT_PITCH | ff_family;
401 wxStrncpy(logFont->lfFaceName, ff_face, WXSIZEOF(logFont->lfFaceName));
402}
403
404wxFont wxCreateFontFromLogFont(const LOGFONT *logFont)
405{
09fcd889 406 wxNativeFontInfo info;
11c7d5b6 407
09fcd889 408 info.lf = *logFont;
11c7d5b6 409
09fcd889 410 return wxFont(info);
11c7d5b6
VZ
411}
412