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