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__)
127 case wxFONTENCODING_CP1250
:
128 info
->charset
= EASTEUROPE_CHARSET
;
131 case wxFONTENCODING_CP1251
:
132 info
->charset
= RUSSIAN_CHARSET
;
135 case wxFONTENCODING_CP1253
:
136 info
->charset
= GREEK_CHARSET
;
139 case wxFONTENCODING_CP1254
:
140 info
->charset
= TURKISH_CHARSET
;
143 case wxFONTENCODING_CP1255
:
144 info
->charset
= HEBREW_CHARSET
;
147 case wxFONTENCODING_CP1256
:
148 info
->charset
= ARABIC_CHARSET
;
151 case wxFONTENCODING_CP1257
:
152 info
->charset
= BALTIC_CHARSET
;
155 case wxFONTENCODING_CP874
:
156 info
->charset
= THAI_CHARSET
;
160 case wxFONTENCODING_CP437
:
161 info
->charset
= OEM_CHARSET
;
165 // no way to translate this encoding into a Windows charset
169 info
->encoding
= encoding
;
174 bool wxTestFontEncoding(const wxNativeEncodingInfo
& info
)
176 // try to create such font
178 wxZeroMemory(lf
); // all default values
180 lf
.lfCharSet
= info
.charset
;
181 wxStrncpy(lf
.lfFaceName
, info
.facename
, sizeof(lf
.lfFaceName
));
183 HFONT hfont
= ::CreateFontIndirect(&lf
);
190 ::DeleteObject((HGDIOBJ
)hfont
);
195 // ----------------------------------------------------------------------------
196 // wxFontEncoding <-> CHARSET_XXX
197 // ----------------------------------------------------------------------------
199 wxFontEncoding
wxGetFontEncFromCharSet(int cs
)
201 wxFontEncoding fontEncoding
;
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"));
213 fontEncoding
= wxFONTENCODING_CP1252
;
216 #if defined(__WIN32__) && !defined(__WXMICROWIN__)
217 case EASTEUROPE_CHARSET
:
218 fontEncoding
= wxFONTENCODING_CP1250
;
222 fontEncoding
= wxFONTENCODING_CP1257
;
225 case RUSSIAN_CHARSET
:
226 fontEncoding
= wxFONTENCODING_CP1251
;
230 fontEncoding
= wxFONTENCODING_CP1256
;
234 fontEncoding
= wxFONTENCODING_CP1253
;
238 fontEncoding
= wxFONTENCODING_CP1255
;
241 case TURKISH_CHARSET
:
242 fontEncoding
= wxFONTENCODING_CP1254
;
246 fontEncoding
= wxFONTENCODING_CP437
;
251 fontEncoding
= wxFONTENCODING_CP437
;
258 // ----------------------------------------------------------------------------
259 // wxFont <-> LOGFONT conversion
260 // ----------------------------------------------------------------------------
262 void wxFillLogFont(LOGFONT
*logFont
, const wxFont
*font
)
267 switch ( font
->GetFamily() )
270 ff_family
= FF_SCRIPT
;
271 ff_face
= _T("Script");
275 ff_family
= FF_DECORATIVE
;
279 ff_family
= FF_ROMAN
;
280 ff_face
= _T("Times New Roman");
285 ff_family
= FF_MODERN
;
286 ff_face
= _T("Courier New");
290 ff_family
= FF_SWISS
;
291 ff_face
= _T("Arial");
296 ff_family
= FF_SWISS
;
297 ff_face
= _T("MS Sans Serif");
301 switch ( font
->GetStyle() )
309 wxFAIL_MSG(wxT("unknown font slant"));
317 switch ( font
->GetWeight() )
320 wxFAIL_MSG(_T("unknown font weight"));
324 ff_weight
= FW_NORMAL
;
328 ff_weight
= FW_LIGHT
;
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
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
);
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
348 static const int ppInch
= 96;
351 int pointSize
= font
->GetPointSize();
352 #if wxFONT_SIZE_COMPATIBILITY
353 // Incorrect, but compatible with old wxWindows behaviour
354 int nHeight
= (pointSize
*ppInch
)/72;
356 // Correct for Windows compatibility
357 int nHeight
= -(int)((pointSize
*((double)ppInch
)/72.0) + 0.5);
360 wxString facename
= font
->GetFaceName();
365 //else: ff_face is a reasonable default facename for this font family
367 // deal with encoding now
368 wxNativeEncodingInfo info
;
369 wxFontEncoding encoding
= font
->GetEncoding();
370 if ( !wxGetNativeFontEncoding(encoding
, &info
) )
373 if ( !wxTheFontMapper
->GetAltForEncoding(encoding
, &info
) )
374 #endif // wxUSE_FONTMAP
376 // unsupported encoding, replace with the default
377 info
.charset
= ANSI_CHARSET
;
381 if ( !info
.facename
.IsEmpty() )
383 // the facename determined by the encoding overrides everything else
384 ff_face
= info
.facename
;
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
));
404 wxFont
wxCreateFontFromLogFont(const LOGFONT
*logFont
)
406 wxNativeFontInfo info
;