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
;
147 case wxFONTENCODING_CP874
:
148 info
->charset
= THAI_CHARSET
;
152 case wxFONTENCODING_CP437
:
153 info
->charset
= OEM_CHARSET
;
157 // no way to translate this encoding into a Windows charset
161 info
->encoding
= encoding
;
166 bool wxTestFontEncoding(const wxNativeEncodingInfo
& info
)
168 // try to create such font
170 wxZeroMemory(lf
); // all default values
172 lf
.lfCharSet
= info
.charset
;
173 wxStrncpy(lf
.lfFaceName
, info
.facename
, sizeof(lf
.lfFaceName
));
175 HFONT hfont
= ::CreateFontIndirect(&lf
);
182 ::DeleteObject((HGDIOBJ
)hfont
);
187 // ----------------------------------------------------------------------------
188 // wxFont <-> LOGFONT conversion
189 // ----------------------------------------------------------------------------
191 void wxFillLogFont(LOGFONT
*logFont
, const wxFont
*font
)
196 switch ( font
->GetFamily() )
199 ff_family
= FF_SCRIPT
;
200 ff_face
= _T("Script");
204 ff_family
= FF_DECORATIVE
;
208 ff_family
= FF_ROMAN
;
209 ff_face
= _T("Times New Roman");
214 ff_family
= FF_MODERN
;
215 ff_face
= _T("Courier New");
219 ff_family
= FF_SWISS
;
220 ff_face
= _T("Arial");
225 ff_family
= FF_SWISS
;
226 ff_face
= _T("MS Sans Serif");
230 switch ( font
->GetStyle() )
238 wxFAIL_MSG(wxT("unknown font slant"));
246 switch ( font
->GetWeight() )
249 wxFAIL_MSG(_T("unknown font weight"));
253 ff_weight
= FW_NORMAL
;
257 ff_weight
= FW_LIGHT
;
266 HDC dc
= ::GetDC(NULL
);
267 int ppInch
= ::GetDeviceCaps(dc
, LOGPIXELSY
);
268 ::ReleaseDC(NULL
, dc
);
270 // New behaviour: apparently ppInch varies according to Large/Small Fonts
271 // setting in Windows. This messes up fonts. So, set ppInch to a constant
273 static const int ppInch
= 96;
276 #if wxFONT_SIZE_COMPATIBILITY
277 // Incorrect, but compatible with old wxWindows behaviour
278 int nHeight
= (font
->GetPointSize()*ppInch
/72);
280 // Correct for Windows compatibility
281 int nHeight
= - (font
->GetPointSize()*ppInch
/72);
284 wxString facename
= font
->GetFaceName();
289 //else: ff_face is a reasonable default facename for this font family
291 // deal with encoding now
292 wxNativeEncodingInfo info
;
293 wxFontEncoding encoding
= font
->GetEncoding();
294 if ( !wxGetNativeFontEncoding(encoding
, &info
) )
296 if ( !wxTheFontMapper
->GetAltForEncoding(encoding
, &info
) )
298 // unsupported encoding, replace with the default
299 info
.charset
= ANSI_CHARSET
;
303 if ( !info
.facename
.IsEmpty() )
305 // the facename determined by the encoding overrides everything else
306 ff_face
= info
.facename
;
309 // transfer all the data to LOGFONT
310 logFont
->lfHeight
= nHeight
;
311 logFont
->lfWidth
= 0;
312 logFont
->lfEscapement
= 0;
313 logFont
->lfOrientation
= 0;
314 logFont
->lfWeight
= ff_weight
;
315 logFont
->lfItalic
= ff_italic
;
316 logFont
->lfUnderline
= (BYTE
)font
->GetUnderlined();
317 logFont
->lfStrikeOut
= 0;
318 logFont
->lfCharSet
= info
.charset
;
319 logFont
->lfOutPrecision
= OUT_DEFAULT_PRECIS
;
320 logFont
->lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
321 logFont
->lfQuality
= PROOF_QUALITY
;
322 logFont
->lfPitchAndFamily
= DEFAULT_PITCH
| ff_family
;
323 wxStrncpy(logFont
->lfFaceName
, ff_face
, WXSIZEOF(logFont
->lfFaceName
));
326 wxFont
wxCreateFontFromLogFont(const LOGFONT
*logFont
)
328 // extract family from pitch-and-family
329 int lfFamily
= logFont
->lfPitchAndFamily
;
330 if ( lfFamily
& FIXED_PITCH
)
331 lfFamily
-= FIXED_PITCH
;
332 if ( lfFamily
& VARIABLE_PITCH
)
333 lfFamily
-= VARIABLE_PITCH
;
339 fontFamily
= wxROMAN
;
343 fontFamily
= wxSWISS
;
347 fontFamily
= wxSCRIPT
;
351 fontFamily
= wxMODERN
;
355 fontFamily
= wxDECORATIVE
;
359 fontFamily
= wxSWISS
;
363 int fontWeight
= wxNORMAL
;
364 switch ( logFont
->lfWeight
)
367 fontWeight
= wxLIGHT
;
372 fontWeight
= wxNORMAL
;
380 int fontStyle
= logFont
->lfItalic
? wxITALIC
: wxNORMAL
;
382 bool fontUnderline
= logFont
->lfUnderline
!= 0;
384 wxString fontFace
= logFont
->lfFaceName
;
387 HDC dc
= ::GetDC(NULL
);
389 // remember that 1pt = 1/72inch
390 int height
= abs(logFont
->lfHeight
);
391 int fontPoints
= (72*height
)/GetDeviceCaps(dc
, LOGPIXELSY
);
393 ::ReleaseDC(NULL
, dc
);
395 wxFontEncoding fontEncoding
;
396 switch ( logFont
->lfCharSet
)
399 wxFAIL_MSG(wxT("unsupported charset"));
403 fontEncoding
= wxFONTENCODING_CP1252
;
407 case EASTEUROPE_CHARSET
:
408 fontEncoding
= wxFONTENCODING_CP1250
;
412 fontEncoding
= wxFONTENCODING_CP1257
;
415 case RUSSIAN_CHARSET
:
416 fontEncoding
= wxFONTENCODING_CP1251
;
420 fontEncoding
= wxFONTENCODING_CP1256
;
424 fontEncoding
= wxFONTENCODING_CP1253
;
428 fontEncoding
= wxFONTENCODING_CP1255
;
431 case TURKISH_CHARSET
:
432 fontEncoding
= wxFONTENCODING_CP1254
;
436 fontEncoding
= wxFONTENCODING_CP437
;
441 fontEncoding
= wxFONTENCODING_CP437
;
445 return wxFont(fontPoints
, fontFamily
, fontStyle
,
446 fontWeight
, fontUnderline
, fontFace
,