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
164 bool wxTestFontEncoding(const wxNativeEncodingInfo
& info
)
166 // try to create such font
168 wxZeroMemory(lf
); // all default values
170 lf
.lfCharSet
= info
.charset
;
171 strncpy(lf
.lfFaceName
, info
.facename
, sizeof(lf
.lfFaceName
));
173 HFONT hfont
= ::CreateFontIndirect(&lf
);
180 ::DeleteObject((HGDIOBJ
)hfont
);
185 // ----------------------------------------------------------------------------
186 // wxFont <-> LOGFONT conversion
187 // ----------------------------------------------------------------------------
189 void wxFillLogFont(LOGFONT
*logFont
, const wxFont
*font
)
194 switch ( font
->GetFamily() )
197 ff_family
= FF_SCRIPT
;
198 ff_face
= _T("Script");
202 ff_family
= FF_DECORATIVE
;
206 ff_family
= FF_ROMAN
;
207 ff_face
= _T("Times New Roman");
212 ff_family
= FF_MODERN
;
213 ff_face
= _T("Courier New");
217 ff_family
= FF_SWISS
;
218 ff_face
= _T("Arial");
223 ff_family
= FF_SWISS
;
224 ff_face
= _T("MS Sans Serif");
228 switch ( font
->GetStyle() )
236 wxFAIL_MSG(wxT("unknown font slant"));
244 switch ( font
->GetWeight() )
247 wxFAIL_MSG(_T("unknown font weight"));
251 ff_weight
= FW_NORMAL
;
255 ff_weight
= FW_LIGHT
;
264 HDC dc
= ::GetDC(NULL
);
265 int ppInch
= ::GetDeviceCaps(dc
, LOGPIXELSY
);
266 ::ReleaseDC(NULL
, dc
);
268 // New behaviour: apparently ppInch varies according to Large/Small Fonts
269 // setting in Windows. This messes up fonts. So, set ppInch to a constant
271 static const int ppInch
= 96;
274 #if wxFONT_SIZE_COMPATIBILITY
275 // Incorrect, but compatible with old wxWindows behaviour
276 int nHeight
= (font
->GetPointSize()*ppInch
/72);
278 // Correct for Windows compatibility
279 int nHeight
= - (font
->GetPointSize()*ppInch
/72);
282 wxString facename
= font
->GetFaceName();
287 //else: ff_face is a reasonable default facename for this font family
289 // deal with encoding now
290 wxNativeEncodingInfo info
;
291 wxFontEncoding encoding
= font
->GetEncoding();
292 if ( !wxGetNativeFontEncoding(encoding
, &info
) )
294 if ( !wxTheFontMapper
->GetAltForEncoding(encoding
, &info
) )
296 // unsupported encoding, replace with the default
297 info
.charset
= ANSI_CHARSET
;
301 if ( !info
.facename
.IsEmpty() )
303 // the facename determined by the encoding overrides everything else
304 ff_face
= info
.facename
;
307 // transfer all the data to LOGFONT
308 logFont
->lfHeight
= nHeight
;
309 logFont
->lfWidth
= 0;
310 logFont
->lfEscapement
= 0;
311 logFont
->lfOrientation
= 0;
312 logFont
->lfWeight
= ff_weight
;
313 logFont
->lfItalic
= ff_italic
;
314 logFont
->lfUnderline
= (BYTE
)font
->GetUnderlined();
315 logFont
->lfStrikeOut
= 0;
316 logFont
->lfCharSet
= info
.charset
;
317 logFont
->lfOutPrecision
= OUT_DEFAULT_PRECIS
;
318 logFont
->lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
319 logFont
->lfQuality
= PROOF_QUALITY
;
320 logFont
->lfPitchAndFamily
= DEFAULT_PITCH
| ff_family
;
321 wxStrncpy(logFont
->lfFaceName
, ff_face
, WXSIZEOF(logFont
->lfFaceName
));
324 wxFont
wxCreateFontFromLogFont(const LOGFONT
*logFont
)
326 // extract family from pitch-and-family
327 int lfFamily
= logFont
->lfPitchAndFamily
;
328 if ( lfFamily
& FIXED_PITCH
)
329 lfFamily
-= FIXED_PITCH
;
330 if ( lfFamily
& VARIABLE_PITCH
)
331 lfFamily
-= VARIABLE_PITCH
;
337 fontFamily
= wxROMAN
;
341 fontFamily
= wxSWISS
;
345 fontFamily
= wxSCRIPT
;
349 fontFamily
= wxMODERN
;
353 fontFamily
= wxDECORATIVE
;
357 fontFamily
= wxSWISS
;
361 int fontWeight
= wxNORMAL
;
362 switch ( logFont
->lfWeight
)
365 fontWeight
= wxLIGHT
;
370 fontWeight
= wxNORMAL
;
378 int fontStyle
= logFont
->lfItalic
? wxITALIC
: wxNORMAL
;
380 bool fontUnderline
= logFont
->lfUnderline
!= 0;
382 wxString fontFace
= logFont
->lfFaceName
;
385 HDC dc
= ::GetDC(NULL
);
387 // remember that 1pt = 1/72inch
388 int height
= abs(logFont
->lfHeight
);
389 int fontPoints
= (72*height
)/GetDeviceCaps(dc
, LOGPIXELSY
);
391 ::ReleaseDC(NULL
, dc
);
393 wxFontEncoding fontEncoding
;
394 switch ( logFont
->lfCharSet
)
397 wxFAIL_MSG(wxT("unsupported charset"));
401 fontEncoding
= wxFONTENCODING_CP1252
;
405 case EASTEUROPE_CHARSET
:
406 fontEncoding
= wxFONTENCODING_CP1250
;
410 fontEncoding
= wxFONTENCODING_CP1257
;
413 case RUSSIAN_CHARSET
:
414 fontEncoding
= wxFONTENCODING_CP1251
;
418 fontEncoding
= wxFONTENCODING_CP1256
;
422 fontEncoding
= wxFONTENCODING_CP1253
;
426 fontEncoding
= wxFONTENCODING_CP1255
;
429 case TURKISH_CHARSET
:
430 fontEncoding
= wxFONTENCODING_CP1254
;
434 fontEncoding
= wxFONTENCODING_CP437
;
439 fontEncoding
= wxFONTENCODING_CP437
;
443 return wxFont(fontPoints
, fontFamily
, fontStyle
,
444 fontWeight
, fontUnderline
, fontFace
,