]> git.saurik.com Git - wxWidgets.git/blame - src/os2/fontutil.cpp
Ensure that the default wxWebView backends are registered.
[wxWidgets.git] / src / os2 / fontutil.cpp
CommitLineData
d8cde57b 1///////////////////////////////////////////////////////////////////////////////
80fdcdb9 2// Name: src/msw/fontutil.cpp
d8cde57b
DW
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>
65571936 9// Licence: wxWindows licence
d8cde57b
DW
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
6670f564
WS
23#define DEBUG_PRINTF(NAME) \
24 { \
25 static int raz=0; \
26 printf( #NAME " %i\n",raz); fflush(stdout); \
27 raz++; \
28 }
29
d8cde57b 30#ifndef WX_PRECOMP
3417f661 31 #include "wx/app.h"
d8cde57b
DW
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"
bd6685b3 41#include "wx/encinfo.h"
d8cde57b
DW
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
6670f564 56bool wxNativeEncodingInfo::FromString( const wxString& rsStr )
d8cde57b 57{
9a83f860 58 wxStringTokenizer vTokenizer(rsStr, wxT(";"));
e99762c0
DW
59 wxString sEncid = vTokenizer.GetNextToken();
60 long lEnc;
d8cde57b 61
e99762c0 62 if (!sEncid.ToLong(&lEnc))
1e1d0be1 63 return FALSE;
e99762c0
DW
64 encoding = (wxFontEncoding)lEnc;
65 facename = vTokenizer.GetNextToken();
66 if (!facename)
d8cde57b
DW
67 return FALSE;
68
e99762c0
DW
69 wxString sTmp = vTokenizer.GetNextToken();
70
71 if (!sTmp)
d8cde57b 72 {
e99762c0 73 charset = 850;
d8cde57b
DW
74 }
75 else
76 {
9a83f860 77 if ( wxSscanf(sTmp, wxT("%u"), &charset) != 1 )
d8cde57b
DW
78 {
79 // should be a number!
80 return FALSE;
81 }
82 }
6670f564 83 return true;
e99762c0 84} // end of wxNativeEncodingInfo::FromString
d8cde57b
DW
85
86wxString wxNativeEncodingInfo::ToString() const
87{
e99762c0 88 wxString sStr;
7e99520b 89
9a83f860 90 sStr << (long)encoding << wxT(';') << facename;
1e1d0be1 91
e99762c0 92 if (charset != 850)
d8cde57b 93 {
9a83f860 94 sStr << wxT(';') << charset;
d8cde57b 95 }
e99762c0
DW
96 return sStr;
97} // end of wxNativeEncodingInfo::ToString
d8cde57b
DW
98
99// ----------------------------------------------------------------------------
100// helper functions
101// ----------------------------------------------------------------------------
102
6670f564
WS
103bool wxGetNativeFontEncoding( wxFontEncoding vEncoding,
104 wxNativeEncodingInfo* pInfo )
d8cde57b 105{
9a83f860 106 wxCHECK_MSG(pInfo, FALSE, wxT("bad pointer in wxGetNativeFontEncoding") );
e99762c0 107 if (vEncoding == wxFONTENCODING_DEFAULT)
d8cde57b 108 {
e99762c0 109 vEncoding = wxFont::GetDefaultEncoding();
d8cde57b 110 }
e99762c0 111 switch (vEncoding)
d8cde57b 112 {
d8cde57b
DW
113 case wxFONTENCODING_ISO8859_1:
114 case wxFONTENCODING_ISO8859_15:
e99762c0
DW
115 case wxFONTENCODING_CP1250:
116 pInfo->charset = 1250;
d8cde57b
DW
117 break;
118
e99762c0
DW
119 case wxFONTENCODING_ISO8859_2:
120 case wxFONTENCODING_CP1252:
121 pInfo->charset = 1252;
d8cde57b
DW
122 break;
123
e99762c0
DW
124 case wxFONTENCODING_ISO8859_4:
125 case wxFONTENCODING_ISO8859_10:
126 pInfo->charset = 921; // what is baltic?
d8cde57b
DW
127 break;
128
e99762c0
DW
129 case wxFONTENCODING_ISO8859_5:
130 case wxFONTENCODING_CP1251:
131 pInfo->charset = 1251;
d8cde57b
DW
132 break;
133
e99762c0
DW
134 case wxFONTENCODING_ISO8859_6:
135 pInfo->charset = 864;
d8cde57b
DW
136 break;
137
e99762c0
DW
138 case wxFONTENCODING_ISO8859_7:
139 pInfo->charset = 869;
d8cde57b
DW
140 break;
141
e99762c0
DW
142 case wxFONTENCODING_ISO8859_8:
143 pInfo->charset = 862;
d8cde57b
DW
144 break;
145
e99762c0
DW
146 case wxFONTENCODING_ISO8859_9:
147 pInfo->charset = 857;
d8cde57b
DW
148 break;
149
e99762c0
DW
150 case wxFONTENCODING_ISO8859_11:
151 pInfo->charset = 874; // what is thai
d8cde57b
DW
152 break;
153
154 case wxFONTENCODING_CP437:
e99762c0 155 pInfo->charset = 437;
d8cde57b 156 break;
e99762c0 157
d8cde57b 158 default:
e99762c0
DW
159 wxFAIL_MSG(wxT("unsupported encoding"));
160 // fall through
d8cde57b 161
e99762c0
DW
162 case wxFONTENCODING_SYSTEM:
163 pInfo->charset = 850;
164 break;
165 }
6670f564 166 return true;
e99762c0 167} // end of wxGetNativeFontEncoding
d8cde57b 168
cc95f4f9
DW
169wxFontEncoding wxGetFontEncFromCharSet(
170 int nCharSet
171)
172{
173 wxFontEncoding eFontEncoding;
174
175 switch (nCharSet)
176 {
177 default:
178 case 1250:
179 eFontEncoding = wxFONTENCODING_CP1250;
180 break;
181
182 case 1252:
183 eFontEncoding = wxFONTENCODING_CP1252;
184 break;
185
186 case 921:
187 eFontEncoding = wxFONTENCODING_ISO8859_4;
188 break;
189
190 case 1251:
191 eFontEncoding = wxFONTENCODING_CP1251;
192 break;
193
194 case 864:
195 eFontEncoding = wxFONTENCODING_ISO8859_6;
196 break;
197
198 case 869:
199 eFontEncoding = wxFONTENCODING_ISO8859_7;
200 break;
201
202 case 862:
203 eFontEncoding = wxFONTENCODING_ISO8859_8;
204 break;
205
206 case 857:
207 eFontEncoding = wxFONTENCODING_ISO8859_9;
208 break;
209
210 case 874:
211 eFontEncoding = wxFONTENCODING_ISO8859_11;
212 break;
213
214 case 437:
215 eFontEncoding = wxFONTENCODING_CP437;
216 break;
217 }
218 return eFontEncoding;
219} // end of wxGetNativeFontEncoding
220
6670f564 221bool wxTestFontEncoding( const wxNativeEncodingInfo& rInfo )
d8cde57b 222{
6670f564
WS
223 FATTRS vLogFont;
224 HPS hPS;
e99762c0
DW
225
226 hPS = ::WinGetPS(HWND_DESKTOP);
227
228 memset(&vLogFont, '\0', sizeof(FATTRS)); // all default values
229 vLogFont.usRecordLength = sizeof(FATTRS);
6670f564 230 vLogFont.usCodePage = (USHORT)rInfo.charset;
e99762c0
DW
231 vLogFont.lMaxBaselineExt = 0L; // Outline fonts should use 0
232 vLogFont.lAveCharWidth = 0L; // Outline fonts should use 0
233 vLogFont.fsFontUse = FATTR_FONTUSE_OUTLINE | // only outline fonts allowed
234 FATTR_FONTUSE_TRANSFORMABLE; // may be transformed
235
e408bf52 236 wxStrlcpy((wxChar*)vLogFont.szFacename, rInfo.facename.c_str(), WXSIZEOF(vLogFont.szFacename));
e99762c0
DW
237
238 if (!::GpiCreateLogFont( hPS
239 ,NULL
240 ,1L
241 ,&vLogFont
242 ))
d8cde57b 243 {
e99762c0 244 ::WinReleasePS(hPS);
d8cde57b
DW
245 return FALSE;
246 }
e99762c0 247 ::WinReleasePS(hPS);
6670f564 248 return true;
e99762c0 249} // end of wxTestFontEncoding
d8cde57b
DW
250
251// ----------------------------------------------------------------------------
252// wxFont <-> LOGFONT conversion
253// ----------------------------------------------------------------------------
254
a4353f07
DW
255void wxConvertVectorFontSize(
256 FIXED fxPointSize
257, PFATTRS pFattrs
258)
259{
260 HPS hPS;
261 HDC hDC;
262 LONG lXFontResolution;
263 LONG lYFontResolution;
264 SIZEF vSizef;
265
266 hPS = WinGetScreenPS(HWND_DESKTOP); // Screen presentation space
267
268 //
269 // Query device context for the screen and then query
270 // the resolution of the device for the device context.
271 //
272
273 hDC = GpiQueryDevice(hPS);
274 DevQueryCaps( hDC, CAPS_HORIZONTAL_FONT_RES, (LONG)1, &lXFontResolution);
275 DevQueryCaps( hDC, CAPS_VERTICAL_FONT_RES, (LONG)1, &lYFontResolution);
276
277 //
278 // Calculate the size of the character box, based on the
279 // point size selected and the resolution of the device.
280 // The size parameters are of type FIXED, NOT int.
281 // NOTE: 1 point == 1/72 of an inch.
282 //
283
ad8dd67e
SN
284 // multiply first to avoid getting vSizef.cx,cy = 0 since fxPointSize
285 // is normally < 72 and FontResolution is typically ca. 100
286 vSizef.cx = (FIXED)( (fxPointSize * lXFontResolution) / 72 );
287 vSizef.cy = (FIXED)( (fxPointSize * lYFontResolution) / 72 );
a4353f07 288
ad8dd67e
SN
289 if (pFattrs)
290 {
291 pFattrs->lMaxBaselineExt = MAKELONG( HIUSHORT( vSizef.cy ), 0 );
292 pFattrs->lAveCharWidth = MAKELONG( HIUSHORT( vSizef.cx ), 0 );
293 }
a4353f07
DW
294 WinReleasePS(hPS);
295
296} // end of wxConvertVectorPointSize
297
6670f564
WS
298void wxFillLogFont( LOGFONT* pFattrs, // OS2 GPI FATTRS
299 PFACENAMEDESC pFaceName,
300 HPS* phPS,
301 bool* pbInternalPS,
302 long* pflId,
303 wxString& sFaceName,
304 wxFont* pFont )
d8cde57b 305{
6670f564
WS
306 LONG lNumFonts = 0L; // For system font count
307 ERRORID vError; // For logging API errors
308 LONG lTemp = 0L;
309 bool bInternalPS = false; // if we have to create one
310 PFONTMETRICS pFM = NULL;
cc95f4f9
DW
311
312 //
313 // Initial house cleaning to free data buffers and ensure we have a
314 // functional PS to work with
315 //
54ffa107 316 if (!*phPS)
cc95f4f9 317 {
54ffa107 318 *phPS = ::WinGetPS(HWND_DESKTOP);
6670f564 319 bInternalPS = true;
cc95f4f9
DW
320 }
321
322 //
323 // Determine the number of fonts.
324 //
54ffa107 325 if((lNumFonts = ::GpiQueryFonts( *phPS
a23692f0 326 ,QF_PUBLIC | QF_PRIVATE
54ffa107
DW
327 ,NULL
328 ,&lTemp
329 ,(LONG) sizeof(FONTMETRICS)
330 ,NULL
331 )) < 0L)
332 {
333 ERRORID vError;
334 wxString sError;
335
336 vError = ::WinGetLastError(wxGetInstance());
337 sError = wxPMErrorToStr(vError);
338 return;
339 }
cc95f4f9
DW
340
341 //
342 // Allocate space for the font metrics.
343 //
344 pFM = new FONTMETRICS[lNumFonts + 1];
e99762c0 345
cc95f4f9
DW
346 //
347 // Retrieve the font metrics.
348 //
349 lTemp = lNumFonts;
54ffa107 350 lTemp = ::GpiQueryFonts( *phPS
cc95f4f9
DW
351 ,QF_PUBLIC
352 ,NULL
353 ,&lTemp
354 ,(LONG) sizeof(FONTMETRICS)
355 ,pFM
356 );
357 pFont->SetFM( pFM
358 ,(int)lNumFonts
359 );
360
cc95f4f9
DW
361 //
362 // Initialize FATTR and FACENAMEDESC
363 //
364 pFattrs->usRecordLength = sizeof(FATTRS);
a4353f07 365 pFattrs->fsFontUse = FATTR_FONTUSE_OUTLINE; // only outline fonts allowed
cc95f4f9
DW
366 pFattrs->fsType = 0;
367 pFattrs->lMaxBaselineExt = pFattrs->lAveCharWidth = 0;
368 pFattrs->idRegistry = 0;
369 pFattrs->lMatch = 0;
370
371 pFaceName->usSize = sizeof(FACENAMEDESC);
a23692f0
DW
372 pFaceName->usWeightClass = FWEIGHT_DONT_CARE;
373 pFaceName->usWidthClass = FWIDTH_DONT_CARE;
cc95f4f9 374 pFaceName->usReserved = 0;
e99762c0 375 pFaceName->flOptions = 0;
cc95f4f9
DW
376
377 //
378 // This does the actual selection of fonts
379 //
380 wxOS2SelectMatchingFontByName( pFattrs
381 ,pFaceName
382 ,pFM
383 ,(int)lNumFonts
384 ,pFont
385 );
386 //
387 // We should now have the correct FATTRS set with the selected
388 // font, so now we need to generate an ID
389 //
54ffa107 390 long lNumLids = ::GpiQueryNumberSetIds(*phPS);
cc95f4f9
DW
391
392 if(lNumLids )
393 {
394 long alTypes[255];
395 STR8 azNames[255];
396 long alIds[255];
397
d697657f 398 memset(alIds, 0, sizeof(long) * 255);
54ffa107 399 if(!::GpiQuerySetIds( *phPS
cc95f4f9
DW
400 ,lNumLids
401 ,alTypes
402 ,azNames
403 ,alIds
404 ))
405 {
406 if (bInternalPS)
54ffa107 407 ::WinReleasePS(*phPS);
cc95f4f9
DW
408 return;
409 }
d697657f
DW
410 if (*pflId == 0L)
411 *pflId = 1L;
0d598bae 412 for(unsigned long LCNum = 0; LCNum < (unsigned long)lNumLids; LCNum++)
cc95f4f9
DW
413 if(alIds[LCNum] == *pflId)
414 ++*pflId;
415 if(*pflId > 254) // wow, no id available!
416 {
417 if (bInternalPS)
54ffa107 418 ::WinReleasePS(*phPS);
cc95f4f9
DW
419 return;
420 }
421 }
54ffa107
DW
422 else
423 *pflId = 1L;
cc95f4f9
DW
424 //
425 // Release and delete the current font
426 //
54ffa107
DW
427 ::GpiSetCharSet(*phPS, LCID_DEFAULT);/* release the font before deleting */
428 ::GpiDeleteSetId(*phPS, 1L); /* delete the logical font */
cc95f4f9
DW
429
430 //
431 // Now build a facestring
432 //
433 char zFacename[128];
434
435 strcpy(zFacename, pFattrs->szFacename);
436
54ffa107 437 if(::GpiQueryFaceString( *phPS
cc95f4f9
DW
438 ,zFacename
439 ,pFaceName
440 ,FACESIZE
441 ,pFattrs->szFacename
442 ) == GPI_ERROR)
443 {
444 vError = ::WinGetLastError(vHabmain);
445 }
0fba44b4 446 sFaceName = (wxChar*)zFacename;
828621c2 447 *pbInternalPS = bInternalPS;
cc95f4f9
DW
448
449 //
450 // That's it, we now have everything we need to actually create the font
451 //
452} // end of wxFillLogFont
453
454void wxOS2SelectMatchingFontByName(
455 PFATTRS pFattrs
456, PFACENAMEDESC pFaceName
457, PFONTMETRICS pFM
458, int nNumFonts
459, const wxFont* pFont
460)
461{
462 int i;
cc95f4f9 463 int nPointSize;
cc95f4f9 464 int nIs;
cc95f4f9 465 int nMinDiff0;
cc95f4f9
DW
466 int anDiff[16];
467 int anMinDiff[16];
e1146627 468 int nIndex = 0;
0fba44b4 469 wxChar zFontFaceName[FACESIZE];
cc95f4f9
DW
470 wxString sFaceName;
471 USHORT usWeightClass;
472 int fsSelection = 0;
473
474 nMinDiff0 = 0xf000;
475 for(i = 0;i < 16; i++)
476 anMinDiff[i] = nMinDiff0;
477
e99762c0 478 switch (pFont->GetFamily())
d8cde57b
DW
479 {
480 case wxSCRIPT:
1b75810c 481 sFaceName = wxT("Tms Rmn");
d8cde57b
DW
482 break;
483
484 case wxDECORATIVE:
07df68c8
DW
485 sFaceName = wxT("WarpSans");
486 break;
487
d8cde57b 488 case wxROMAN:
1b75810c 489 sFaceName = wxT("Tms Rmn");
d8cde57b
DW
490 break;
491
492 case wxTELETYPE:
1b75810c 493 sFaceName = wxT("Courier") ;
d8cde57b
DW
494 break;
495
e3bfcacf 496 case wxMODERN:
1b75810c 497 sFaceName = wxT("System VIO") ;
e3bfcacf
DW
498 break;
499
d8cde57b 500 case wxSWISS:
e3bfcacf 501 sFaceName = wxT("Helv") ;
d8cde57b
DW
502 break;
503
504 case wxDEFAULT:
505 default:
a23692f0 506 sFaceName = wxT("System VIO") ;
d8cde57b
DW
507 }
508
e99762c0 509 switch (pFont->GetWeight())
d8cde57b
DW
510 {
511 default:
9a83f860 512 wxFAIL_MSG(wxT("unknown font weight"));
cc95f4f9
DW
513 // fall through
514 usWeightClass = FWEIGHT_DONT_CARE;
e99762c0 515 break;
d8cde57b
DW
516
517 case wxNORMAL:
cc95f4f9 518 usWeightClass = FWEIGHT_NORMAL;
d8cde57b
DW
519 break;
520
521 case wxLIGHT:
cc95f4f9 522 usWeightClass = FWEIGHT_LIGHT;
d8cde57b
DW
523 break;
524
525 case wxBOLD:
cc95f4f9 526 usWeightClass = FWEIGHT_BOLD;
e99762c0
DW
527 break;
528
cc95f4f9
DW
529 case wxFONTWEIGHT_MAX:
530 usWeightClass = FWEIGHT_ULTRA_BOLD;
d8cde57b
DW
531 break;
532 }
cc95f4f9 533 pFaceName->usWeightClass = usWeightClass;
d8cde57b 534
e99762c0
DW
535 switch (pFont->GetStyle())
536 {
537 case wxITALIC:
538 case wxSLANT:
cc95f4f9
DW
539 fsSelection = FM_SEL_ITALIC;
540 pFaceName->flOptions = FTYPE_ITALIC;
e99762c0
DW
541 break;
542
543 default:
544 wxFAIL_MSG(wxT("unknown font slant"));
545 // fall through
d8cde57b 546
e99762c0 547 case wxNORMAL:
cc95f4f9 548 fsSelection = 0;
e99762c0
DW
549 break;
550 }
cc95f4f9 551
e408bf52 552 wxStrlcpy(zFontFaceName, sFaceName.c_str(), WXSIZEOF(zFontFaceName));
cc95f4f9 553 nPointSize = pFont->GetPointSize();
e99762c0
DW
554
555 //
cc95f4f9 556 // Matching logic to find the right FM struct
e99762c0 557 //
cc95f4f9
DW
558 nIndex = 0;
559 for(i = 0, nIs = 0; i < nNumFonts; i++)
d8cde57b 560 {
0fba44b4 561 anDiff[0] = wxGpiStrcmp((wxChar*)pFM[i].szFacename, zFontFaceName);
cc95f4f9
DW
562 anDiff[1] = abs(pFM[i].lEmHeight - nPointSize);
563 anDiff[2] = abs(pFM[i].usWeightClass - usWeightClass);
564 anDiff[3] = abs((pFM[i].fsSelection & 0x2f) - fsSelection);
565 if(anDiff[0] == 0)
566 {
cc95f4f9
DW
567 if( (nIs & 0x01) == 0)
568 {
569 nIs = 1;
570 nIndex = i;
571 anMinDiff[1] = anDiff[1];
572 anMinDiff[2] = anDiff[2];
573 anMinDiff[3] = anDiff[3];
574 }
575 else if(anDiff[3] < anMinDiff[3])
576 {
577 nIndex = i;
578 anMinDiff[3] = anDiff[3];
579 }
580 else if(anDiff[2] < anMinDiff[2])
581 {
582 nIndex = i;
583 anMinDiff[2] = anDiff[2];
584 }
585 else if(anDiff[1] < anMinDiff[1])
586 {
587 nIndex = i;
588 anMinDiff[1] = anDiff[1];
589 }
590 anMinDiff[0] = 0;
591 }
592 else if(anDiff[0] < anMinDiff[0])
593 {
594 nIs = 2;
595 nIndex = i;
596 anMinDiff[3] = anDiff[3];
597 anMinDiff[2] = anDiff[2];
598 anMinDiff[1] = anDiff[1];
599 anMinDiff[0] = anDiff[0];
600 }
601 else if(anDiff[0] == anMinDiff[0])
602 {
603 if(anDiff[3] < anMinDiff[3])
604 {
605 nIndex = i;
606 anMinDiff[3] = anDiff[3];
607 nIs = 2;
608 }
609 else if(anDiff[2] < anMinDiff[2])
610 {
611 nIndex = i;
612 anMinDiff[2] = anDiff[2];
613 nIs = 2;
614 }
615 else if(anDiff[1] < anMinDiff[1])
616 {
617 nIndex = i;
618 anMinDiff[1] = anDiff[1];
619 nIs = 2;
620 }
621 }
d8cde57b 622 }
d8cde57b 623
e99762c0 624 //
cc95f4f9 625 // Fill in the FATTRS with the best match from FONTMETRICS
e99762c0 626 //
a23692f0 627 pFattrs->usRecordLength = sizeof(FATTRS); // Sets size of structure
a23692f0 628 pFattrs->lMatch = pFM[nIndex].lMatch; // Force match
f289196b
DW
629 pFattrs->idRegistry = 0;
630 pFattrs->usCodePage = 0;
631 pFattrs->fsFontUse = 0;
632 pFattrs->fsType = 0;
633 pFattrs->lMaxBaselineExt = 0;
634 pFattrs->lAveCharWidth = 0;
0fba44b4 635 wxStrcpy((wxChar*)pFattrs->szFacename, (wxChar*)pFM[nIndex].szFacename);
a4353f07
DW
636 if (pFont->GetWeight() == wxNORMAL)
637 pFattrs->fsSelection = 0;
638 else
639 pFattrs->fsSelection = FATTR_SEL_BOLD;
cc95f4f9 640
a4353f07 641 if (pFont->GetStyle() == wxITALIC || pFont->GetStyle() == wxSLANT)
cc95f4f9 642 pFattrs->fsSelection |= FATTR_SEL_ITALIC;
a4353f07
DW
643
644 if (pFont->GetUnderlined())
645 pFattrs->fsSelection |= FATTR_SEL_UNDERSCORE;
cc95f4f9 646} // end of wxOS2SelectMatchingFontByName
e99762c0
DW
647
648wxFont wxCreateFontFromLogFont(
649 const LOGFONT* pLogFont
650, const PFONTMETRICS pFM
651, PFACENAMEDESC pFaceName
652)
d8cde57b 653{
47df2b8c 654 wxNativeFontInfo vInfo;
d8cde57b 655
47df2b8c
DW
656 vInfo.fa = *pLogFont;
657 vInfo.fm = *pFM;
658 vInfo.fn = *pFaceName;
659 return wxFont(vInfo);
e99762c0
DW
660} // end of wxCreateFontFromLogFont
661
662int wxGpiStrcmp(
0fba44b4
DW
663 wxChar* s0
664, wxChar* s1
e99762c0
DW
665)
666{ int l0;
667 int l1;
668 int l;
669 int d;
670 int d1;
671 int i;
672 int rc;
673
674 rc = 0;
675 if(s0 == NULL)
676 {
677 if(s1 == NULL)
678 return 0;
679 else
680 return 32;
681 }
682 else if(s1 == NULL)
683 return 32;
684
0fba44b4
DW
685 l0 = wxStrlen(s0);
686 l1 = wxStrlen(s1);
e99762c0
DW
687 l = l0;
688 if(l0 != l1)
689 {
690 rc++;
691 if(l1 < l0)
692 l = l1;
693 }
694 for(i=0;i<l;i++)
695 {
696 d = s0[i]-s1[i];
697 if(!d)
698 continue;
0fba44b4 699 d1 = wxToupper(s0[i]) - wxToupper(s1[i]);
e99762c0
DW
700 if(!d1)
701 continue;
702 rc += abs(d);
703 }
704 return rc;
d8cde57b 705}