]> git.saurik.com Git - wxWidgets.git/blame - src/os2/fontutil.cpp
applied (slightly modified) wxGLApp patch for MSW
[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
3417f661 32 #include "wx/app.h"
d8cde57b
DW
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
1e1d0be1 54// encodingid;facename[;charset]
d8cde57b 55
e99762c0
DW
56bool wxNativeEncodingInfo::FromString(
57 const wxString& rsStr
58)
d8cde57b 59{
e99762c0
DW
60 wxStringTokenizer vTokenizer(rsStr, _T(";"));
61 wxString sEncid = vTokenizer.GetNextToken();
62 long lEnc;
d8cde57b 63
e99762c0 64 if (!sEncid.ToLong(&lEnc))
1e1d0be1 65 return FALSE;
e99762c0
DW
66 encoding = (wxFontEncoding)lEnc;
67 facename = vTokenizer.GetNextToken();
68 if (!facename)
d8cde57b
DW
69 return FALSE;
70
e99762c0
DW
71 wxString sTmp = vTokenizer.GetNextToken();
72
73 if (!sTmp)
d8cde57b 74 {
e99762c0 75 charset = 850;
d8cde57b
DW
76 }
77 else
78 {
e99762c0 79 if ( wxSscanf(sTmp, _T("%u"), &charset) != 1 )
d8cde57b
DW
80 {
81 // should be a number!
82 return FALSE;
83 }
84 }
d8cde57b 85 return TRUE;
e99762c0 86} // end of wxNativeEncodingInfo::FromString
d8cde57b
DW
87
88wxString wxNativeEncodingInfo::ToString() const
89{
e99762c0 90 wxString sStr;
7e99520b 91
e99762c0 92 sStr << (long)encoding << _T(';') << facename;
1e1d0be1 93
e99762c0 94 if (charset != 850)
d8cde57b 95 {
e99762c0 96 sStr << _T(';') << charset;
d8cde57b 97 }
e99762c0
DW
98 return sStr;
99} // end of wxNativeEncodingInfo::ToString
d8cde57b
DW
100
101// ----------------------------------------------------------------------------
102// helper functions
103// ----------------------------------------------------------------------------
104
e99762c0
DW
105bool wxGetNativeFontEncoding(
106 wxFontEncoding vEncoding
107, wxNativeEncodingInfo* pInfo
108)
d8cde57b 109{
e99762c0
DW
110 wxCHECK_MSG(pInfo, FALSE, _T("bad pointer in wxGetNativeFontEncoding") );
111 if (vEncoding == wxFONTENCODING_DEFAULT)
d8cde57b 112 {
e99762c0 113 vEncoding = wxFont::GetDefaultEncoding();
d8cde57b 114 }
e99762c0 115 switch (vEncoding)
d8cde57b 116 {
d8cde57b
DW
117 case wxFONTENCODING_ISO8859_1:
118 case wxFONTENCODING_ISO8859_15:
e99762c0
DW
119 case wxFONTENCODING_CP1250:
120 pInfo->charset = 1250;
d8cde57b
DW
121 break;
122
e99762c0
DW
123 case wxFONTENCODING_ISO8859_2:
124 case wxFONTENCODING_CP1252:
125 pInfo->charset = 1252;
d8cde57b
DW
126 break;
127
e99762c0
DW
128 case wxFONTENCODING_ISO8859_4:
129 case wxFONTENCODING_ISO8859_10:
130 pInfo->charset = 921; // what is baltic?
d8cde57b
DW
131 break;
132
e99762c0
DW
133 case wxFONTENCODING_ISO8859_5:
134 case wxFONTENCODING_CP1251:
135 pInfo->charset = 1251;
d8cde57b
DW
136 break;
137
e99762c0
DW
138 case wxFONTENCODING_ISO8859_6:
139 pInfo->charset = 864;
d8cde57b
DW
140 break;
141
e99762c0
DW
142 case wxFONTENCODING_ISO8859_7:
143 pInfo->charset = 869;
d8cde57b
DW
144 break;
145
e99762c0
DW
146 case wxFONTENCODING_ISO8859_8:
147 pInfo->charset = 862;
d8cde57b
DW
148 break;
149
e99762c0
DW
150 case wxFONTENCODING_ISO8859_9:
151 pInfo->charset = 857;
d8cde57b
DW
152 break;
153
e99762c0
DW
154 case wxFONTENCODING_ISO8859_11:
155 pInfo->charset = 874; // what is thai
d8cde57b
DW
156 break;
157
158 case wxFONTENCODING_CP437:
e99762c0 159 pInfo->charset = 437;
d8cde57b 160 break;
e99762c0 161
d8cde57b 162 default:
e99762c0
DW
163 wxFAIL_MSG(wxT("unsupported encoding"));
164 // fall through
d8cde57b 165
e99762c0
DW
166 case wxFONTENCODING_SYSTEM:
167 pInfo->charset = 850;
168 break;
169 }
d8cde57b 170 return TRUE;
e99762c0 171} // end of wxGetNativeFontEncoding
d8cde57b 172
e99762c0
DW
173bool wxTestFontEncoding(
174 const wxNativeEncodingInfo& rInfo
175)
d8cde57b 176{
e99762c0
DW
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 ))
d8cde57b 197 {
e99762c0 198 ::WinReleasePS(hPS);
d8cde57b
DW
199 return FALSE;
200 }
e99762c0 201 ::WinReleasePS(hPS);
d8cde57b 202 return TRUE;
e99762c0 203} // end of wxTestFontEncoding
d8cde57b
DW
204
205// ----------------------------------------------------------------------------
206// wxFont <-> LOGFONT conversion
207// ----------------------------------------------------------------------------
208
e99762c0
DW
209void wxFillLogFont(
210 LOGFONT* pLogFont // OS2 GPI FATTRS
211, PFACENAMEDESC pFaceName
212, const wxFont* pFont
213)
d8cde57b 214{
e99762c0
DW
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())
d8cde57b
DW
224 {
225 case wxSCRIPT:
e99762c0 226 sFace = _T("Script");
d8cde57b
DW
227 break;
228
229 case wxDECORATIVE:
d8cde57b 230 case wxROMAN:
e99762c0 231 sFace = _T("Times New Roman");
d8cde57b
DW
232 break;
233
234 case wxTELETYPE:
235 case wxMODERN:
e99762c0 236 sFace = _T("Courier New");
d8cde57b
DW
237 break;
238
239 case wxSWISS:
e99762c0 240 sFace = _T("WarpSans");
d8cde57b
DW
241 break;
242
243 case wxDEFAULT:
244 default:
e99762c0 245 sFace = _T("Helv");
d8cde57b
DW
246 }
247
e99762c0 248 switch (pFont->GetWeight())
d8cde57b
DW
249 {
250 default:
251 wxFAIL_MSG(_T("unknown font weight"));
e99762c0
DW
252 uWeight = FWEIGHT_DONT_CARE;
253 break;
d8cde57b
DW
254
255 case wxNORMAL:
e99762c0 256 uWeight = FWEIGHT_NORMAL;
d8cde57b
DW
257 break;
258
259 case wxLIGHT:
e99762c0 260 uWeight = FWEIGHT_LIGHT;
d8cde57b
DW
261 break;
262
263 case wxBOLD:
e99762c0
DW
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;
d8cde57b
DW
271 break;
272 }
e99762c0 273 pFaceName->usWeightClass |= uWeight;
d8cde57b 274
e99762c0
DW
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
d8cde57b 286
e99762c0
DW
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)
d8cde57b 320 {
e99762c0 321 sFace = sFacename;
d8cde57b
DW
322 }
323 //else: ff_face is a reasonable default facename for this font family
324
e99762c0
DW
325 //
326 // Deal with encoding now
327 //
328 wxNativeEncodingInfo vInfo;
329 wxFontEncoding vEncoding = pFont->GetEncoding();
330
331 if (!wxGetNativeFontEncoding( vEncoding
332 ,&vInfo
333 ))
d8cde57b 334 {
e99762c0
DW
335 if ( !wxTheFontMapper->GetAltForEncoding( vEncoding
336 ,&vInfo
337 ))
d8cde57b 338 {
e99762c0
DW
339 //
340 // Unsupported encoding, replace with the default
341 //
342 vInfo.charset = 850;
d8cde57b
DW
343 }
344 }
345
e99762c0 346 if (!vInfo.facename.IsEmpty() )
d8cde57b 347 {
e99762c0
DW
348 //
349 // The facename determined by the encoding overrides everything else
350 //
351 sFace = vInfo.facename;
d8cde57b
DW
352 }
353
e99762c0
DW
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
364wxFont wxCreateFontFromLogFont(
365 const LOGFONT* pLogFont
366, const PFONTMETRICS pFM
367, PFACENAMEDESC pFaceName
368)
d8cde57b 369{
e99762c0
DW
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;
d8cde57b 385
e99762c0
DW
386 //
387 // Weight and Style
388 //
389 int nFontWeight = wxNORMAL;
d8cde57b 390
e99762c0 391 switch (pFaceName->usWeightClass)
d8cde57b 392 {
e99762c0
DW
393 case FWEIGHT_LIGHT:
394 nFontWeight = wxLIGHT;
d8cde57b
DW
395 break;
396
397 default:
e99762c0
DW
398 case FWEIGHT_NORMAL:
399 nFontWeight = wxNORMAL;
d8cde57b
DW
400 break;
401
e99762c0
DW
402 case FWEIGHT_BOLD:
403 nFontWeight = wxBOLD;
d8cde57b
DW
404 break;
405 }
406
e99762c0 407 int nFontStyle;
d8cde57b 408
e99762c0
DW
409 if(pLogFont->fsSelection & FATTR_SEL_ITALIC)
410 nFontStyle = wxITALIC;
411 else
412 nFontStyle = wxNORMAL;
d8cde57b 413
e99762c0
DW
414 bool bFontUnderline = (pLogFont->fsSelection & FATTR_SEL_UNDERSCORE);
415 wxString sFontFace = pLogFont->szFacename;
416 int nFontPoints = pFM->lEmHeight;
417 wxFontEncoding vFontEncoding;
d8cde57b 418
e99762c0 419 switch (pLogFont->usCodePage)
d8cde57b
DW
420 {
421 default:
422 wxFAIL_MSG(wxT("unsupported charset"));
423 // fall through
424
e99762c0
DW
425 case 850:
426 vFontEncoding = wxFONTENCODING_CP1252;
d8cde57b
DW
427 break;
428
e99762c0
DW
429 case 1250:
430 vFontEncoding = wxFONTENCODING_CP1250;
d8cde57b
DW
431 break;
432
e99762c0
DW
433 case 921:
434 vFontEncoding = wxFONTENCODING_CP1257;
d8cde57b
DW
435 break;
436
e99762c0
DW
437 case 866:
438 vFontEncoding = wxFONTENCODING_CP1251;
d8cde57b
DW
439 break;
440
e99762c0
DW
441 case 864:
442 vFontEncoding = wxFONTENCODING_CP1256;
d8cde57b
DW
443 break;
444
e99762c0
DW
445 case 869:
446 vFontEncoding = wxFONTENCODING_CP1253;
d8cde57b
DW
447 break;
448
e99762c0
DW
449 case 862:
450 vFontEncoding = wxFONTENCODING_CP1255;
d8cde57b
DW
451 break;
452
e99762c0
DW
453 case 857:
454 vFontEncoding = wxFONTENCODING_CP1254;
d8cde57b
DW
455 break;
456
e99762c0
DW
457 case 874:
458 vFontEncoding = wxFONTENCODING_CP437;
d8cde57b 459 break;
d8cde57b 460
e99762c0
DW
461 case 437:
462 vFontEncoding = wxFONTENCODING_CP437;
d8cde57b
DW
463 break;
464 }
465
e99762c0
DW
466 return wxFont( nFontPoints
467 ,nFontFamily
468 ,nFontStyle
469 ,nFontWeight
470 ,bFontUnderline
471 ,sFontFace
472 ,vFontEncoding
473 );
474} // end of wxCreateFontFromLogFont
475
476int 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;
d8cde57b 519}
d8cde57b 520