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__)
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 // wxFont <-> LOGFONT conversion
197 // ----------------------------------------------------------------------------
199 void wxFillLogFont(LOGFONT
*logFont
, const wxFont
*font
)
204 switch ( font
->GetFamily() )
207 ff_family
= FF_SCRIPT
;
208 ff_face
= _T("Script");
212 ff_family
= FF_DECORATIVE
;
216 ff_family
= FF_ROMAN
;
217 ff_face
= _T("Times New Roman");
222 ff_family
= FF_MODERN
;
223 ff_face
= _T("Courier New");
227 ff_family
= FF_SWISS
;
228 ff_face
= _T("Arial");
233 ff_family
= FF_SWISS
;
234 ff_face
= _T("MS Sans Serif");
238 switch ( font
->GetStyle() )
246 wxFAIL_MSG(wxT("unknown font slant"));
254 switch ( font
->GetWeight() )
257 wxFAIL_MSG(_T("unknown font weight"));
261 ff_weight
= FW_NORMAL
;
265 ff_weight
= FW_LIGHT
;
274 HDC dc
= ::GetDC(NULL
);
275 int ppInch
= ::GetDeviceCaps(dc
, LOGPIXELSY
);
276 ::ReleaseDC(NULL
, dc
);
278 // New behaviour: apparently ppInch varies according to Large/Small Fonts
279 // setting in Windows. This messes up fonts. So, set ppInch to a constant
281 static const int ppInch
= 96;
284 #if wxFONT_SIZE_COMPATIBILITY
285 // Incorrect, but compatible with old wxWindows behaviour
286 int nHeight
= (font
->GetPointSize()*ppInch
/72);
288 // Correct for Windows compatibility
289 int nHeight
= - (font
->GetPointSize()*ppInch
/72);
292 wxString facename
= font
->GetFaceName();
297 //else: ff_face is a reasonable default facename for this font family
299 // deal with encoding now
300 wxNativeEncodingInfo info
;
301 wxFontEncoding encoding
= font
->GetEncoding();
302 if ( !wxGetNativeFontEncoding(encoding
, &info
) )
304 if ( !wxTheFontMapper
->GetAltForEncoding(encoding
, &info
) )
306 // unsupported encoding, replace with the default
307 info
.charset
= ANSI_CHARSET
;
311 if ( !info
.facename
.IsEmpty() )
313 // the facename determined by the encoding overrides everything else
314 ff_face
= info
.facename
;
317 // transfer all the data to LOGFONT
318 logFont
->lfHeight
= nHeight
;
319 logFont
->lfWidth
= 0;
320 logFont
->lfEscapement
= 0;
321 logFont
->lfOrientation
= 0;
322 logFont
->lfWeight
= ff_weight
;
323 logFont
->lfItalic
= ff_italic
;
324 logFont
->lfUnderline
= (BYTE
)font
->GetUnderlined();
325 logFont
->lfStrikeOut
= 0;
326 logFont
->lfCharSet
= info
.charset
;
327 logFont
->lfOutPrecision
= OUT_DEFAULT_PRECIS
;
328 logFont
->lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
329 logFont
->lfQuality
= PROOF_QUALITY
;
330 logFont
->lfPitchAndFamily
= DEFAULT_PITCH
| ff_family
;
331 wxStrncpy(logFont
->lfFaceName
, ff_face
, WXSIZEOF(logFont
->lfFaceName
));
334 wxFont
wxCreateFontFromLogFont(const LOGFONT
*logFont
)
336 // extract family from pitch-and-family
337 int lfFamily
= logFont
->lfPitchAndFamily
;
338 if ( lfFamily
& FIXED_PITCH
)
339 lfFamily
-= FIXED_PITCH
;
340 if ( lfFamily
& VARIABLE_PITCH
)
341 lfFamily
-= VARIABLE_PITCH
;
347 fontFamily
= wxROMAN
;
351 fontFamily
= wxSWISS
;
355 fontFamily
= wxSCRIPT
;
359 fontFamily
= wxMODERN
;
363 fontFamily
= wxDECORATIVE
;
367 fontFamily
= wxSWISS
;
371 int fontWeight
= wxNORMAL
;
372 switch ( logFont
->lfWeight
)
375 fontWeight
= wxLIGHT
;
380 fontWeight
= wxNORMAL
;
388 int fontStyle
= logFont
->lfItalic
? wxITALIC
: wxNORMAL
;
390 bool fontUnderline
= logFont
->lfUnderline
!= 0;
392 wxString fontFace
= logFont
->lfFaceName
;
395 HDC dc
= ::GetDC(NULL
);
397 // remember that 1pt = 1/72inch
398 int height
= abs(logFont
->lfHeight
);
399 int fontPoints
= (72*height
)/GetDeviceCaps(dc
, LOGPIXELSY
);
401 ::ReleaseDC(NULL
, dc
);
403 wxFontEncoding fontEncoding
;
404 switch ( logFont
->lfCharSet
)
407 wxFAIL_MSG(wxT("unsupported charset"));
411 fontEncoding
= wxFONTENCODING_CP1252
;
415 case EASTEUROPE_CHARSET
:
416 fontEncoding
= wxFONTENCODING_CP1250
;
420 fontEncoding
= wxFONTENCODING_CP1257
;
423 case RUSSIAN_CHARSET
:
424 fontEncoding
= wxFONTENCODING_CP1251
;
428 fontEncoding
= wxFONTENCODING_CP1256
;
432 fontEncoding
= wxFONTENCODING_CP1253
;
436 fontEncoding
= wxFONTENCODING_CP1255
;
439 case TURKISH_CHARSET
:
440 fontEncoding
= wxFONTENCODING_CP1254
;
444 fontEncoding
= wxFONTENCODING_CP437
;
449 fontEncoding
= wxFONTENCODING_CP437
;
453 return wxFont(fontPoints
, fontFamily
, fontStyle
,
454 fontWeight
, fontUnderline
, fontFace
,