]> git.saurik.com Git - wxWidgets.git/blame - src/os2/fontutil.cpp
Busy cursor don't need wxYield(), SendIdleEvents()
[wxWidgets.git] / src / os2 / fontutil.cpp
CommitLineData
d8cde57b
DW
1///////////////////////////////////////////////////////////////////////////////
2// Name: msw/fontutil.cpp
3// Purpose: font-related helper functions for wxMSW
4// Author: Modified by David Webster for OS/2
5// Modified by:
6// Created: 01.03.00
7// RCS-ID: $Id$
8// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9// Licence: wxWindows license
10///////////////////////////////////////////////////////////////////////////////
7e99520b
DW
11#define DEBUG_PRINTF(NAME) { static int raz=0; \
12 printf( #NAME " %i\n",raz); fflush(stdout); \
13 raz++; \
14 }
d8cde57b
DW
15
16// ============================================================================
17// declarations
18// ============================================================================
19
20// ----------------------------------------------------------------------------
21// headers
22// ----------------------------------------------------------------------------
23
a4372af6
SN
24#ifdef __GNUG__
25 #pragma implementation "fontutil.h"
26#endif
27
d8cde57b
DW
28// For compilers that support precompilation, includes "wx.h".
29#include "wx/wxprec.h"
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/os2/private.h"
38
39#include "wx/fontutil.h"
40#include "wx/fontmap.h"
41
42#include "wx/tokenzr.h"
43
44// ============================================================================
45// implementation
46// ============================================================================
47
48// ----------------------------------------------------------------------------
49// wxNativeEncodingInfo
50// ----------------------------------------------------------------------------
51
52// convert to/from the string representation: format is
1e1d0be1 53// encodingid;facename[;charset]
d8cde57b
DW
54
55bool wxNativeEncodingInfo::FromString(const wxString& s)
56{
57 wxStringTokenizer tokenizer(s, _T(";"));
58
1e1d0be1
VS
59 wxString encid = tokenizer.GetNextToken();
60 long enc;
61 if ( !encid.ToLong(&enc) )
62 return FALSE;
63 encoding = (wxFontEncoding)enc;
64
d8cde57b
DW
65 facename = tokenizer.GetNextToken();
66 if ( !facename )
67 return FALSE;
68
69 wxString tmp = tokenizer.GetNextToken();
70 if ( !tmp )
71 {
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;
76 }
77 else
78 {
79 if ( wxSscanf(tmp, _T("%u"), &charset) != 1 )
80 {
81 // should be a number!
82 return FALSE;
83 }
84 }
85
86 return TRUE;
87}
88
89wxString wxNativeEncodingInfo::ToString() const
90{
1e1d0be1 91 wxString s;
7e99520b 92
1e1d0be1
VS
93 s << (long)encoding << _T(';') << facename;
94
d8cde57b
DW
95// TODO: what is this for OS/2?
96/*
97 if ( charset != ANSI_CHARSET )
98 {
99 s << _T(';') << charset;
100 }
101*/
102 return s;
103}
104
105// ----------------------------------------------------------------------------
106// helper functions
107// ----------------------------------------------------------------------------
108
109bool wxGetNativeFontEncoding(wxFontEncoding encoding,
110 wxNativeEncodingInfo *info)
111{
112 wxCHECK_MSG( info, FALSE, _T("bad pointer in wxGetNativeFontEncoding") );
113
114 if ( encoding == wxFONTENCODING_DEFAULT )
115 {
116 encoding = wxFont::GetDefaultEncoding();
117 }
118
119 switch ( encoding )
120 {
121// TODO: fix this for OS2
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 case wxFONTENCODING_CP1250:
133 info->charset = EASTEUROPE_CHARSET;
134 break;
135
136 case wxFONTENCODING_CP1251:
137 info->charset = RUSSIAN_CHARSET;
138 break;
139
140 case wxFONTENCODING_CP1253:
141 info->charset = GREEK_CHARSET;
142 break;
143
144 case wxFONTENCODING_CP1254:
145 info->charset = TURKISH_CHARSET;
146 break;
147
148 case wxFONTENCODING_CP1255:
149 info->charset = HEBREW_CHARSET;
150 break;
151
152 case wxFONTENCODING_CP1256:
153 info->charset = ARABIC_CHARSET;
154 break;
155
156 case wxFONTENCODING_CP1257:
157 info->charset = BALTIC_CHARSET;
158 break;
159
160 case wxFONTENCODING_CP874:
161 info->charset = THAI_CHARSET;
162 break;
163
164 case wxFONTENCODING_CP437:
165 info->charset = OEM_CHARSET;
166 break;
167*/
168 default:
169 // no way to translate this encoding into a Windows charset
170 return FALSE;
171 }
172
173 return TRUE;
174}
175
176bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
177{
178 // TODO:
179 /*
180 // try to create such font
181 LOGFONT lf;
182 wxZeroMemory(lf); // all default values
183
184 lf.lfCharSet = info.charset;
185 strncpy(lf.lfFaceName, info.facename, sizeof(lf.lfFaceName));
186
187 HFONT hfont = ::CreateFontIndirect(&lf);
188 if ( !hfont )
189 {
190 // no such font
191 return FALSE;
192 }
193
194 ::DeleteObject((HGDIOBJ)hfont);
195*/
196 return TRUE;
197}
198
199// ----------------------------------------------------------------------------
200// wxFont <-> LOGFONT conversion
201// ----------------------------------------------------------------------------
202
203#if 0
204void wxFillLogFont(LOGFONT *logFont, const wxFont *font)
205{
206 int ff_family;
207 wxString ff_face;
208
209 switch ( font->GetFamily() )
210 {
211 case wxSCRIPT:
212 ff_family = FF_SCRIPT;
213 ff_face = _T("Script");
214 break;
215
216 case wxDECORATIVE:
217 ff_family = FF_DECORATIVE;
218 break;
219
220 case wxROMAN:
221 ff_family = FF_ROMAN;
222 ff_face = _T("Times New Roman");
223 break;
224
225 case wxTELETYPE:
226 case wxMODERN:
227 ff_family = FF_MODERN;
228 ff_face = _T("Courier New");
229 break;
230
231 case wxSWISS:
232 ff_family = FF_SWISS;
233 ff_face = _T("Arial");
234 break;
235
236 case wxDEFAULT:
237 default:
238 ff_family = FF_SWISS;
239 ff_face = _T("MS Sans Serif");
240 }
241
242 BYTE ff_italic;
243 switch ( font->GetStyle() )
244 {
245 case wxITALIC:
246 case wxSLANT:
247 ff_italic = 1;
248 break;
249
250 default:
251 wxFAIL_MSG(wxT("unknown font slant"));
252 // fall through
253
254 case wxNORMAL:
255 ff_italic = 0;
256 }
257
258 int ff_weight;
259 switch ( font->GetWeight() )
260 {
261 default:
262 wxFAIL_MSG(_T("unknown font weight"));
263 // fall through
264
265 case wxNORMAL:
266 ff_weight = FW_NORMAL;
267 break;
268
269 case wxLIGHT:
270 ff_weight = FW_LIGHT;
271 break;
272
273 case wxBOLD:
274 ff_weight = FW_BOLD;
275 break;
276 }
277
278#if 0
279 HDC dc = ::GetDC(NULL);
280 int ppInch = ::GetDeviceCaps(dc, LOGPIXELSY);
281 ::ReleaseDC(NULL, dc);
282#else
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
285 // 96 dpi.
286 static const int ppInch = 96;
287#endif // 0/1
288
289#if wxFONT_SIZE_COMPATIBILITY
290 // Incorrect, but compatible with old wxWindows behaviour
291 int nHeight = (font->GetPointSize()*ppInch/72);
292#else
293 // Correct for Windows compatibility
294 int nHeight = - (font->GetPointSize()*ppInch/72);
295#endif
296
297 wxString facename = font->GetFaceName();
298 if ( !!facename )
299 {
300 ff_face = facename;
301 }
302 //else: ff_face is a reasonable default facename for this font family
303
304 // deal with encoding now
305 wxNativeEncodingInfo info;
306 wxFontEncoding encoding = font->GetEncoding();
307 if ( !wxGetNativeFontEncoding(encoding, &info) )
308 {
309 if ( !wxTheFontMapper->GetAltForEncoding(encoding, &info) )
310 {
311 // unsupported encoding, replace with the default
312 info.charset = ANSI_CHARSET;
313 }
314 }
315
316 if ( !info.facename.IsEmpty() )
317 {
318 // the facename determined by the encoding overrides everything else
319 ff_face = info.facename;
320 }
321
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));
337}
338
339wxFont wxCreateFontFromLogFont(const LOGFONT *logFont)
340{
7e99520b
DW
341DEBUG_PRINTF(wxCreateFontFromLogFont)
342
d8cde57b
DW
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;
349
350 int fontFamily;
351 switch ( lfFamily )
352 {
353 case FF_ROMAN:
354 fontFamily = wxROMAN;
355 break;
356
357 case FF_SWISS:
358 fontFamily = wxSWISS;
359 break;
360
361 case FF_SCRIPT:
362 fontFamily = wxSCRIPT;
363 break;
364
365 case FF_MODERN:
366 fontFamily = wxMODERN;
367 break;
368
369 case FF_DECORATIVE:
370 fontFamily = wxDECORATIVE;
371 break;
372
373 default:
374 fontFamily = wxSWISS;
375 }
376
377 // weight and style
378 int fontWeight = wxNORMAL;
379 switch ( logFont->lfWeight )
380 {
381 case FW_LIGHT:
382 fontWeight = wxLIGHT;
383 break;
384
385 default:
386 case FW_NORMAL:
387 fontWeight = wxNORMAL;
388 break;
389
390 case FW_BOLD:
391 fontWeight = wxBOLD;
392 break;
393 }
394
395 int fontStyle = logFont->lfItalic ? wxITALIC : wxNORMAL;
396
397 bool fontUnderline = logFont->lfUnderline != 0;
398
399 wxString fontFace = logFont->lfFaceName;
400
401 // font size
402 HDC dc = ::GetDC(NULL);
403
404 // remember that 1pt = 1/72inch
405 int height = abs(logFont->lfHeight);
406 int fontPoints = (72*height)/GetDeviceCaps(dc, LOGPIXELSY);
407
408 ::ReleaseDC(NULL, dc);
409
410 wxFontEncoding fontEncoding;
411 switch ( logFont->lfCharSet )
412 {
413 default:
414 wxFAIL_MSG(wxT("unsupported charset"));
415 // fall through
416
417 case ANSI_CHARSET:
418 fontEncoding = wxFONTENCODING_CP1252;
419 break;
420
421#ifdef __WIN32__
422 case EASTEUROPE_CHARSET:
423 fontEncoding = wxFONTENCODING_CP1250;
424 break;
425
426 case BALTIC_CHARSET:
427 fontEncoding = wxFONTENCODING_CP1257;
428 break;
429
430 case RUSSIAN_CHARSET:
431 fontEncoding = wxFONTENCODING_CP1251;
432 break;
433
434 case ARABIC_CHARSET:
435 fontEncoding = wxFONTENCODING_CP1256;
436 break;
437
438 case GREEK_CHARSET:
439 fontEncoding = wxFONTENCODING_CP1253;
440 break;
441
442 case HEBREW_CHARSET:
443 fontEncoding = wxFONTENCODING_CP1255;
444 break;
445
446 case TURKISH_CHARSET:
447 fontEncoding = wxFONTENCODING_CP1254;
448 break;
449
450 case THAI_CHARSET:
451 fontEncoding = wxFONTENCODING_CP437;
452 break;
453#endif
454
455 case OEM_CHARSET:
456 fontEncoding = wxFONTENCODING_CP437;
457 break;
458 }
459
460 return wxFont(fontPoints, fontFamily, fontStyle,
461 fontWeight, fontUnderline, fontFace,
462 fontEncoding);
463}
464#endif // 0
465