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 // ----------------------------------------------------------------------------
21 #pragma implementation "fontutil.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
28 #include "wx/string.h"
33 #include "wx/os2/private.h"
35 #include "wx/fontutil.h"
36 #include "wx/fontmap.h"
38 #include "wx/tokenzr.h"
40 // ============================================================================
42 // ============================================================================
44 // ----------------------------------------------------------------------------
45 // wxNativeEncodingInfo
46 // ----------------------------------------------------------------------------
48 // convert to/from the string representation: format is
49 // encodingid;facename[;charset]
51 bool wxNativeEncodingInfo::FromString(const wxString
& s
)
53 wxStringTokenizer
tokenizer(s
, _T(";"));
55 wxString encid
= tokenizer
.GetNextToken();
57 if ( !encid
.ToLong(&enc
) )
59 encoding
= (wxFontEncoding
)enc
;
61 facename
= tokenizer
.GetNextToken();
65 wxString tmp
= tokenizer
.GetNextToken();
68 // default charset (don't use DEFAULT_CHARSET though because of subtle
69 // Windows 9x/NT differences in handling it)
70 // TODO: what is this for OS/2?
71 // charset = ANSI_CHARSET;
75 if ( wxSscanf(tmp
, _T("%u"), &charset
) != 1 )
77 // should be a number!
85 wxString
wxNativeEncodingInfo::ToString() const
89 s
<< (long)encoding
<< _T(';') << facename
;
91 // TODO: what is this for OS/2?
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 // TODO: fix this for OS2
119 // although this function is supposed to return an exact match, do do
120 // some mappings here for the most common case of "standard" encoding
121 case wxFONTENCODING_SYSTEM:
122 case wxFONTENCODING_ISO8859_1:
123 case wxFONTENCODING_ISO8859_15:
124 case wxFONTENCODING_CP1252:
125 info->charset = ANSI_CHARSET;
128 case wxFONTENCODING_CP1250:
129 info->charset = EASTEUROPE_CHARSET;
132 case wxFONTENCODING_CP1251:
133 info->charset = RUSSIAN_CHARSET;
136 case wxFONTENCODING_CP1253:
137 info->charset = GREEK_CHARSET;
140 case wxFONTENCODING_CP1254:
141 info->charset = TURKISH_CHARSET;
144 case wxFONTENCODING_CP1255:
145 info->charset = HEBREW_CHARSET;
148 case wxFONTENCODING_CP1256:
149 info->charset = ARABIC_CHARSET;
152 case wxFONTENCODING_CP1257:
153 info->charset = BALTIC_CHARSET;
156 case wxFONTENCODING_CP874:
157 info->charset = THAI_CHARSET;
160 case wxFONTENCODING_CP437:
161 info->charset = OEM_CHARSET;
165 // no way to translate this encoding into a Windows charset
172 bool wxTestFontEncoding(const wxNativeEncodingInfo
& info
)
176 // try to create such font
178 wxZeroMemory(lf); // all default values
180 lf.lfCharSet = info.charset;
181 strncpy(lf.lfFaceName, info.facename, sizeof(lf.lfFaceName));
183 HFONT hfont = ::CreateFontIndirect(&lf);
190 ::DeleteObject((HGDIOBJ)hfont);
195 // ----------------------------------------------------------------------------
196 // wxFont <-> LOGFONT conversion
197 // ----------------------------------------------------------------------------
200 void wxFillLogFont(LOGFONT
*logFont
, const wxFont
*font
)
205 switch ( font
->GetFamily() )
208 ff_family
= FF_SCRIPT
;
209 ff_face
= _T("Script");
213 ff_family
= FF_DECORATIVE
;
217 ff_family
= FF_ROMAN
;
218 ff_face
= _T("Times New Roman");
223 ff_family
= FF_MODERN
;
224 ff_face
= _T("Courier New");
228 ff_family
= FF_SWISS
;
229 ff_face
= _T("Arial");
234 ff_family
= FF_SWISS
;
235 ff_face
= _T("MS Sans Serif");
239 switch ( font
->GetStyle() )
247 wxFAIL_MSG(wxT("unknown font slant"));
255 switch ( font
->GetWeight() )
258 wxFAIL_MSG(_T("unknown font weight"));
262 ff_weight
= FW_NORMAL
;
266 ff_weight
= FW_LIGHT
;
275 HDC dc
= ::GetDC(NULL
);
276 int ppInch
= ::GetDeviceCaps(dc
, LOGPIXELSY
);
277 ::ReleaseDC(NULL
, dc
);
279 // New behaviour: apparently ppInch varies according to Large/Small Fonts
280 // setting in Windows. This messes up fonts. So, set ppInch to a constant
282 static const int ppInch
= 96;
285 #if wxFONT_SIZE_COMPATIBILITY
286 // Incorrect, but compatible with old wxWindows behaviour
287 int nHeight
= (font
->GetPointSize()*ppInch
/72);
289 // Correct for Windows compatibility
290 int nHeight
= - (font
->GetPointSize()*ppInch
/72);
293 wxString facename
= font
->GetFaceName();
298 //else: ff_face is a reasonable default facename for this font family
300 // deal with encoding now
301 wxNativeEncodingInfo info
;
302 wxFontEncoding encoding
= font
->GetEncoding();
303 if ( !wxGetNativeFontEncoding(encoding
, &info
) )
305 if ( !wxTheFontMapper
->GetAltForEncoding(encoding
, &info
) )
307 // unsupported encoding, replace with the default
308 info
.charset
= ANSI_CHARSET
;
312 if ( !info
.facename
.IsEmpty() )
314 // the facename determined by the encoding overrides everything else
315 ff_face
= info
.facename
;
318 // transfer all the data to LOGFONT
319 logFont
->lfHeight
= nHeight
;
320 logFont
->lfWidth
= 0;
321 logFont
->lfEscapement
= 0;
322 logFont
->lfOrientation
= 0;
323 logFont
->lfWeight
= ff_weight
;
324 logFont
->lfItalic
= ff_italic
;
325 logFont
->lfUnderline
= (BYTE
)font
->GetUnderlined();
326 logFont
->lfStrikeOut
= 0;
327 logFont
->lfCharSet
= info
.charset
;
328 logFont
->lfOutPrecision
= OUT_DEFAULT_PRECIS
;
329 logFont
->lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
330 logFont
->lfQuality
= PROOF_QUALITY
;
331 logFont
->lfPitchAndFamily
= DEFAULT_PITCH
| ff_family
;
332 wxStrncpy(logFont
->lfFaceName
, ff_face
, WXSIZEOF(logFont
->lfFaceName
));
335 wxFont
wxCreateFontFromLogFont(const LOGFONT
*logFont
)
337 // extract family from pitch-and-family
338 int lfFamily
= logFont
->lfPitchAndFamily
;
339 if ( lfFamily
& FIXED_PITCH
)
340 lfFamily
-= FIXED_PITCH
;
341 if ( lfFamily
& VARIABLE_PITCH
)
342 lfFamily
-= VARIABLE_PITCH
;
348 fontFamily
= wxROMAN
;
352 fontFamily
= wxSWISS
;
356 fontFamily
= wxSCRIPT
;
360 fontFamily
= wxMODERN
;
364 fontFamily
= wxDECORATIVE
;
368 fontFamily
= wxSWISS
;
372 int fontWeight
= wxNORMAL
;
373 switch ( logFont
->lfWeight
)
376 fontWeight
= wxLIGHT
;
381 fontWeight
= wxNORMAL
;
389 int fontStyle
= logFont
->lfItalic
? wxITALIC
: wxNORMAL
;
391 bool fontUnderline
= logFont
->lfUnderline
!= 0;
393 wxString fontFace
= logFont
->lfFaceName
;
396 HDC dc
= ::GetDC(NULL
);
398 // remember that 1pt = 1/72inch
399 int height
= abs(logFont
->lfHeight
);
400 int fontPoints
= (72*height
)/GetDeviceCaps(dc
, LOGPIXELSY
);
402 ::ReleaseDC(NULL
, dc
);
404 wxFontEncoding fontEncoding
;
405 switch ( logFont
->lfCharSet
)
408 wxFAIL_MSG(wxT("unsupported charset"));
412 fontEncoding
= wxFONTENCODING_CP1252
;
416 case EASTEUROPE_CHARSET
:
417 fontEncoding
= wxFONTENCODING_CP1250
;
421 fontEncoding
= wxFONTENCODING_CP1257
;
424 case RUSSIAN_CHARSET
:
425 fontEncoding
= wxFONTENCODING_CP1251
;
429 fontEncoding
= wxFONTENCODING_CP1256
;
433 fontEncoding
= wxFONTENCODING_CP1253
;
437 fontEncoding
= wxFONTENCODING_CP1255
;
440 case TURKISH_CHARSET
:
441 fontEncoding
= wxFONTENCODING_CP1254
;
445 fontEncoding
= wxFONTENCODING_CP437
;
450 fontEncoding
= wxFONTENCODING_CP437
;
454 return wxFont(fontPoints
, fontFamily
, fontStyle
,
455 fontWeight
, fontUnderline
, fontFace
,