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 // ============================================================================
46 // ============================================================================
48 // ----------------------------------------------------------------------------
49 // wxNativeEncodingInfo
50 // ----------------------------------------------------------------------------
52 // convert to/from the string representation: format is
53 // encodingid;facename[;charset]
55 bool wxNativeEncodingInfo::FromString(const wxString
& s
)
57 wxStringTokenizer
tokenizer(s
, _T(";"));
59 wxString encid
= tokenizer
.GetNextToken();
61 if ( !encid
.ToLong(&enc
) )
63 encoding
= (wxFontEncoding
)enc
;
65 facename
= tokenizer
.GetNextToken();
69 wxString tmp
= tokenizer
.GetNextToken();
72 // default charset (don't use DEFAULT_CHARSET though because of subtle
73 // Windows 9x/NT differences in handling it)
74 charset
= ANSI_CHARSET
;
78 if ( wxSscanf(tmp
, _T("%u"), &charset
) != 1 )
80 // should be a number!
88 wxString
wxNativeEncodingInfo::ToString() const
92 s
<< (long)encoding
<< _T(';') << facename
;
93 if ( charset
!= ANSI_CHARSET
)
95 s
<< _T(';') << charset
;
101 // ----------------------------------------------------------------------------
103 // ----------------------------------------------------------------------------
105 bool wxGetNativeFontEncoding(wxFontEncoding encoding
,
106 wxNativeEncodingInfo
*info
)
108 wxCHECK_MSG( info
, FALSE
, _T("bad pointer in wxGetNativeFontEncoding") );
110 if ( encoding
== wxFONTENCODING_DEFAULT
)
112 encoding
= wxFont::GetDefaultEncoding();
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
;
126 #if !defined(__WIN16__) && !defined(__WXMICROWIN__)
128 // The following four fonts are multi-byte charsets
129 case wxFONTENCODING_CP932
:
130 info
->charset
= SHIFTJIS_CHARSET
;
133 case wxFONTENCODING_CP936
:
134 info
->charset
= GB2312_CHARSET
;
137 case wxFONTENCODING_CP949
:
138 info
->charset
= HANGUL_CHARSET
;
141 case wxFONTENCODING_CP950
:
142 info
->charset
= CHINESEBIG5_CHARSET
;
145 // The rest are single byte encodings
146 case wxFONTENCODING_CP1250
:
147 info
->charset
= EASTEUROPE_CHARSET
;
150 case wxFONTENCODING_CP1251
:
151 info
->charset
= RUSSIAN_CHARSET
;
154 case wxFONTENCODING_CP1253
:
155 info
->charset
= GREEK_CHARSET
;
158 case wxFONTENCODING_CP1254
:
159 info
->charset
= TURKISH_CHARSET
;
162 case wxFONTENCODING_CP1255
:
163 info
->charset
= HEBREW_CHARSET
;
166 case wxFONTENCODING_CP1256
:
167 info
->charset
= ARABIC_CHARSET
;
170 case wxFONTENCODING_CP1257
:
171 info
->charset
= BALTIC_CHARSET
;
174 case wxFONTENCODING_CP874
:
175 info
->charset
= THAI_CHARSET
;
181 case wxFONTENCODING_CP437
:
182 info
->charset
= OEM_CHARSET
;
186 // no way to translate this encoding into a Windows charset
190 info
->encoding
= encoding
;
195 bool wxTestFontEncoding(const wxNativeEncodingInfo
& info
)
197 // try to create such font
199 wxZeroMemory(lf
); // all default values
201 lf
.lfCharSet
= info
.charset
;
202 wxStrncpy(lf
.lfFaceName
, info
.facename
, sizeof(lf
.lfFaceName
));
204 HFONT hfont
= ::CreateFontIndirect(&lf
);
211 ::DeleteObject((HGDIOBJ
)hfont
);
216 // ----------------------------------------------------------------------------
217 // wxFontEncoding <-> CHARSET_XXX
218 // ----------------------------------------------------------------------------
220 wxFontEncoding
wxGetFontEncFromCharSet(int cs
)
222 wxFontEncoding fontEncoding
;
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"));
234 fontEncoding
= wxFONTENCODING_CP1252
;
237 #if defined(__WIN32__) && !defined(__WXMICROWIN__)
238 case EASTEUROPE_CHARSET
:
239 fontEncoding
= wxFONTENCODING_CP1250
;
243 fontEncoding
= wxFONTENCODING_CP1257
;
246 case RUSSIAN_CHARSET
:
247 fontEncoding
= wxFONTENCODING_CP1251
;
251 fontEncoding
= wxFONTENCODING_CP1256
;
255 fontEncoding
= wxFONTENCODING_CP1253
;
259 fontEncoding
= wxFONTENCODING_CP1255
;
262 case TURKISH_CHARSET
:
263 fontEncoding
= wxFONTENCODING_CP1254
;
267 fontEncoding
= wxFONTENCODING_CP437
;
270 case SHIFTJIS_CHARSET
:
271 fontEncoding
= wxFONTENCODING_CP932
;
275 fontEncoding
= wxFONTENCODING_CP936
;
279 fontEncoding
= wxFONTENCODING_CP949
;
282 case CHINESEBIG5_CHARSET
:
283 fontEncoding
= wxFONTENCODING_CP950
;
289 fontEncoding
= wxFONTENCODING_CP437
;
296 // ----------------------------------------------------------------------------
297 // wxFont <-> LOGFONT conversion
298 // ----------------------------------------------------------------------------
300 void wxFillLogFont(LOGFONT
*logFont
, const wxFont
*font
)
305 switch ( font
->GetFamily() )
308 ff_family
= FF_SCRIPT
;
309 ff_face
= _T("Script");
313 ff_family
= FF_DECORATIVE
;
317 ff_family
= FF_ROMAN
;
318 ff_face
= _T("Times New Roman");
323 ff_family
= FF_MODERN
;
324 ff_face
= _T("Courier New");
328 ff_family
= FF_SWISS
;
329 ff_face
= _T("Arial");
334 ff_family
= FF_SWISS
;
335 ff_face
= _T("MS Sans Serif");
339 switch ( font
->GetStyle() )
347 wxFAIL_MSG(wxT("unknown font slant"));
355 switch ( font
->GetWeight() )
358 wxFAIL_MSG(_T("unknown font weight"));
362 ff_weight
= FW_NORMAL
;
366 ff_weight
= FW_LIGHT
;
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
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
);
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
386 static const int ppInch
= 96;
389 int pointSize
= font
->GetPointSize();
390 #if wxFONT_SIZE_COMPATIBILITY
391 // Incorrect, but compatible with old wxWindows behaviour
392 int nHeight
= (pointSize
*ppInch
)/72;
394 // Correct for Windows compatibility
395 int nHeight
= -(int)((pointSize
*((double)ppInch
)/72.0) + 0.5);
398 wxString facename
= font
->GetFaceName();
403 //else: ff_face is a reasonable default facename for this font family
405 // deal with encoding now
406 wxNativeEncodingInfo info
;
407 wxFontEncoding encoding
= font
->GetEncoding();
408 if ( !wxGetNativeFontEncoding(encoding
, &info
) )
411 if ( !wxTheFontMapper
->GetAltForEncoding(encoding
, &info
) )
412 #endif // wxUSE_FONTMAP
414 // unsupported encoding, replace with the default
415 info
.charset
= ANSI_CHARSET
;
419 if ( !info
.facename
.IsEmpty() )
421 // the facename determined by the encoding overrides everything else
422 ff_face
= info
.facename
;
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
));
442 wxFont
wxCreateFontFromLogFont(const LOGFONT
*logFont
)
444 wxNativeFontInfo info
;