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