]> git.saurik.com Git - wxWidgets.git/blame - src/msw/fontutil.cpp
1. patch from Søren Erland Vestø implementing wxFTP::GetFileSize()
[wxWidgets.git] / src / msw / fontutil.cpp
CommitLineData
11c7d5b6
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: msw/fontutil.cpp
3// Purpose: font-related helper functions for wxMSW
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 05.11.99
7// RCS-ID: $Id$
8// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9// Licence: wxWindows license
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#ifdef __GNUG__
21 #pragma implementation "fontutil.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#ifndef WX_PRECOMP
32 #include "wx/string.h"
33 #include "wx/log.h"
34 #include "wx/intl.h"
35#endif //WX_PRECOMP
36
37#include "wx/msw/private.h"
38
39#include "wx/fontutil.h"
40#include "wx/fontmap.h"
41
42#include "wx/tokenzr.h"
43
6b82d894
JS
44// If 1, use the screen resolution to calculate font sizes.
45// This is OK for screen fonts but might have implications when the
46// same font is used for printing.
47// If 0, assume 96 DPI.
48#define wxUSE_SCREEN_DPI 1
49
11c7d5b6
VZ
50// ============================================================================
51// implementation
52// ============================================================================
53
54// ----------------------------------------------------------------------------
55// wxNativeEncodingInfo
56// ----------------------------------------------------------------------------
57
58// convert to/from the string representation: format is
1e1d0be1 59// encodingid;facename[;charset]
11c7d5b6
VZ
60
61bool wxNativeEncodingInfo::FromString(const wxString& s)
62{
63 wxStringTokenizer tokenizer(s, _T(";"));
64
1e1d0be1
VS
65 wxString encid = tokenizer.GetNextToken();
66 long enc;
67 if ( !encid.ToLong(&enc) )
68 return FALSE;
69 encoding = (wxFontEncoding)enc;
70
11c7d5b6
VZ
71 facename = tokenizer.GetNextToken();
72 if ( !facename )
73 return FALSE;
74
75 wxString tmp = tokenizer.GetNextToken();
76 if ( !tmp )
77 {
78 // default charset (don't use DEFAULT_CHARSET though because of subtle
79 // Windows 9x/NT differences in handling it)
80 charset = ANSI_CHARSET;
81 }
82 else
83 {
84 if ( wxSscanf(tmp, _T("%u"), &charset) != 1 )
85 {
86 // should be a number!
87 return FALSE;
88 }
89 }
90
91 return TRUE;
92}
93
94wxString wxNativeEncodingInfo::ToString() const
95{
1e1d0be1 96 wxString s;
f6bcfd97 97
1e1d0be1 98 s << (long)encoding << _T(';') << facename;
11c7d5b6
VZ
99 if ( charset != ANSI_CHARSET )
100 {
1e1d0be1 101 s << _T(';') << charset;
11c7d5b6
VZ
102 }
103
104 return s;
105}
106
107// ----------------------------------------------------------------------------
108// helper functions
109// ----------------------------------------------------------------------------
110
111bool wxGetNativeFontEncoding(wxFontEncoding encoding,
112 wxNativeEncodingInfo *info)
113{
114 wxCHECK_MSG( info, FALSE, _T("bad pointer in wxGetNativeFontEncoding") );
115
116 if ( encoding == wxFONTENCODING_DEFAULT )
117 {
118 encoding = wxFont::GetDefaultEncoding();
119 }
120
121 switch ( encoding )
122 {
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;
130 break;
131
132#if !defined(__WIN16__)
133 case wxFONTENCODING_CP1250:
134 info->charset = EASTEUROPE_CHARSET;
135 break;
136
137 case wxFONTENCODING_CP1251:
138 info->charset = RUSSIAN_CHARSET;
139 break;
140
141 case wxFONTENCODING_CP1253:
142 info->charset = GREEK_CHARSET;
143 break;
144
145 case wxFONTENCODING_CP1254:
146 info->charset = TURKISH_CHARSET;
147 break;
148
149 case wxFONTENCODING_CP1255:
150 info->charset = HEBREW_CHARSET;
151 break;
152
153 case wxFONTENCODING_CP1256:
154 info->charset = ARABIC_CHARSET;
155 break;
156
157 case wxFONTENCODING_CP1257:
158 info->charset = BALTIC_CHARSET;
159 break;
f3314fbc
JS
160
161 case wxFONTENCODING_CP874:
162 info->charset = THAI_CHARSET;
163 break;
11c7d5b6
VZ
164#endif // !Win16
165
166 case wxFONTENCODING_CP437:
167 info->charset = OEM_CHARSET;
168 break;
169
170 default:
171 // no way to translate this encoding into a Windows charset
172 return FALSE;
173 }
174
6b0eebc5 175 info->encoding = encoding;
f6bcfd97 176
11c7d5b6
VZ
177 return TRUE;
178}
179
180bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
181{
182 // try to create such font
183 LOGFONT lf;
184 wxZeroMemory(lf); // all default values
185
186 lf.lfCharSet = info.charset;
0e89bb17 187 wxStrncpy(lf.lfFaceName, info.facename, sizeof(lf.lfFaceName));
11c7d5b6
VZ
188
189 HFONT hfont = ::CreateFontIndirect(&lf);
190 if ( !hfont )
191 {
192 // no such font
193 return FALSE;
194 }
195
196 ::DeleteObject((HGDIOBJ)hfont);
197
198 return TRUE;
199}
200
f6bcfd97
BP
201// ----------------------------------------------------------------------------
202// wxFontEncoding <-> CHARSET_XXX
203// ----------------------------------------------------------------------------
204
205wxFontEncoding wxGetFontEncFromCharSet(int cs)
206{
207 wxFontEncoding fontEncoding;
208
209 switch ( cs )
210 {
211 default:
212 // JACS: Silently using ANSI_CHARSET
213 // apparently works for Chinese Windows. Assume it works
214 // for all/most other languages.
215 //wxFAIL_MSG(wxT("unsupported charset"));
216 // fall through
217
218 case ANSI_CHARSET:
219 fontEncoding = wxFONTENCODING_CP1252;
220 break;
221
222#ifdef __WIN32__
223 case EASTEUROPE_CHARSET:
224 fontEncoding = wxFONTENCODING_CP1250;
225 break;
226
227 case BALTIC_CHARSET:
228 fontEncoding = wxFONTENCODING_CP1257;
229 break;
230
231 case RUSSIAN_CHARSET:
232 fontEncoding = wxFONTENCODING_CP1251;
233 break;
234
235 case ARABIC_CHARSET:
236 fontEncoding = wxFONTENCODING_CP1256;
237 break;
238
239 case GREEK_CHARSET:
240 fontEncoding = wxFONTENCODING_CP1253;
241 break;
242
243 case HEBREW_CHARSET:
244 fontEncoding = wxFONTENCODING_CP1255;
245 break;
246
247 case TURKISH_CHARSET:
248 fontEncoding = wxFONTENCODING_CP1254;
249 break;
250
251 case THAI_CHARSET:
252 fontEncoding = wxFONTENCODING_CP437;
253 break;
254#endif // Win32
255
256 case OEM_CHARSET:
257 fontEncoding = wxFONTENCODING_CP437;
258 break;
259 }
260
261 return fontEncoding;
262}
263
11c7d5b6
VZ
264// ----------------------------------------------------------------------------
265// wxFont <-> LOGFONT conversion
266// ----------------------------------------------------------------------------
267
268void wxFillLogFont(LOGFONT *logFont, const wxFont *font)
269{
270 int ff_family;
271 wxString ff_face;
272
273 switch ( font->GetFamily() )
274 {
275 case wxSCRIPT:
276 ff_family = FF_SCRIPT;
277 ff_face = _T("Script");
278 break;
279
280 case wxDECORATIVE:
281 ff_family = FF_DECORATIVE;
282 break;
283
284 case wxROMAN:
285 ff_family = FF_ROMAN;
286 ff_face = _T("Times New Roman");
287 break;
288
289 case wxTELETYPE:
290 case wxMODERN:
291 ff_family = FF_MODERN;
292 ff_face = _T("Courier New");
293 break;
294
295 case wxSWISS:
296 ff_family = FF_SWISS;
297 ff_face = _T("Arial");
298 break;
299
300 case wxDEFAULT:
301 default:
302 ff_family = FF_SWISS;
303 ff_face = _T("MS Sans Serif");
304 }
305
306 BYTE ff_italic;
307 switch ( font->GetStyle() )
308 {
309 case wxITALIC:
310 case wxSLANT:
311 ff_italic = 1;
312 break;
313
314 default:
315 wxFAIL_MSG(wxT("unknown font slant"));
316 // fall through
317
318 case wxNORMAL:
319 ff_italic = 0;
320 }
321
322 int ff_weight;
323 switch ( font->GetWeight() )
324 {
325 default:
326 wxFAIL_MSG(_T("unknown font weight"));
327 // fall through
328
329 case wxNORMAL:
330 ff_weight = FW_NORMAL;
331 break;
332
333 case wxLIGHT:
334 ff_weight = FW_LIGHT;
335 break;
336
337 case wxBOLD:
338 ff_weight = FW_BOLD;
339 break;
340 }
341
6b82d894 342#if wxUSE_SCREEN_DPI
11c7d5b6 343 HDC dc = ::GetDC(NULL);
6b82d894 344 static const int ppInch = ::GetDeviceCaps(dc, LOGPIXELSY);
11c7d5b6
VZ
345 ::ReleaseDC(NULL, dc);
346#else
347 // New behaviour: apparently ppInch varies according to Large/Small Fonts
348 // setting in Windows. This messes up fonts. So, set ppInch to a constant
349 // 96 dpi.
350 static const int ppInch = 96;
351#endif // 0/1
352
353#if wxFONT_SIZE_COMPATIBILITY
354 // Incorrect, but compatible with old wxWindows behaviour
355 int nHeight = (font->GetPointSize()*ppInch/72);
356#else
357 // Correct for Windows compatibility
bf027a6d
JS
358// int nHeight = - (font->GetPointSize()*ppInch/72);
359 int nHeight = - (int) ( (font->GetPointSize()*((double)ppInch)/72.0) + 0.5);
11c7d5b6
VZ
360#endif
361
362 wxString facename = font->GetFaceName();
363 if ( !!facename )
364 {
365 ff_face = facename;
366 }
367 //else: ff_face is a reasonable default facename for this font family
368
369 // deal with encoding now
370 wxNativeEncodingInfo info;
371 wxFontEncoding encoding = font->GetEncoding();
372 if ( !wxGetNativeFontEncoding(encoding, &info) )
373 {
374 if ( !wxTheFontMapper->GetAltForEncoding(encoding, &info) )
375 {
376 // unsupported encoding, replace with the default
377 info.charset = ANSI_CHARSET;
378 }
379 }
380
381 if ( !info.facename.IsEmpty() )
382 {
383 // the facename determined by the encoding overrides everything else
384 ff_face = info.facename;
385 }
386
387 // transfer all the data to LOGFONT
388 logFont->lfHeight = nHeight;
389 logFont->lfWidth = 0;
390 logFont->lfEscapement = 0;
391 logFont->lfOrientation = 0;
392 logFont->lfWeight = ff_weight;
393 logFont->lfItalic = ff_italic;
394 logFont->lfUnderline = (BYTE)font->GetUnderlined();
395 logFont->lfStrikeOut = 0;
396 logFont->lfCharSet = info.charset;
397 logFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
398 logFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
399 logFont->lfQuality = PROOF_QUALITY;
400 logFont->lfPitchAndFamily = DEFAULT_PITCH | ff_family;
401 wxStrncpy(logFont->lfFaceName, ff_face, WXSIZEOF(logFont->lfFaceName));
402}
403
404wxFont wxCreateFontFromLogFont(const LOGFONT *logFont)
405{
406 // extract family from pitch-and-family
407 int lfFamily = logFont->lfPitchAndFamily;
408 if ( lfFamily & FIXED_PITCH )
409 lfFamily -= FIXED_PITCH;
410 if ( lfFamily & VARIABLE_PITCH )
411 lfFamily -= VARIABLE_PITCH;
412
413 int fontFamily;
414 switch ( lfFamily )
415 {
416 case FF_ROMAN:
417 fontFamily = wxROMAN;
418 break;
419
420 case FF_SWISS:
421 fontFamily = wxSWISS;
422 break;
423
424 case FF_SCRIPT:
425 fontFamily = wxSCRIPT;
426 break;
427
428 case FF_MODERN:
429 fontFamily = wxMODERN;
430 break;
431
432 case FF_DECORATIVE:
433 fontFamily = wxDECORATIVE;
434 break;
435
436 default:
437 fontFamily = wxSWISS;
438 }
439
440 // weight and style
441 int fontWeight = wxNORMAL;
442 switch ( logFont->lfWeight )
443 {
444 case FW_LIGHT:
445 fontWeight = wxLIGHT;
446 break;
447
448 default:
449 case FW_NORMAL:
450 fontWeight = wxNORMAL;
451 break;
452
453 case FW_BOLD:
454 fontWeight = wxBOLD;
455 break;
456 }
457
458 int fontStyle = logFont->lfItalic ? wxITALIC : wxNORMAL;
459
460 bool fontUnderline = logFont->lfUnderline != 0;
461
462 wxString fontFace = logFont->lfFaceName;
463
11c7d5b6
VZ
464 // remember that 1pt = 1/72inch
465 int height = abs(logFont->lfHeight);
11c7d5b6 466
6b82d894
JS
467#if wxUSE_SCREEN_DPI
468 HDC dc = ::GetDC(NULL);
469 static const int ppInch = GetDeviceCaps(dc, LOGPIXELSY);
11c7d5b6 470 ::ReleaseDC(NULL, dc);
6b82d894
JS
471#else
472 static const int ppInch = 96;
473#endif
474 int fontPoints = (int) (((72.0*((double)height))/(double) ppInch) + 0.5);
11c7d5b6 475
11c7d5b6
VZ
476 return wxFont(fontPoints, fontFamily, fontStyle,
477 fontWeight, fontUnderline, fontFace,
f6bcfd97 478 wxGetFontEncFromCharSet(logFont->lfCharSet));
11c7d5b6
VZ
479}
480