]> git.saurik.com Git - wxWidgets.git/blame - src/msw/fontutil.cpp
make --static flag act on --cppflags too.
[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__)
bc4e6fcd
VZ
127
128 // The following four fonts are multi-byte charsets
129 case wxFONTENCODING_CP932:
130 info->charset = SHIFTJIS_CHARSET;
131 break;
132
133 case wxFONTENCODING_CP936:
134 info->charset = GB2312_CHARSET;
135 break;
136
137 case wxFONTENCODING_CP949:
138 info->charset = HANGUL_CHARSET;
139 break;
140
141 case wxFONTENCODING_CP950:
142 info->charset = CHINESEBIG5_CHARSET;
143 break;
144
145 // The rest are single byte encodings
11c7d5b6
VZ
146 case wxFONTENCODING_CP1250:
147 info->charset = EASTEUROPE_CHARSET;
148 break;
149
150 case wxFONTENCODING_CP1251:
151 info->charset = RUSSIAN_CHARSET;
152 break;
153
154 case wxFONTENCODING_CP1253:
155 info->charset = GREEK_CHARSET;
156 break;
157
158 case wxFONTENCODING_CP1254:
159 info->charset = TURKISH_CHARSET;
160 break;
161
162 case wxFONTENCODING_CP1255:
163 info->charset = HEBREW_CHARSET;
164 break;
165
166 case wxFONTENCODING_CP1256:
167 info->charset = ARABIC_CHARSET;
168 break;
169
170 case wxFONTENCODING_CP1257:
171 info->charset = BALTIC_CHARSET;
172 break;
f3314fbc
JS
173
174 case wxFONTENCODING_CP874:
175 info->charset = THAI_CHARSET;
176 break;
bc4e6fcd
VZ
177
178
11c7d5b6
VZ
179#endif // !Win16
180
181 case wxFONTENCODING_CP437:
182 info->charset = OEM_CHARSET;
183 break;
184
185 default:
186 // no way to translate this encoding into a Windows charset
187 return FALSE;
188 }
189
6b0eebc5 190 info->encoding = encoding;
f6bcfd97 191
11c7d5b6
VZ
192 return TRUE;
193}
194
195bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
196{
197 // try to create such font
198 LOGFONT lf;
199 wxZeroMemory(lf); // all default values
200
201 lf.lfCharSet = info.charset;
0e89bb17 202 wxStrncpy(lf.lfFaceName, info.facename, sizeof(lf.lfFaceName));
11c7d5b6
VZ
203
204 HFONT hfont = ::CreateFontIndirect(&lf);
205 if ( !hfont )
206 {
207 // no such font
208 return FALSE;
209 }
210
211 ::DeleteObject((HGDIOBJ)hfont);
212
213 return TRUE;
214}
215
f6bcfd97
BP
216// ----------------------------------------------------------------------------
217// wxFontEncoding <-> CHARSET_XXX
218// ----------------------------------------------------------------------------
219
220wxFontEncoding wxGetFontEncFromCharSet(int cs)
221{
222 wxFontEncoding fontEncoding;
223
224 switch ( cs )
225 {
226 default:
227 // JACS: Silently using ANSI_CHARSET
228 // apparently works for Chinese Windows. Assume it works
229 // for all/most other languages.
230 //wxFAIL_MSG(wxT("unsupported charset"));
231 // fall through
232
233 case ANSI_CHARSET:
234 fontEncoding = wxFONTENCODING_CP1252;
235 break;
236
04ef50df 237#if defined(__WIN32__) && !defined(__WXMICROWIN__)
f6bcfd97
BP
238 case EASTEUROPE_CHARSET:
239 fontEncoding = wxFONTENCODING_CP1250;
240 break;
241
242 case BALTIC_CHARSET:
243 fontEncoding = wxFONTENCODING_CP1257;
244 break;
245
246 case RUSSIAN_CHARSET:
247 fontEncoding = wxFONTENCODING_CP1251;
248 break;
249
250 case ARABIC_CHARSET:
251 fontEncoding = wxFONTENCODING_CP1256;
252 break;
253
254 case GREEK_CHARSET:
255 fontEncoding = wxFONTENCODING_CP1253;
256 break;
257
258 case HEBREW_CHARSET:
259 fontEncoding = wxFONTENCODING_CP1255;
260 break;
261
262 case TURKISH_CHARSET:
263 fontEncoding = wxFONTENCODING_CP1254;
264 break;
265
266 case THAI_CHARSET:
267 fontEncoding = wxFONTENCODING_CP437;
268 break;
bc4e6fcd
VZ
269
270 case SHIFTJIS_CHARSET:
271 fontEncoding = wxFONTENCODING_CP932;
272 break;
273
274 case GB2312_CHARSET:
275 fontEncoding = wxFONTENCODING_CP936;
276 break;
277
278 case HANGUL_CHARSET:
279 fontEncoding = wxFONTENCODING_CP949;
280 break;
281
282 case CHINESEBIG5_CHARSET:
283 fontEncoding = wxFONTENCODING_CP950;
284 break;
285
f6bcfd97
BP
286#endif // Win32
287
288 case OEM_CHARSET:
289 fontEncoding = wxFONTENCODING_CP437;
290 break;
291 }
292
293 return fontEncoding;
294}
295
11c7d5b6
VZ
296// ----------------------------------------------------------------------------
297// wxFont <-> LOGFONT conversion
298// ----------------------------------------------------------------------------
299
300void wxFillLogFont(LOGFONT *logFont, const wxFont *font)
301{
302 int ff_family;
303 wxString ff_face;
304
305 switch ( font->GetFamily() )
306 {
307 case wxSCRIPT:
308 ff_family = FF_SCRIPT;
309 ff_face = _T("Script");
310 break;
311
312 case wxDECORATIVE:
313 ff_family = FF_DECORATIVE;
314 break;
315
316 case wxROMAN:
317 ff_family = FF_ROMAN;
318 ff_face = _T("Times New Roman");
319 break;
320
321 case wxTELETYPE:
322 case wxMODERN:
323 ff_family = FF_MODERN;
324 ff_face = _T("Courier New");
325 break;
326
327 case wxSWISS:
328 ff_family = FF_SWISS;
329 ff_face = _T("Arial");
330 break;
331
332 case wxDEFAULT:
333 default:
334 ff_family = FF_SWISS;
335 ff_face = _T("MS Sans Serif");
336 }
337
338 BYTE ff_italic;
339 switch ( font->GetStyle() )
340 {
341 case wxITALIC:
342 case wxSLANT:
343 ff_italic = 1;
344 break;
345
346 default:
347 wxFAIL_MSG(wxT("unknown font slant"));
348 // fall through
349
350 case wxNORMAL:
351 ff_italic = 0;
352 }
353
354 int ff_weight;
355 switch ( font->GetWeight() )
356 {
357 default:
358 wxFAIL_MSG(_T("unknown font weight"));
359 // fall through
360
361 case wxNORMAL:
362 ff_weight = FW_NORMAL;
363 break;
364
365 case wxLIGHT:
366 ff_weight = FW_LIGHT;
367 break;
368
369 case wxBOLD:
370 ff_weight = FW_BOLD;
371 break;
372 }
373
55bd3f34
VZ
374 // VZ: I'm reverting this as we clearly must use the real screen
375 // resolution instead of hardcoded one or it surely will fail to work
376 // in some cases.
377 //
378 // If there are any problems with this code, please let me know about
379 // it instead of reverting this change, thanks!
380#if 1 // wxUSE_SCREEN_DPI
381 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
382#else // 0
11c7d5b6
VZ
383 // New behaviour: apparently ppInch varies according to Large/Small Fonts
384 // setting in Windows. This messes up fonts. So, set ppInch to a constant
385 // 96 dpi.
386 static const int ppInch = 96;
55bd3f34 387#endif // 1/0
11c7d5b6 388
55bd3f34 389 int pointSize = font->GetPointSize();
11c7d5b6
VZ
390#if wxFONT_SIZE_COMPATIBILITY
391 // Incorrect, but compatible with old wxWindows behaviour
55bd3f34 392 int nHeight = (pointSize*ppInch)/72;
11c7d5b6
VZ
393#else
394 // Correct for Windows compatibility
55bd3f34 395 int nHeight = -(int)((pointSize*((double)ppInch)/72.0) + 0.5);
11c7d5b6
VZ
396#endif
397
398 wxString facename = font->GetFaceName();
399 if ( !!facename )
400 {
401 ff_face = facename;
402 }
403 //else: ff_face is a reasonable default facename for this font family
404
405 // deal with encoding now
406 wxNativeEncodingInfo info;
407 wxFontEncoding encoding = font->GetEncoding();
408 if ( !wxGetNativeFontEncoding(encoding, &info) )
409 {
1e6feb95 410#if wxUSE_FONTMAP
11c7d5b6 411 if ( !wxTheFontMapper->GetAltForEncoding(encoding, &info) )
1e6feb95 412#endif // wxUSE_FONTMAP
11c7d5b6
VZ
413 {
414 // unsupported encoding, replace with the default
415 info.charset = ANSI_CHARSET;
416 }
417 }
418
419 if ( !info.facename.IsEmpty() )
420 {
421 // the facename determined by the encoding overrides everything else
422 ff_face = info.facename;
423 }
424
425 // transfer all the data to LOGFONT
426 logFont->lfHeight = nHeight;
427 logFont->lfWidth = 0;
428 logFont->lfEscapement = 0;
429 logFont->lfOrientation = 0;
430 logFont->lfWeight = ff_weight;
431 logFont->lfItalic = ff_italic;
432 logFont->lfUnderline = (BYTE)font->GetUnderlined();
433 logFont->lfStrikeOut = 0;
434 logFont->lfCharSet = info.charset;
435 logFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
436 logFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
437 logFont->lfQuality = PROOF_QUALITY;
438 logFont->lfPitchAndFamily = DEFAULT_PITCH | ff_family;
439 wxStrncpy(logFont->lfFaceName, ff_face, WXSIZEOF(logFont->lfFaceName));
440}
441
442wxFont wxCreateFontFromLogFont(const LOGFONT *logFont)
443{
09fcd889 444 wxNativeFontInfo info;
11c7d5b6 445
09fcd889 446 info.lf = *logFont;
11c7d5b6 447
09fcd889 448 return wxFont(info);
11c7d5b6
VZ
449}
450