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 ///////////////////////////////////////////////////////////////////////////////
11 #define DEBUG_PRINTF(NAME) { static int raz=0; \
12 printf( #NAME " %i\n",raz); fflush(stdout); \
16 // ============================================================================
18 // ============================================================================
20 // ----------------------------------------------------------------------------
22 // ----------------------------------------------------------------------------
25 #pragma implementation "fontutil.h"
28 // For compilers that support precompilation, includes "wx.h".
29 #include "wx/wxprec.h"
32 #include "wx/string.h"
37 #include "wx/os2/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
53 // encodingid;facename[;charset]
55 bool wxNativeEncodingInfo::FromString(const wxString
& s
)
57 wxStringTokenizer
tokenizer(s
, _T(";"));
59 wxString encid
= tokenizer
.GetNextToken();
61 if ( !encid
.ToLong(&enc
) )
63 encoding
= (wxFontEncoding
)enc
;
65 facename
= tokenizer
.GetNextToken();
69 wxString tmp
= tokenizer
.GetNextToken();
72 // default charset (don't use DEFAULT_CHARSET though because of subtle
73 // Windows 9x/NT differences in handling it)
74 // TODO: what is this for OS/2?
75 // charset = ANSI_CHARSET;
79 if ( wxSscanf(tmp
, _T("%u"), &charset
) != 1 )
81 // should be a number!
89 wxString
wxNativeEncodingInfo::ToString() const
93 s
<< (long)encoding
<< _T(';') << facename
;
95 // TODO: what is this for OS/2?
97 if ( charset != ANSI_CHARSET )
99 s << _T(';') << charset;
105 // ----------------------------------------------------------------------------
107 // ----------------------------------------------------------------------------
109 bool wxGetNativeFontEncoding(wxFontEncoding encoding
,
110 wxNativeEncodingInfo
*info
)
112 wxCHECK_MSG( info
, FALSE
, _T("bad pointer in wxGetNativeFontEncoding") );
114 if ( encoding
== wxFONTENCODING_DEFAULT
)
116 encoding
= wxFont::GetDefaultEncoding();
121 // TODO: fix this for OS2
123 // although this function is supposed to return an exact match, do do
124 // some mappings here for the most common case of "standard" encoding
125 case wxFONTENCODING_SYSTEM:
126 case wxFONTENCODING_ISO8859_1:
127 case wxFONTENCODING_ISO8859_15:
128 case wxFONTENCODING_CP1252:
129 info->charset = ANSI_CHARSET;
132 case wxFONTENCODING_CP1250:
133 info->charset = EASTEUROPE_CHARSET;
136 case wxFONTENCODING_CP1251:
137 info->charset = RUSSIAN_CHARSET;
140 case wxFONTENCODING_CP1253:
141 info->charset = GREEK_CHARSET;
144 case wxFONTENCODING_CP1254:
145 info->charset = TURKISH_CHARSET;
148 case wxFONTENCODING_CP1255:
149 info->charset = HEBREW_CHARSET;
152 case wxFONTENCODING_CP1256:
153 info->charset = ARABIC_CHARSET;
156 case wxFONTENCODING_CP1257:
157 info->charset = BALTIC_CHARSET;
160 case wxFONTENCODING_CP874:
161 info->charset = THAI_CHARSET;
164 case wxFONTENCODING_CP437:
165 info->charset = OEM_CHARSET;
169 // no way to translate this encoding into a Windows charset
176 bool wxTestFontEncoding(const wxNativeEncodingInfo
& info
)
180 // try to create such font
182 wxZeroMemory(lf); // all default values
184 lf.lfCharSet = info.charset;
185 strncpy(lf.lfFaceName, info.facename, sizeof(lf.lfFaceName));
187 HFONT hfont = ::CreateFontIndirect(&lf);
194 ::DeleteObject((HGDIOBJ)hfont);
199 // ----------------------------------------------------------------------------
200 // wxFont <-> LOGFONT conversion
201 // ----------------------------------------------------------------------------
204 void wxFillLogFont(LOGFONT
*logFont
, const wxFont
*font
)
209 switch ( font
->GetFamily() )
212 ff_family
= FF_SCRIPT
;
213 ff_face
= _T("Script");
217 ff_family
= FF_DECORATIVE
;
221 ff_family
= FF_ROMAN
;
222 ff_face
= _T("Times New Roman");
227 ff_family
= FF_MODERN
;
228 ff_face
= _T("Courier New");
232 ff_family
= FF_SWISS
;
233 ff_face
= _T("Arial");
238 ff_family
= FF_SWISS
;
239 ff_face
= _T("MS Sans Serif");
243 switch ( font
->GetStyle() )
251 wxFAIL_MSG(wxT("unknown font slant"));
259 switch ( font
->GetWeight() )
262 wxFAIL_MSG(_T("unknown font weight"));
266 ff_weight
= FW_NORMAL
;
270 ff_weight
= FW_LIGHT
;
279 HDC dc
= ::GetDC(NULL
);
280 int ppInch
= ::GetDeviceCaps(dc
, LOGPIXELSY
);
281 ::ReleaseDC(NULL
, dc
);
283 // New behaviour: apparently ppInch varies according to Large/Small Fonts
284 // setting in Windows. This messes up fonts. So, set ppInch to a constant
286 static const int ppInch
= 96;
289 #if wxFONT_SIZE_COMPATIBILITY
290 // Incorrect, but compatible with old wxWindows behaviour
291 int nHeight
= (font
->GetPointSize()*ppInch
/72);
293 // Correct for Windows compatibility
294 int nHeight
= - (font
->GetPointSize()*ppInch
/72);
297 wxString facename
= font
->GetFaceName();
302 //else: ff_face is a reasonable default facename for this font family
304 // deal with encoding now
305 wxNativeEncodingInfo info
;
306 wxFontEncoding encoding
= font
->GetEncoding();
307 if ( !wxGetNativeFontEncoding(encoding
, &info
) )
309 if ( !wxTheFontMapper
->GetAltForEncoding(encoding
, &info
) )
311 // unsupported encoding, replace with the default
312 info
.charset
= ANSI_CHARSET
;
316 if ( !info
.facename
.IsEmpty() )
318 // the facename determined by the encoding overrides everything else
319 ff_face
= info
.facename
;
322 // transfer all the data to LOGFONT
323 logFont
->lfHeight
= nHeight
;
324 logFont
->lfWidth
= 0;
325 logFont
->lfEscapement
= 0;
326 logFont
->lfOrientation
= 0;
327 logFont
->lfWeight
= ff_weight
;
328 logFont
->lfItalic
= ff_italic
;
329 logFont
->lfUnderline
= (BYTE
)font
->GetUnderlined();
330 logFont
->lfStrikeOut
= 0;
331 logFont
->lfCharSet
= info
.charset
;
332 logFont
->lfOutPrecision
= OUT_DEFAULT_PRECIS
;
333 logFont
->lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
334 logFont
->lfQuality
= PROOF_QUALITY
;
335 logFont
->lfPitchAndFamily
= DEFAULT_PITCH
| ff_family
;
336 wxStrncpy(logFont
->lfFaceName
, ff_face
, WXSIZEOF(logFont
->lfFaceName
));
339 wxFont
wxCreateFontFromLogFont(const LOGFONT
*logFont
)
341 DEBUG_PRINTF(wxCreateFontFromLogFont
)
343 // extract family from pitch-and-family
344 int lfFamily
= logFont
->lfPitchAndFamily
;
345 if ( lfFamily
& FIXED_PITCH
)
346 lfFamily
-= FIXED_PITCH
;
347 if ( lfFamily
& VARIABLE_PITCH
)
348 lfFamily
-= VARIABLE_PITCH
;
354 fontFamily
= wxROMAN
;
358 fontFamily
= wxSWISS
;
362 fontFamily
= wxSCRIPT
;
366 fontFamily
= wxMODERN
;
370 fontFamily
= wxDECORATIVE
;
374 fontFamily
= wxSWISS
;
378 int fontWeight
= wxNORMAL
;
379 switch ( logFont
->lfWeight
)
382 fontWeight
= wxLIGHT
;
387 fontWeight
= wxNORMAL
;
395 int fontStyle
= logFont
->lfItalic
? wxITALIC
: wxNORMAL
;
397 bool fontUnderline
= logFont
->lfUnderline
!= 0;
399 wxString fontFace
= logFont
->lfFaceName
;
402 HDC dc
= ::GetDC(NULL
);
404 // remember that 1pt = 1/72inch
405 int height
= abs(logFont
->lfHeight
);
406 int fontPoints
= (72*height
)/GetDeviceCaps(dc
, LOGPIXELSY
);
408 ::ReleaseDC(NULL
, dc
);
410 wxFontEncoding fontEncoding
;
411 switch ( logFont
->lfCharSet
)
414 wxFAIL_MSG(wxT("unsupported charset"));
418 fontEncoding
= wxFONTENCODING_CP1252
;
422 case EASTEUROPE_CHARSET
:
423 fontEncoding
= wxFONTENCODING_CP1250
;
427 fontEncoding
= wxFONTENCODING_CP1257
;
430 case RUSSIAN_CHARSET
:
431 fontEncoding
= wxFONTENCODING_CP1251
;
435 fontEncoding
= wxFONTENCODING_CP1256
;
439 fontEncoding
= wxFONTENCODING_CP1253
;
443 fontEncoding
= wxFONTENCODING_CP1255
;
446 case TURKISH_CHARSET
:
447 fontEncoding
= wxFONTENCODING_CP1254
;
451 fontEncoding
= wxFONTENCODING_CP437
;
456 fontEncoding
= wxFONTENCODING_CP437
;
460 return wxFont(fontPoints
, fontFamily
, fontStyle
,
461 fontWeight
, fontUnderline
, fontFace
,