1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: msw/fontutil.cpp
3 // Purpose: font-related helper functions for wxMSW
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "fontutil.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
32 #include "wx/string.h"
37 #include "wx/msw/private.h"
39 #include "wx/fontutil.h"
40 #include "wx/fontmap.h"
42 #include "wx/tokenzr.h"
44 // for MSVC5 and old w32api
45 #ifndef HANGUL_CHARSET
46 # define HANGUL_CHARSET 129
49 // ============================================================================
51 // ============================================================================
53 // ----------------------------------------------------------------------------
54 // wxNativeEncodingInfo
55 // ----------------------------------------------------------------------------
57 // convert to/from the string representation: format is
58 // encodingid;facename[;charset]
60 bool wxNativeEncodingInfo::FromString(const wxString
& s
)
62 wxStringTokenizer
tokenizer(s
, _T(";"));
64 wxString encid
= tokenizer
.GetNextToken();
66 if ( !encid
.ToLong(&enc
) )
68 encoding
= (wxFontEncoding
)enc
;
70 facename
= tokenizer
.GetNextToken();
74 wxString tmp
= tokenizer
.GetNextToken();
77 // default charset (don't use DEFAULT_CHARSET though because of subtle
78 // Windows 9x/NT differences in handling it)
79 charset
= ANSI_CHARSET
;
83 if ( wxSscanf(tmp
, _T("%u"), &charset
) != 1 )
85 // should be a number!
93 wxString
wxNativeEncodingInfo::ToString() const
97 s
<< (long)encoding
<< _T(';') << facename
;
98 if ( charset
!= ANSI_CHARSET
)
100 s
<< _T(';') << charset
;
106 // ----------------------------------------------------------------------------
108 // ----------------------------------------------------------------------------
110 bool wxGetNativeFontEncoding(wxFontEncoding encoding
,
111 wxNativeEncodingInfo
*info
)
113 wxCHECK_MSG( info
, FALSE
, _T("bad pointer in wxGetNativeFontEncoding") );
115 if ( encoding
== wxFONTENCODING_DEFAULT
)
117 encoding
= wxFont::GetDefaultEncoding();
122 // although this function is supposed to return an exact match, do do
123 // some mappings here for the most common case of "standard" encoding
124 case wxFONTENCODING_SYSTEM
:
125 case wxFONTENCODING_ISO8859_1
:
126 case wxFONTENCODING_ISO8859_15
:
127 case wxFONTENCODING_CP1252
:
128 info
->charset
= ANSI_CHARSET
;
131 #if !defined(__WIN16__) && !defined(__WXMICROWIN__)
133 // The following four fonts are multi-byte charsets
134 case wxFONTENCODING_CP932
:
135 info
->charset
= SHIFTJIS_CHARSET
;
138 case wxFONTENCODING_CP936
:
139 info
->charset
= GB2312_CHARSET
;
142 case wxFONTENCODING_CP949
:
143 info
->charset
= HANGUL_CHARSET
;
146 case wxFONTENCODING_CP950
:
147 info
->charset
= CHINESEBIG5_CHARSET
;
150 // The rest are single byte encodings
151 case wxFONTENCODING_CP1250
:
152 info
->charset
= EASTEUROPE_CHARSET
;
155 case wxFONTENCODING_CP1251
:
156 info
->charset
= RUSSIAN_CHARSET
;
159 case wxFONTENCODING_CP1253
:
160 info
->charset
= GREEK_CHARSET
;
163 case wxFONTENCODING_CP1254
:
164 info
->charset
= TURKISH_CHARSET
;
167 case wxFONTENCODING_CP1255
:
168 info
->charset
= HEBREW_CHARSET
;
171 case wxFONTENCODING_CP1256
:
172 info
->charset
= ARABIC_CHARSET
;
175 case wxFONTENCODING_CP1257
:
176 info
->charset
= BALTIC_CHARSET
;
179 case wxFONTENCODING_CP874
:
180 info
->charset
= THAI_CHARSET
;
186 case wxFONTENCODING_CP437
:
187 info
->charset
= OEM_CHARSET
;
191 // no way to translate this encoding into a Windows charset
195 info
->encoding
= encoding
;
200 bool wxTestFontEncoding(const wxNativeEncodingInfo
& info
)
202 // try to create such font
204 wxZeroMemory(lf
); // all default values
206 lf
.lfCharSet
= info
.charset
;
207 wxStrncpy(lf
.lfFaceName
, info
.facename
, sizeof(lf
.lfFaceName
));
209 HFONT hfont
= ::CreateFontIndirect(&lf
);
216 ::DeleteObject((HGDIOBJ
)hfont
);
221 // ----------------------------------------------------------------------------
222 // wxFontEncoding <-> CHARSET_XXX
223 // ----------------------------------------------------------------------------
225 wxFontEncoding
wxGetFontEncFromCharSet(int cs
)
227 wxFontEncoding fontEncoding
;
232 // JACS: Silently using ANSI_CHARSET
233 // apparently works for Chinese Windows. Assume it works
234 // for all/most other languages.
235 //wxFAIL_MSG(wxT("unsupported charset"));
239 fontEncoding
= wxFONTENCODING_CP1252
;
242 #if defined(__WIN32__) && !defined(__WXMICROWIN__)
243 case EASTEUROPE_CHARSET
:
244 fontEncoding
= wxFONTENCODING_CP1250
;
248 fontEncoding
= wxFONTENCODING_CP1257
;
251 case RUSSIAN_CHARSET
:
252 fontEncoding
= wxFONTENCODING_CP1251
;
256 fontEncoding
= wxFONTENCODING_CP1256
;
260 fontEncoding
= wxFONTENCODING_CP1253
;
264 fontEncoding
= wxFONTENCODING_CP1255
;
267 case TURKISH_CHARSET
:
268 fontEncoding
= wxFONTENCODING_CP1254
;
272 fontEncoding
= wxFONTENCODING_CP437
;
275 case SHIFTJIS_CHARSET
:
276 fontEncoding
= wxFONTENCODING_CP932
;
280 fontEncoding
= wxFONTENCODING_CP936
;
284 fontEncoding
= wxFONTENCODING_CP949
;
287 case CHINESEBIG5_CHARSET
:
288 fontEncoding
= wxFONTENCODING_CP950
;
294 fontEncoding
= wxFONTENCODING_CP437
;
301 // ----------------------------------------------------------------------------
302 // wxFont <-> LOGFONT conversion
303 // ----------------------------------------------------------------------------
305 void wxFillLogFont(LOGFONT
*logFont
, const wxFont
*font
)
310 switch ( font
->GetFamily() )
313 ff_family
= FF_SCRIPT
;
314 ff_face
= _T("Script");
318 ff_family
= FF_DECORATIVE
;
322 ff_family
= FF_ROMAN
;
323 ff_face
= _T("Times New Roman");
328 ff_family
= FF_MODERN
;
329 ff_face
= _T("Courier New");
333 ff_family
= FF_SWISS
;
334 ff_face
= _T("Arial");
339 ff_family
= FF_SWISS
;
340 ff_face
= _T("MS Sans Serif");
344 switch ( font
->GetStyle() )
352 wxFAIL_MSG(wxT("unknown font slant"));
360 switch ( font
->GetWeight() )
363 wxFAIL_MSG(_T("unknown font weight"));
367 ff_weight
= FW_NORMAL
;
371 ff_weight
= FW_LIGHT
;
379 // VZ: I'm reverting this as we clearly must use the real screen
380 // resolution instead of hardcoded one or it surely will fail to work
383 // If there are any problems with this code, please let me know about
384 // it instead of reverting this change, thanks!
385 #if 1 // wxUSE_SCREEN_DPI
386 const int ppInch
= ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY
);
388 // New behaviour: apparently ppInch varies according to Large/Small Fonts
389 // setting in Windows. This messes up fonts. So, set ppInch to a constant
391 static const int ppInch
= 96;
394 int pointSize
= font
->GetPointSize();
395 #if wxFONT_SIZE_COMPATIBILITY
396 // Incorrect, but compatible with old wxWindows behaviour
397 int nHeight
= (pointSize
*ppInch
)/72;
399 // Correct for Windows compatibility
400 int nHeight
= -(int)((pointSize
*((double)ppInch
)/72.0) + 0.5);
403 wxString facename
= font
->GetFaceName();
408 //else: ff_face is a reasonable default facename for this font family
410 // deal with encoding now
411 wxNativeEncodingInfo info
;
412 wxFontEncoding encoding
= font
->GetEncoding();
413 if ( !wxGetNativeFontEncoding(encoding
, &info
) )
416 if ( !wxTheFontMapper
->GetAltForEncoding(encoding
, &info
) )
417 #endif // wxUSE_FONTMAP
419 // unsupported encoding, replace with the default
420 info
.charset
= ANSI_CHARSET
;
424 if ( !info
.facename
.IsEmpty() )
426 // the facename determined by the encoding overrides everything else
427 ff_face
= info
.facename
;
430 // transfer all the data to LOGFONT
431 logFont
->lfHeight
= nHeight
;
432 logFont
->lfWidth
= 0;
433 logFont
->lfEscapement
= 0;
434 logFont
->lfOrientation
= 0;
435 logFont
->lfWeight
= ff_weight
;
436 logFont
->lfItalic
= ff_italic
;
437 logFont
->lfUnderline
= (BYTE
)font
->GetUnderlined();
438 logFont
->lfStrikeOut
= 0;
439 logFont
->lfCharSet
= info
.charset
;
440 logFont
->lfOutPrecision
= OUT_DEFAULT_PRECIS
;
441 logFont
->lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
442 logFont
->lfQuality
= PROOF_QUALITY
;
443 logFont
->lfPitchAndFamily
= DEFAULT_PITCH
| ff_family
;
444 wxStrncpy(logFont
->lfFaceName
, ff_face
, WXSIZEOF(logFont
->lfFaceName
));
447 wxFont
wxCreateFontFromLogFont(const LOGFONT
*logFont
)
449 wxNativeFontInfo info
;