1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: msw/fontutil.cpp
3 // Purpose: font-related helper functions for wxMSW
4 // Author: Modified by David Webster for OS/2
8 // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
24 #include "wx/string.h"
29 #include "wx/os2/private.h"
31 #include "wx/fontutil.h"
32 #include "wx/fontmap.h"
34 #include "wx/tokenzr.h"
36 // ============================================================================
38 // ============================================================================
40 // ----------------------------------------------------------------------------
41 // wxNativeEncodingInfo
42 // ----------------------------------------------------------------------------
44 // convert to/from the string representation: format is
47 bool wxNativeEncodingInfo::FromString(const wxString
& s
)
49 wxStringTokenizer
tokenizer(s
, _T(";"));
51 facename
= tokenizer
.GetNextToken();
55 wxString tmp
= tokenizer
.GetNextToken();
58 // default charset (don't use DEFAULT_CHARSET though because of subtle
59 // Windows 9x/NT differences in handling it)
60 // TODO: what is this for OS/2?
61 // charset = ANSI_CHARSET;
65 if ( wxSscanf(tmp
, _T("%u"), &charset
) != 1 )
67 // should be a number!
75 wxString
wxNativeEncodingInfo::ToString() const
78 // TODO: what is this for OS/2?
80 if ( charset != ANSI_CHARSET )
82 s << _T(';') << charset;
88 // ----------------------------------------------------------------------------
90 // ----------------------------------------------------------------------------
92 bool wxGetNativeFontEncoding(wxFontEncoding encoding
,
93 wxNativeEncodingInfo
*info
)
95 wxCHECK_MSG( info
, FALSE
, _T("bad pointer in wxGetNativeFontEncoding") );
97 if ( encoding
== wxFONTENCODING_DEFAULT
)
99 encoding
= wxFont::GetDefaultEncoding();
104 // TODO: fix this for OS2
106 // although this function is supposed to return an exact match, do do
107 // some mappings here for the most common case of "standard" encoding
108 case wxFONTENCODING_SYSTEM:
109 case wxFONTENCODING_ISO8859_1:
110 case wxFONTENCODING_ISO8859_15:
111 case wxFONTENCODING_CP1252:
112 info->charset = ANSI_CHARSET;
115 case wxFONTENCODING_CP1250:
116 info->charset = EASTEUROPE_CHARSET;
119 case wxFONTENCODING_CP1251:
120 info->charset = RUSSIAN_CHARSET;
123 case wxFONTENCODING_CP1253:
124 info->charset = GREEK_CHARSET;
127 case wxFONTENCODING_CP1254:
128 info->charset = TURKISH_CHARSET;
131 case wxFONTENCODING_CP1255:
132 info->charset = HEBREW_CHARSET;
135 case wxFONTENCODING_CP1256:
136 info->charset = ARABIC_CHARSET;
139 case wxFONTENCODING_CP1257:
140 info->charset = BALTIC_CHARSET;
143 case wxFONTENCODING_CP874:
144 info->charset = THAI_CHARSET;
147 case wxFONTENCODING_CP437:
148 info->charset = OEM_CHARSET;
152 // no way to translate this encoding into a Windows charset
159 bool wxTestFontEncoding(const wxNativeEncodingInfo
& info
)
163 // try to create such font
165 wxZeroMemory(lf); // all default values
167 lf.lfCharSet = info.charset;
168 strncpy(lf.lfFaceName, info.facename, sizeof(lf.lfFaceName));
170 HFONT hfont = ::CreateFontIndirect(&lf);
177 ::DeleteObject((HGDIOBJ)hfont);
182 // ----------------------------------------------------------------------------
183 // wxFont <-> LOGFONT conversion
184 // ----------------------------------------------------------------------------
187 void wxFillLogFont(LOGFONT
*logFont
, const wxFont
*font
)
192 switch ( font
->GetFamily() )
195 ff_family
= FF_SCRIPT
;
196 ff_face
= _T("Script");
200 ff_family
= FF_DECORATIVE
;
204 ff_family
= FF_ROMAN
;
205 ff_face
= _T("Times New Roman");
210 ff_family
= FF_MODERN
;
211 ff_face
= _T("Courier New");
215 ff_family
= FF_SWISS
;
216 ff_face
= _T("Arial");
221 ff_family
= FF_SWISS
;
222 ff_face
= _T("MS Sans Serif");
226 switch ( font
->GetStyle() )
234 wxFAIL_MSG(wxT("unknown font slant"));
242 switch ( font
->GetWeight() )
245 wxFAIL_MSG(_T("unknown font weight"));
249 ff_weight
= FW_NORMAL
;
253 ff_weight
= FW_LIGHT
;
262 HDC dc
= ::GetDC(NULL
);
263 int ppInch
= ::GetDeviceCaps(dc
, LOGPIXELSY
);
264 ::ReleaseDC(NULL
, dc
);
266 // New behaviour: apparently ppInch varies according to Large/Small Fonts
267 // setting in Windows. This messes up fonts. So, set ppInch to a constant
269 static const int ppInch
= 96;
272 #if wxFONT_SIZE_COMPATIBILITY
273 // Incorrect, but compatible with old wxWindows behaviour
274 int nHeight
= (font
->GetPointSize()*ppInch
/72);
276 // Correct for Windows compatibility
277 int nHeight
= - (font
->GetPointSize()*ppInch
/72);
280 wxString facename
= font
->GetFaceName();
285 //else: ff_face is a reasonable default facename for this font family
287 // deal with encoding now
288 wxNativeEncodingInfo info
;
289 wxFontEncoding encoding
= font
->GetEncoding();
290 if ( !wxGetNativeFontEncoding(encoding
, &info
) )
292 if ( !wxTheFontMapper
->GetAltForEncoding(encoding
, &info
) )
294 // unsupported encoding, replace with the default
295 info
.charset
= ANSI_CHARSET
;
299 if ( !info
.facename
.IsEmpty() )
301 // the facename determined by the encoding overrides everything else
302 ff_face
= info
.facename
;
305 // transfer all the data to LOGFONT
306 logFont
->lfHeight
= nHeight
;
307 logFont
->lfWidth
= 0;
308 logFont
->lfEscapement
= 0;
309 logFont
->lfOrientation
= 0;
310 logFont
->lfWeight
= ff_weight
;
311 logFont
->lfItalic
= ff_italic
;
312 logFont
->lfUnderline
= (BYTE
)font
->GetUnderlined();
313 logFont
->lfStrikeOut
= 0;
314 logFont
->lfCharSet
= info
.charset
;
315 logFont
->lfOutPrecision
= OUT_DEFAULT_PRECIS
;
316 logFont
->lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
317 logFont
->lfQuality
= PROOF_QUALITY
;
318 logFont
->lfPitchAndFamily
= DEFAULT_PITCH
| ff_family
;
319 wxStrncpy(logFont
->lfFaceName
, ff_face
, WXSIZEOF(logFont
->lfFaceName
));
322 wxFont
wxCreateFontFromLogFont(const LOGFONT
*logFont
)
324 // extract family from pitch-and-family
325 int lfFamily
= logFont
->lfPitchAndFamily
;
326 if ( lfFamily
& FIXED_PITCH
)
327 lfFamily
-= FIXED_PITCH
;
328 if ( lfFamily
& VARIABLE_PITCH
)
329 lfFamily
-= VARIABLE_PITCH
;
335 fontFamily
= wxROMAN
;
339 fontFamily
= wxSWISS
;
343 fontFamily
= wxSCRIPT
;
347 fontFamily
= wxMODERN
;
351 fontFamily
= wxDECORATIVE
;
355 fontFamily
= wxSWISS
;
359 int fontWeight
= wxNORMAL
;
360 switch ( logFont
->lfWeight
)
363 fontWeight
= wxLIGHT
;
368 fontWeight
= wxNORMAL
;
376 int fontStyle
= logFont
->lfItalic
? wxITALIC
: wxNORMAL
;
378 bool fontUnderline
= logFont
->lfUnderline
!= 0;
380 wxString fontFace
= logFont
->lfFaceName
;
383 HDC dc
= ::GetDC(NULL
);
385 // remember that 1pt = 1/72inch
386 int height
= abs(logFont
->lfHeight
);
387 int fontPoints
= (72*height
)/GetDeviceCaps(dc
, LOGPIXELSY
);
389 ::ReleaseDC(NULL
, dc
);
391 wxFontEncoding fontEncoding
;
392 switch ( logFont
->lfCharSet
)
395 wxFAIL_MSG(wxT("unsupported charset"));
399 fontEncoding
= wxFONTENCODING_CP1252
;
403 case EASTEUROPE_CHARSET
:
404 fontEncoding
= wxFONTENCODING_CP1250
;
408 fontEncoding
= wxFONTENCODING_CP1257
;
411 case RUSSIAN_CHARSET
:
412 fontEncoding
= wxFONTENCODING_CP1251
;
416 fontEncoding
= wxFONTENCODING_CP1256
;
420 fontEncoding
= wxFONTENCODING_CP1253
;
424 fontEncoding
= wxFONTENCODING_CP1255
;
427 case TURKISH_CHARSET
:
428 fontEncoding
= wxFONTENCODING_CP1254
;
432 fontEncoding
= wxFONTENCODING_CP437
;
437 fontEncoding
= wxFONTENCODING_CP437
;
441 return wxFont(fontPoints
, fontFamily
, fontStyle
,
442 fontWeight
, fontUnderline
, fontFace
,