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