]> git.saurik.com Git - wxWidgets.git/blob - src/os2/fontutil.cpp
Don't create a bitmap with dimensions <= 0...
[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 #define DEBUG_PRINTF(NAME) { static int raz=0; \
12 printf( #NAME " %i\n",raz); fflush(stdout); \
13 raz++; \
14 }
15
16 // ============================================================================
17 // declarations
18 // ============================================================================
19
20 // ----------------------------------------------------------------------------
21 // headers
22 // ----------------------------------------------------------------------------
23
24 #ifdef __GNUG__
25 #pragma implementation "fontutil.h"
26 #endif
27
28 // For compilers that support precompilation, includes "wx.h".
29 #include "wx/wxprec.h"
30
31 #ifndef WX_PRECOMP
32 #include "wx/app.h"
33 #include "wx/string.h"
34 #include "wx/log.h"
35 #include "wx/intl.h"
36 #endif //WX_PRECOMP
37
38 #include "wx/os2/private.h"
39
40 #include "wx/fontutil.h"
41 #include "wx/fontmap.h"
42
43 #include "wx/tokenzr.h"
44
45 // ============================================================================
46 // implementation
47 // ============================================================================
48
49 // ----------------------------------------------------------------------------
50 // wxNativeEncodingInfo
51 // ----------------------------------------------------------------------------
52
53 // convert to/from the string representation: format is
54 // encodingid;facename[;charset]
55
56 bool wxNativeEncodingInfo::FromString(
57 const wxString& rsStr
58 )
59 {
60 wxStringTokenizer vTokenizer(rsStr, _T(";"));
61 wxString sEncid = vTokenizer.GetNextToken();
62 long lEnc;
63
64 if (!sEncid.ToLong(&lEnc))
65 return FALSE;
66 encoding = (wxFontEncoding)lEnc;
67 facename = vTokenizer.GetNextToken();
68 if (!facename)
69 return FALSE;
70
71 wxString sTmp = vTokenizer.GetNextToken();
72
73 if (!sTmp)
74 {
75 charset = 850;
76 }
77 else
78 {
79 if ( wxSscanf(sTmp, _T("%u"), &charset) != 1 )
80 {
81 // should be a number!
82 return FALSE;
83 }
84 }
85 return TRUE;
86 } // end of wxNativeEncodingInfo::FromString
87
88 wxString wxNativeEncodingInfo::ToString() const
89 {
90 wxString sStr;
91
92 sStr << (long)encoding << _T(';') << facename;
93
94 if (charset != 850)
95 {
96 sStr << _T(';') << charset;
97 }
98 return sStr;
99 } // end of wxNativeEncodingInfo::ToString
100
101 // ----------------------------------------------------------------------------
102 // helper functions
103 // ----------------------------------------------------------------------------
104
105 bool wxGetNativeFontEncoding(
106 wxFontEncoding vEncoding
107 , wxNativeEncodingInfo* pInfo
108 )
109 {
110 wxCHECK_MSG(pInfo, FALSE, _T("bad pointer in wxGetNativeFontEncoding") );
111 if (vEncoding == wxFONTENCODING_DEFAULT)
112 {
113 vEncoding = wxFont::GetDefaultEncoding();
114 }
115 switch (vEncoding)
116 {
117 case wxFONTENCODING_ISO8859_1:
118 case wxFONTENCODING_ISO8859_15:
119 case wxFONTENCODING_CP1250:
120 pInfo->charset = 1250;
121 break;
122
123 case wxFONTENCODING_ISO8859_2:
124 case wxFONTENCODING_CP1252:
125 pInfo->charset = 1252;
126 break;
127
128 case wxFONTENCODING_ISO8859_4:
129 case wxFONTENCODING_ISO8859_10:
130 pInfo->charset = 921; // what is baltic?
131 break;
132
133 case wxFONTENCODING_ISO8859_5:
134 case wxFONTENCODING_CP1251:
135 pInfo->charset = 1251;
136 break;
137
138 case wxFONTENCODING_ISO8859_6:
139 pInfo->charset = 864;
140 break;
141
142 case wxFONTENCODING_ISO8859_7:
143 pInfo->charset = 869;
144 break;
145
146 case wxFONTENCODING_ISO8859_8:
147 pInfo->charset = 862;
148 break;
149
150 case wxFONTENCODING_ISO8859_9:
151 pInfo->charset = 857;
152 break;
153
154 case wxFONTENCODING_ISO8859_11:
155 pInfo->charset = 874; // what is thai
156 break;
157
158 case wxFONTENCODING_CP437:
159 pInfo->charset = 437;
160 break;
161
162 default:
163 wxFAIL_MSG(wxT("unsupported encoding"));
164 // fall through
165
166 case wxFONTENCODING_SYSTEM:
167 pInfo->charset = 850;
168 break;
169 }
170 return TRUE;
171 } // end of wxGetNativeFontEncoding
172
173 bool wxTestFontEncoding(
174 const wxNativeEncodingInfo& rInfo
175 )
176 {
177 FATTRS vLogFont;
178 HPS hPS;
179
180 hPS = ::WinGetPS(HWND_DESKTOP);
181
182 memset(&vLogFont, '\0', sizeof(FATTRS)); // all default values
183 vLogFont.usRecordLength = sizeof(FATTRS);
184 vLogFont.usCodePage = rInfo.charset;
185 vLogFont.lMaxBaselineExt = 0L; // Outline fonts should use 0
186 vLogFont.lAveCharWidth = 0L; // Outline fonts should use 0
187 vLogFont.fsFontUse = FATTR_FONTUSE_OUTLINE | // only outline fonts allowed
188 FATTR_FONTUSE_TRANSFORMABLE; // may be transformed
189
190 strncpy(vLogFont.szFacename, rInfo.facename.c_str(), sizeof(vLogFont.szFacename));
191
192 if (!::GpiCreateLogFont( hPS
193 ,NULL
194 ,1L
195 ,&vLogFont
196 ))
197 {
198 ::WinReleasePS(hPS);
199 return FALSE;
200 }
201 ::WinReleasePS(hPS);
202 return TRUE;
203 } // end of wxTestFontEncoding
204
205 // ----------------------------------------------------------------------------
206 // wxFont <-> LOGFONT conversion
207 // ----------------------------------------------------------------------------
208
209 void wxFillLogFont(
210 LOGFONT* pLogFont // OS2 GPI FATTRS
211 , PFACENAMEDESC pFaceName
212 , const wxFont* pFont
213 )
214 {
215 wxString sFace;
216 USHORT uWeight;
217 int nItalic;
218
219 pLogFont->fsSelection = 0;
220 pLogFont->fsSelection = FATTR_SEL_OUTLINE; // we will alway use only outlines
221 pFaceName->usWeightClass = 0;
222 pFaceName->flOptions = 0;
223 switch (pFont->GetFamily())
224 {
225 case wxSCRIPT:
226 sFace = _T("Script");
227 break;
228
229 case wxDECORATIVE:
230 case wxROMAN:
231 sFace = _T("Times New Roman");
232 break;
233
234 case wxTELETYPE:
235 case wxMODERN:
236 sFace = _T("Courier New");
237 break;
238
239 case wxSWISS:
240 sFace = _T("WarpSans");
241 break;
242
243 case wxDEFAULT:
244 default:
245 sFace = _T("Helv");
246 }
247
248 switch (pFont->GetWeight())
249 {
250 default:
251 wxFAIL_MSG(_T("unknown font weight"));
252 uWeight = FWEIGHT_DONT_CARE;
253 break;
254
255 case wxNORMAL:
256 uWeight = FWEIGHT_NORMAL;
257 break;
258
259 case wxLIGHT:
260 uWeight = FWEIGHT_LIGHT;
261 break;
262
263 case wxBOLD:
264 uWeight = FWEIGHT_BOLD;
265 pLogFont->fsSelection |= FATTR_SEL_BOLD;
266 break;
267
268 case wxFONTWEIGHT_MAX:
269 uWeight = FWEIGHT_ULTRA_BOLD;
270 pLogFont->fsSelection |= FATTR_SEL_BOLD;
271 break;
272 }
273 pFaceName->usWeightClass |= uWeight;
274
275 switch (pFont->GetStyle())
276 {
277 case wxITALIC:
278 case wxSLANT:
279 nItalic = FTYPE_ITALIC;
280 pLogFont->fsSelection |= FATTR_SEL_ITALIC;
281 break;
282
283 default:
284 wxFAIL_MSG(wxT("unknown font slant"));
285 // fall through
286
287 case wxNORMAL:
288 nItalic = 0;
289 break;
290 }
291 pFaceName->flOptions |= nItalic;
292 if(pFont->GetUnderlined())
293 pLogFont->fsSelection |= FATTR_SEL_UNDERSCORE;
294
295 //
296 // In PM a font's height is expressed in points. A point equals
297 // approximately 1/72 of an inch. We'll assume for now that,
298 // like Windows, that fonts are 96 dpi.
299 //
300 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
301 HDC hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
302 LONG lStart = CAPS_FAMILY;
303 LONG lCount = CAPS_VERTICAL_RESOLUTION;
304 LONG alArray[CAPS_VERTICAL_RESOLUTION];
305 LONG lRes;
306 int nPpInch;
307
308
309 ::DevQueryCaps(hDC, lStart, lCount, alArray);
310 lRes = alArray[CAPS_VERTICAL_RESOLUTION-1];
311 if (lRes > 0)
312 nPpInch = (int)(lRes/39.6); // lres is in pixels per meter
313 else
314 nPpInch = 96;
315
316 int nHeight = (pFont->GetPointSize() * nPpInch/72);
317 wxString sFacename = pFont->GetFaceName();
318
319 if (!!sFacename)
320 {
321 sFace = sFacename;
322 }
323 //else: ff_face is a reasonable default facename for this font family
324
325 //
326 // Deal with encoding now
327 //
328 wxNativeEncodingInfo vInfo;
329 wxFontEncoding vEncoding = pFont->GetEncoding();
330
331 if (!wxGetNativeFontEncoding( vEncoding
332 ,&vInfo
333 ))
334 {
335 if ( !wxTheFontMapper->GetAltForEncoding( vEncoding
336 ,&vInfo
337 ))
338 {
339 //
340 // Unsupported encoding, replace with the default
341 //
342 vInfo.charset = 850;
343 }
344 }
345
346 if (!vInfo.facename.IsEmpty() )
347 {
348 //
349 // The facename determined by the encoding overrides everything else
350 //
351 sFace = vInfo.facename;
352 }
353
354 //
355 // Transfer all the data to LOGFONT
356 //
357 pLogFont->usRecordLength = sizeof(FATTRS);
358 wxStrcpy(pLogFont->szFacename, sFace.c_str());
359 pLogFont->usCodePage = vInfo.charset;
360 pLogFont->fsFontUse |= FATTR_FONTUSE_OUTLINE |
361 FATTR_FONTUSE_TRANSFORMABLE;
362 } // end of wxFillLogFont
363
364 wxFont wxCreateFontFromLogFont(
365 const LOGFONT* pLogFont
366 , const PFONTMETRICS pFM
367 , PFACENAMEDESC pFaceName
368 )
369 {
370 //
371 // Extract family from facename
372 //
373 int nFontFamily;
374
375 if (strcmp(pLogFont->szFacename, "Times New Roman") == 0)
376 nFontFamily = wxROMAN;
377 else if (strcmp(pLogFont->szFacename, "WarpSans") == 0)
378 nFontFamily = wxSWISS;
379 else if (strcmp(pLogFont->szFacename, "Script") == 0)
380 nFontFamily = wxSCRIPT;
381 else if (strcmp(pLogFont->szFacename, "Courier New") == 0)
382 nFontFamily = wxMODERN;
383 else
384 nFontFamily = wxSWISS;
385
386 //
387 // Weight and Style
388 //
389 int nFontWeight = wxNORMAL;
390
391 switch (pFaceName->usWeightClass)
392 {
393 case FWEIGHT_LIGHT:
394 nFontWeight = wxLIGHT;
395 break;
396
397 default:
398 case FWEIGHT_NORMAL:
399 nFontWeight = wxNORMAL;
400 break;
401
402 case FWEIGHT_BOLD:
403 nFontWeight = wxBOLD;
404 break;
405 }
406
407 int nFontStyle;
408
409 if(pLogFont->fsSelection & FATTR_SEL_ITALIC)
410 nFontStyle = wxITALIC;
411 else
412 nFontStyle = wxNORMAL;
413
414 bool bFontUnderline = (pLogFont->fsSelection & FATTR_SEL_UNDERSCORE);
415 wxString sFontFace = pLogFont->szFacename;
416 int nFontPoints = pFM->lEmHeight;
417 wxFontEncoding vFontEncoding;
418
419 switch (pLogFont->usCodePage)
420 {
421 default:
422 wxFAIL_MSG(wxT("unsupported charset"));
423 // fall through
424
425 case 850:
426 vFontEncoding = wxFONTENCODING_CP1252;
427 break;
428
429 case 1250:
430 vFontEncoding = wxFONTENCODING_CP1250;
431 break;
432
433 case 921:
434 vFontEncoding = wxFONTENCODING_CP1257;
435 break;
436
437 case 866:
438 vFontEncoding = wxFONTENCODING_CP1251;
439 break;
440
441 case 864:
442 vFontEncoding = wxFONTENCODING_CP1256;
443 break;
444
445 case 869:
446 vFontEncoding = wxFONTENCODING_CP1253;
447 break;
448
449 case 862:
450 vFontEncoding = wxFONTENCODING_CP1255;
451 break;
452
453 case 857:
454 vFontEncoding = wxFONTENCODING_CP1254;
455 break;
456
457 case 874:
458 vFontEncoding = wxFONTENCODING_CP437;
459 break;
460
461 case 437:
462 vFontEncoding = wxFONTENCODING_CP437;
463 break;
464 }
465
466 return wxFont( nFontPoints
467 ,nFontFamily
468 ,nFontStyle
469 ,nFontWeight
470 ,bFontUnderline
471 ,sFontFace
472 ,vFontEncoding
473 );
474 } // end of wxCreateFontFromLogFont
475
476 int wxGpiStrcmp(
477 char* s0
478 , char* s1
479 )
480 { int l0;
481 int l1;
482 int l;
483 int d;
484 int d1;
485 int i;
486 int rc;
487
488 rc = 0;
489 if(s0 == NULL)
490 {
491 if(s1 == NULL)
492 return 0;
493 else
494 return 32;
495 }
496 else if(s1 == NULL)
497 return 32;
498
499 l0 = strlen(s0);
500 l1 = strlen(s1);
501 l = l0;
502 if(l0 != l1)
503 {
504 rc++;
505 if(l1 < l0)
506 l = l1;
507 }
508 for(i=0;i<l;i++)
509 {
510 d = s0[i]-s1[i];
511 if(!d)
512 continue;
513 d1 = toupper(s0[i]) - toupper(s1[i]);
514 if(!d1)
515 continue;
516 rc += abs(d);
517 }
518 return rc;
519 }
520