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
55 bool wxNativeEncodingInfo::FromString(const wxString
& s
)
57 wxStringTokenizer
tokenizer(s
, _T(";"));
59 facename
= tokenizer
.GetNextToken();
63 wxString tmp
= tokenizer
.GetNextToken();
66 // default charset (don't use DEFAULT_CHARSET though because of subtle
67 // Windows 9x/NT differences in handling it)
68 charset
= ANSI_CHARSET
;
72 if ( wxSscanf(tmp
, _T("%u"), &charset
) != 1 )
74 // should be a number!
82 wxString
wxNativeEncodingInfo::ToString() const
85 if ( charset
!= ANSI_CHARSET
)
87 s
<< _T(';') << charset
;
93 // ----------------------------------------------------------------------------
95 // ----------------------------------------------------------------------------
97 bool wxGetNativeFontEncoding(wxFontEncoding encoding
,
98 wxNativeEncodingInfo
*info
)
100 wxCHECK_MSG( info
, FALSE
, _T("bad pointer in wxGetNativeFontEncoding") );
102 if ( encoding
== wxFONTENCODING_DEFAULT
)
104 encoding
= wxFont::GetDefaultEncoding();
109 // although this function is supposed to return an exact match, do do
110 // some mappings here for the most common case of "standard" encoding
111 case wxFONTENCODING_SYSTEM
:
112 case wxFONTENCODING_ISO8859_1
:
113 case wxFONTENCODING_ISO8859_15
:
114 case wxFONTENCODING_CP1252
:
115 info
->charset
= ANSI_CHARSET
;
118 #if !defined(__WIN16__)
119 case wxFONTENCODING_CP1250
:
120 info
->charset
= EASTEUROPE_CHARSET
;
123 case wxFONTENCODING_CP1251
:
124 info
->charset
= RUSSIAN_CHARSET
;
127 case wxFONTENCODING_CP1253
:
128 info
->charset
= GREEK_CHARSET
;
131 case wxFONTENCODING_CP1254
:
132 info
->charset
= TURKISH_CHARSET
;
135 case wxFONTENCODING_CP1255
:
136 info
->charset
= HEBREW_CHARSET
;
139 case wxFONTENCODING_CP1256
:
140 info
->charset
= ARABIC_CHARSET
;
143 case wxFONTENCODING_CP1257
:
144 info
->charset
= BALTIC_CHARSET
;
148 case wxFONTENCODING_CP437
:
149 info
->charset
= OEM_CHARSET
;
153 // no way to translate this encoding into a Windows charset
160 bool wxTestFontEncoding(const wxNativeEncodingInfo
& info
)
162 // try to create such font
164 wxZeroMemory(lf
); // all default values
166 lf
.lfCharSet
= info
.charset
;
167 strncpy(lf
.lfFaceName
, info
.facename
, sizeof(lf
.lfFaceName
));
169 HFONT hfont
= ::CreateFontIndirect(&lf
);
176 ::DeleteObject((HGDIOBJ
)hfont
);
181 // ----------------------------------------------------------------------------
182 // wxFont <-> LOGFONT conversion
183 // ----------------------------------------------------------------------------
185 void wxFillLogFont(LOGFONT
*logFont
, const wxFont
*font
)
190 switch ( font
->GetFamily() )
193 ff_family
= FF_SCRIPT
;
194 ff_face
= _T("Script");
198 ff_family
= FF_DECORATIVE
;
202 ff_family
= FF_ROMAN
;
203 ff_face
= _T("Times New Roman");
208 ff_family
= FF_MODERN
;
209 ff_face
= _T("Courier New");
213 ff_family
= FF_SWISS
;
214 ff_face
= _T("Arial");
219 ff_family
= FF_SWISS
;
220 ff_face
= _T("MS Sans Serif");
224 switch ( font
->GetStyle() )
232 wxFAIL_MSG(wxT("unknown font slant"));
240 switch ( font
->GetWeight() )
243 wxFAIL_MSG(_T("unknown font weight"));
247 ff_weight
= FW_NORMAL
;
251 ff_weight
= FW_LIGHT
;
260 HDC dc
= ::GetDC(NULL
);
261 int ppInch
= ::GetDeviceCaps(dc
, LOGPIXELSY
);
262 ::ReleaseDC(NULL
, dc
);
264 // New behaviour: apparently ppInch varies according to Large/Small Fonts
265 // setting in Windows. This messes up fonts. So, set ppInch to a constant
267 static const int ppInch
= 96;
270 #if wxFONT_SIZE_COMPATIBILITY
271 // Incorrect, but compatible with old wxWindows behaviour
272 int nHeight
= (font
->GetPointSize()*ppInch
/72);
274 // Correct for Windows compatibility
275 int nHeight
= - (font
->GetPointSize()*ppInch
/72);
278 wxString facename
= font
->GetFaceName();
283 //else: ff_face is a reasonable default facename for this font family
285 // deal with encoding now
286 wxNativeEncodingInfo info
;
287 wxFontEncoding encoding
= font
->GetEncoding();
288 if ( !wxGetNativeFontEncoding(encoding
, &info
) )
290 if ( !wxTheFontMapper
->GetAltForEncoding(encoding
, &info
) )
292 // unsupported encoding, replace with the default
293 info
.charset
= ANSI_CHARSET
;
297 if ( !info
.facename
.IsEmpty() )
299 // the facename determined by the encoding overrides everything else
300 ff_face
= info
.facename
;
303 // transfer all the data to LOGFONT
304 logFont
->lfHeight
= nHeight
;
305 logFont
->lfWidth
= 0;
306 logFont
->lfEscapement
= 0;
307 logFont
->lfOrientation
= 0;
308 logFont
->lfWeight
= ff_weight
;
309 logFont
->lfItalic
= ff_italic
;
310 logFont
->lfUnderline
= (BYTE
)font
->GetUnderlined();
311 logFont
->lfStrikeOut
= 0;
312 logFont
->lfCharSet
= info
.charset
;
313 logFont
->lfOutPrecision
= OUT_DEFAULT_PRECIS
;
314 logFont
->lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
315 logFont
->lfQuality
= PROOF_QUALITY
;
316 logFont
->lfPitchAndFamily
= DEFAULT_PITCH
| ff_family
;
317 wxStrncpy(logFont
->lfFaceName
, ff_face
, WXSIZEOF(logFont
->lfFaceName
));
320 wxFont
wxCreateFontFromLogFont(const LOGFONT
*logFont
)
322 // extract family from pitch-and-family
323 int lfFamily
= logFont
->lfPitchAndFamily
;
324 if ( lfFamily
& FIXED_PITCH
)
325 lfFamily
-= FIXED_PITCH
;
326 if ( lfFamily
& VARIABLE_PITCH
)
327 lfFamily
-= VARIABLE_PITCH
;
333 fontFamily
= wxROMAN
;
337 fontFamily
= wxSWISS
;
341 fontFamily
= wxSCRIPT
;
345 fontFamily
= wxMODERN
;
349 fontFamily
= wxDECORATIVE
;
353 fontFamily
= wxSWISS
;
357 int fontWeight
= wxNORMAL
;
358 switch ( logFont
->lfWeight
)
361 fontWeight
= wxLIGHT
;
366 fontWeight
= wxNORMAL
;
374 int fontStyle
= logFont
->lfItalic
? wxITALIC
: wxNORMAL
;
376 bool fontUnderline
= logFont
->lfUnderline
!= 0;
378 wxString fontFace
= logFont
->lfFaceName
;
381 HDC dc
= ::GetDC(NULL
);
383 // remember that 1pt = 1/72inch
384 int height
= abs(logFont
->lfHeight
);
385 int fontPoints
= (72*height
)/GetDeviceCaps(dc
, LOGPIXELSY
);
387 ::ReleaseDC(NULL
, dc
);
389 wxFontEncoding fontEncoding
;
390 switch ( logFont
->lfCharSet
)
393 wxFAIL_MSG(wxT("unsupported charset"));
397 fontEncoding
= wxFONTENCODING_CP1252
;
401 case EASTEUROPE_CHARSET
:
402 fontEncoding
= wxFONTENCODING_CP1250
;
406 fontEncoding
= wxFONTENCODING_CP1257
;
409 case RUSSIAN_CHARSET
:
410 fontEncoding
= wxFONTENCODING_CP1251
;
414 fontEncoding
= wxFONTENCODING_CP1256
;
418 fontEncoding
= wxFONTENCODING_CP1253
;
422 fontEncoding
= wxFONTENCODING_CP1255
;
425 case TURKISH_CHARSET
:
426 fontEncoding
= wxFONTENCODING_CP1254
;
431 fontEncoding
= wxFONTENCODING_CP437
;
435 return wxFont(fontPoints
, fontFamily
, fontStyle
,
436 fontWeight
, fontUnderline
, fontFace
,