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
45 // encodingid;facename[;charset]
47 bool wxNativeEncodingInfo::FromString(const wxString
& s
)
49 wxStringTokenizer
tokenizer(s
, _T(";"));
51 wxString encid
= tokenizer
.GetNextToken();
53 if ( !encid
.ToLong(&enc
) )
55 encoding
= (wxFontEncoding
)enc
;
57 facename
= tokenizer
.GetNextToken();
61 wxString tmp
= tokenizer
.GetNextToken();
64 // default charset (don't use DEFAULT_CHARSET though because of subtle
65 // Windows 9x/NT differences in handling it)
66 // TODO: what is this for OS/2?
67 // charset = ANSI_CHARSET;
71 if ( wxSscanf(tmp
, _T("%u"), &charset
) != 1 )
73 // should be a number!
81 wxString
wxNativeEncodingInfo::ToString() const
85 s
<< (long)encoding
<< _T(';') << facename
;
87 // TODO: what is this for OS/2?
89 if ( charset != ANSI_CHARSET )
91 s << _T(';') << charset;
97 // ----------------------------------------------------------------------------
99 // ----------------------------------------------------------------------------
101 bool wxGetNativeFontEncoding(wxFontEncoding encoding
,
102 wxNativeEncodingInfo
*info
)
104 wxCHECK_MSG( info
, FALSE
, _T("bad pointer in wxGetNativeFontEncoding") );
106 if ( encoding
== wxFONTENCODING_DEFAULT
)
108 encoding
= wxFont::GetDefaultEncoding();
113 // TODO: fix this for OS2
115 // although this function is supposed to return an exact match, do do
116 // some mappings here for the most common case of "standard" encoding
117 case wxFONTENCODING_SYSTEM:
118 case wxFONTENCODING_ISO8859_1:
119 case wxFONTENCODING_ISO8859_15:
120 case wxFONTENCODING_CP1252:
121 info->charset = ANSI_CHARSET;
124 case wxFONTENCODING_CP1250:
125 info->charset = EASTEUROPE_CHARSET;
128 case wxFONTENCODING_CP1251:
129 info->charset = RUSSIAN_CHARSET;
132 case wxFONTENCODING_CP1253:
133 info->charset = GREEK_CHARSET;
136 case wxFONTENCODING_CP1254:
137 info->charset = TURKISH_CHARSET;
140 case wxFONTENCODING_CP1255:
141 info->charset = HEBREW_CHARSET;
144 case wxFONTENCODING_CP1256:
145 info->charset = ARABIC_CHARSET;
148 case wxFONTENCODING_CP1257:
149 info->charset = BALTIC_CHARSET;
152 case wxFONTENCODING_CP874:
153 info->charset = THAI_CHARSET;
156 case wxFONTENCODING_CP437:
157 info->charset = OEM_CHARSET;
161 // no way to translate this encoding into a Windows charset
168 bool wxTestFontEncoding(const wxNativeEncodingInfo
& info
)
172 // try to create such font
174 wxZeroMemory(lf); // all default values
176 lf.lfCharSet = info.charset;
177 strncpy(lf.lfFaceName, info.facename, sizeof(lf.lfFaceName));
179 HFONT hfont = ::CreateFontIndirect(&lf);
186 ::DeleteObject((HGDIOBJ)hfont);
191 // ----------------------------------------------------------------------------
192 // wxFont <-> LOGFONT conversion
193 // ----------------------------------------------------------------------------
196 void wxFillLogFont(LOGFONT
*logFont
, const wxFont
*font
)
201 switch ( font
->GetFamily() )
204 ff_family
= FF_SCRIPT
;
205 ff_face
= _T("Script");
209 ff_family
= FF_DECORATIVE
;
213 ff_family
= FF_ROMAN
;
214 ff_face
= _T("Times New Roman");
219 ff_family
= FF_MODERN
;
220 ff_face
= _T("Courier New");
224 ff_family
= FF_SWISS
;
225 ff_face
= _T("Arial");
230 ff_family
= FF_SWISS
;
231 ff_face
= _T("MS Sans Serif");
235 switch ( font
->GetStyle() )
243 wxFAIL_MSG(wxT("unknown font slant"));
251 switch ( font
->GetWeight() )
254 wxFAIL_MSG(_T("unknown font weight"));
258 ff_weight
= FW_NORMAL
;
262 ff_weight
= FW_LIGHT
;
271 HDC dc
= ::GetDC(NULL
);
272 int ppInch
= ::GetDeviceCaps(dc
, LOGPIXELSY
);
273 ::ReleaseDC(NULL
, dc
);
275 // New behaviour: apparently ppInch varies according to Large/Small Fonts
276 // setting in Windows. This messes up fonts. So, set ppInch to a constant
278 static const int ppInch
= 96;
281 #if wxFONT_SIZE_COMPATIBILITY
282 // Incorrect, but compatible with old wxWindows behaviour
283 int nHeight
= (font
->GetPointSize()*ppInch
/72);
285 // Correct for Windows compatibility
286 int nHeight
= - (font
->GetPointSize()*ppInch
/72);
289 wxString facename
= font
->GetFaceName();
294 //else: ff_face is a reasonable default facename for this font family
296 // deal with encoding now
297 wxNativeEncodingInfo info
;
298 wxFontEncoding encoding
= font
->GetEncoding();
299 if ( !wxGetNativeFontEncoding(encoding
, &info
) )
301 if ( !wxTheFontMapper
->GetAltForEncoding(encoding
, &info
) )
303 // unsupported encoding, replace with the default
304 info
.charset
= ANSI_CHARSET
;
308 if ( !info
.facename
.IsEmpty() )
310 // the facename determined by the encoding overrides everything else
311 ff_face
= info
.facename
;
314 // transfer all the data to LOGFONT
315 logFont
->lfHeight
= nHeight
;
316 logFont
->lfWidth
= 0;
317 logFont
->lfEscapement
= 0;
318 logFont
->lfOrientation
= 0;
319 logFont
->lfWeight
= ff_weight
;
320 logFont
->lfItalic
= ff_italic
;
321 logFont
->lfUnderline
= (BYTE
)font
->GetUnderlined();
322 logFont
->lfStrikeOut
= 0;
323 logFont
->lfCharSet
= info
.charset
;
324 logFont
->lfOutPrecision
= OUT_DEFAULT_PRECIS
;
325 logFont
->lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
326 logFont
->lfQuality
= PROOF_QUALITY
;
327 logFont
->lfPitchAndFamily
= DEFAULT_PITCH
| ff_family
;
328 wxStrncpy(logFont
->lfFaceName
, ff_face
, WXSIZEOF(logFont
->lfFaceName
));
331 wxFont
wxCreateFontFromLogFont(const LOGFONT
*logFont
)
333 // extract family from pitch-and-family
334 int lfFamily
= logFont
->lfPitchAndFamily
;
335 if ( lfFamily
& FIXED_PITCH
)
336 lfFamily
-= FIXED_PITCH
;
337 if ( lfFamily
& VARIABLE_PITCH
)
338 lfFamily
-= VARIABLE_PITCH
;
344 fontFamily
= wxROMAN
;
348 fontFamily
= wxSWISS
;
352 fontFamily
= wxSCRIPT
;
356 fontFamily
= wxMODERN
;
360 fontFamily
= wxDECORATIVE
;
364 fontFamily
= wxSWISS
;
368 int fontWeight
= wxNORMAL
;
369 switch ( logFont
->lfWeight
)
372 fontWeight
= wxLIGHT
;
377 fontWeight
= wxNORMAL
;
385 int fontStyle
= logFont
->lfItalic
? wxITALIC
: wxNORMAL
;
387 bool fontUnderline
= logFont
->lfUnderline
!= 0;
389 wxString fontFace
= logFont
->lfFaceName
;
392 HDC dc
= ::GetDC(NULL
);
394 // remember that 1pt = 1/72inch
395 int height
= abs(logFont
->lfHeight
);
396 int fontPoints
= (72*height
)/GetDeviceCaps(dc
, LOGPIXELSY
);
398 ::ReleaseDC(NULL
, dc
);
400 wxFontEncoding fontEncoding
;
401 switch ( logFont
->lfCharSet
)
404 wxFAIL_MSG(wxT("unsupported charset"));
408 fontEncoding
= wxFONTENCODING_CP1252
;
412 case EASTEUROPE_CHARSET
:
413 fontEncoding
= wxFONTENCODING_CP1250
;
417 fontEncoding
= wxFONTENCODING_CP1257
;
420 case RUSSIAN_CHARSET
:
421 fontEncoding
= wxFONTENCODING_CP1251
;
425 fontEncoding
= wxFONTENCODING_CP1256
;
429 fontEncoding
= wxFONTENCODING_CP1253
;
433 fontEncoding
= wxFONTENCODING_CP1255
;
436 case TURKISH_CHARSET
:
437 fontEncoding
= wxFONTENCODING_CP1254
;
441 fontEncoding
= wxFONTENCODING_CP437
;
446 fontEncoding
= wxFONTENCODING_CP437
;
450 return wxFont(fontPoints
, fontFamily
, fontStyle
,
451 fontWeight
, fontUnderline
, fontFace
,