]> git.saurik.com Git - wxWidgets.git/blame - src/os2/fontutil.cpp
Better sorting example and better default
[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>
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{
e99762c0
DW
58 wxStringTokenizer vTokenizer(rsStr, _T(";"));
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 {
e99762c0 77 if ( wxSscanf(sTmp, _T("%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
e99762c0 90 sStr << (long)encoding << _T(';') << facename;
1e1d0be1 91
e99762c0 92 if (charset != 850)
d8cde57b 93 {
e99762c0 94 sStr << _T(';') << 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{
e99762c0
DW
106 wxCHECK_MSG(pInfo, FALSE, _T("bad pointer in wxGetNativeFontEncoding") );
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
0fba44b4 236 wxStrncpy((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
284 vSizef.cx = (FIXED)(((fxPointSize) / 72 ) * lXFontResolution );
285 vSizef.cy = (FIXED)(((fxPointSize) / 72 ) * lYFontResolution );
286
287 pFattrs->lMaxBaselineExt = MAKELONG( HIUSHORT( vSizef.cy ), 0 );
288 pFattrs->lAveCharWidth = MAKELONG( HIUSHORT( vSizef.cx ), 0 );
289 WinReleasePS(hPS);
290
291} // end of wxConvertVectorPointSize
292
6670f564
WS
293void wxFillLogFont( LOGFONT* pFattrs, // OS2 GPI FATTRS
294 PFACENAMEDESC pFaceName,
295 HPS* phPS,
296 bool* pbInternalPS,
297 long* pflId,
298 wxString& sFaceName,
299 wxFont* pFont )
d8cde57b 300{
6670f564
WS
301 LONG lNumFonts = 0L; // For system font count
302 ERRORID vError; // For logging API errors
303 LONG lTemp = 0L;
304 bool bInternalPS = false; // if we have to create one
305 PFONTMETRICS pFM = NULL;
cc95f4f9
DW
306
307 //
308 // Initial house cleaning to free data buffers and ensure we have a
309 // functional PS to work with
310 //
54ffa107 311 if (!*phPS)
cc95f4f9 312 {
54ffa107 313 *phPS = ::WinGetPS(HWND_DESKTOP);
6670f564 314 bInternalPS = true;
cc95f4f9
DW
315 }
316
317 //
318 // Determine the number of fonts.
319 //
54ffa107 320 if((lNumFonts = ::GpiQueryFonts( *phPS
a23692f0 321 ,QF_PUBLIC | QF_PRIVATE
54ffa107
DW
322 ,NULL
323 ,&lTemp
324 ,(LONG) sizeof(FONTMETRICS)
325 ,NULL
326 )) < 0L)
327 {
328 ERRORID vError;
329 wxString sError;
330
331 vError = ::WinGetLastError(wxGetInstance());
332 sError = wxPMErrorToStr(vError);
333 return;
334 }
cc95f4f9
DW
335
336 //
337 // Allocate space for the font metrics.
338 //
339 pFM = new FONTMETRICS[lNumFonts + 1];
e99762c0 340
cc95f4f9
DW
341 //
342 // Retrieve the font metrics.
343 //
344 lTemp = lNumFonts;
54ffa107 345 lTemp = ::GpiQueryFonts( *phPS
cc95f4f9
DW
346 ,QF_PUBLIC
347 ,NULL
348 ,&lTemp
349 ,(LONG) sizeof(FONTMETRICS)
350 ,pFM
351 );
352 pFont->SetFM( pFM
353 ,(int)lNumFonts
354 );
355
cc95f4f9
DW
356 //
357 // Initialize FATTR and FACENAMEDESC
358 //
359 pFattrs->usRecordLength = sizeof(FATTRS);
a4353f07 360 pFattrs->fsFontUse = FATTR_FONTUSE_OUTLINE; // only outline fonts allowed
cc95f4f9
DW
361 pFattrs->fsType = 0;
362 pFattrs->lMaxBaselineExt = pFattrs->lAveCharWidth = 0;
363 pFattrs->idRegistry = 0;
364 pFattrs->lMatch = 0;
365
366 pFaceName->usSize = sizeof(FACENAMEDESC);
a23692f0
DW
367 pFaceName->usWeightClass = FWEIGHT_DONT_CARE;
368 pFaceName->usWidthClass = FWIDTH_DONT_CARE;
cc95f4f9 369 pFaceName->usReserved = 0;
e99762c0 370 pFaceName->flOptions = 0;
cc95f4f9
DW
371
372 //
373 // This does the actual selection of fonts
374 //
375 wxOS2SelectMatchingFontByName( pFattrs
376 ,pFaceName
377 ,pFM
378 ,(int)lNumFonts
379 ,pFont
380 );
381 //
382 // We should now have the correct FATTRS set with the selected
383 // font, so now we need to generate an ID
384 //
54ffa107 385 long lNumLids = ::GpiQueryNumberSetIds(*phPS);
cc95f4f9
DW
386
387 if(lNumLids )
388 {
389 long alTypes[255];
390 STR8 azNames[255];
391 long alIds[255];
392
d697657f 393 memset(alIds, 0, sizeof(long) * 255);
54ffa107 394 if(!::GpiQuerySetIds( *phPS
cc95f4f9
DW
395 ,lNumLids
396 ,alTypes
397 ,azNames
398 ,alIds
399 ))
400 {
401 if (bInternalPS)
54ffa107 402 ::WinReleasePS(*phPS);
cc95f4f9
DW
403 return;
404 }
d697657f
DW
405 if (*pflId == 0L)
406 *pflId = 1L;
0d598bae 407 for(unsigned long LCNum = 0; LCNum < (unsigned long)lNumLids; LCNum++)
cc95f4f9
DW
408 if(alIds[LCNum] == *pflId)
409 ++*pflId;
410 if(*pflId > 254) // wow, no id available!
411 {
412 if (bInternalPS)
54ffa107 413 ::WinReleasePS(*phPS);
cc95f4f9
DW
414 return;
415 }
416 }
54ffa107
DW
417 else
418 *pflId = 1L;
cc95f4f9
DW
419 //
420 // Release and delete the current font
421 //
54ffa107
DW
422 ::GpiSetCharSet(*phPS, LCID_DEFAULT);/* release the font before deleting */
423 ::GpiDeleteSetId(*phPS, 1L); /* delete the logical font */
cc95f4f9
DW
424
425 //
426 // Now build a facestring
427 //
428 char zFacename[128];
429
430 strcpy(zFacename, pFattrs->szFacename);
431
54ffa107 432 if(::GpiQueryFaceString( *phPS
cc95f4f9
DW
433 ,zFacename
434 ,pFaceName
435 ,FACESIZE
436 ,pFattrs->szFacename
437 ) == GPI_ERROR)
438 {
439 vError = ::WinGetLastError(vHabmain);
440 }
0fba44b4 441 sFaceName = (wxChar*)zFacename;
828621c2 442 *pbInternalPS = bInternalPS;
cc95f4f9
DW
443
444 //
445 // That's it, we now have everything we need to actually create the font
446 //
447} // end of wxFillLogFont
448
449void wxOS2SelectMatchingFontByName(
450 PFATTRS pFattrs
451, PFACENAMEDESC pFaceName
452, PFONTMETRICS pFM
453, int nNumFonts
454, const wxFont* pFont
455)
456{
457 int i;
cc95f4f9 458 int nPointSize;
cc95f4f9 459 int nIs;
cc95f4f9 460 int nMinDiff0;
cc95f4f9
DW
461 int anDiff[16];
462 int anMinDiff[16];
e1146627 463 int nIndex = 0;
0fba44b4 464 wxChar zFontFaceName[FACESIZE];
cc95f4f9
DW
465 wxString sFaceName;
466 USHORT usWeightClass;
467 int fsSelection = 0;
468
469 nMinDiff0 = 0xf000;
470 for(i = 0;i < 16; i++)
471 anMinDiff[i] = nMinDiff0;
472
e99762c0 473 switch (pFont->GetFamily())
d8cde57b
DW
474 {
475 case wxSCRIPT:
1b75810c 476 sFaceName = wxT("Tms Rmn");
d8cde57b
DW
477 break;
478
479 case wxDECORATIVE:
07df68c8
DW
480 sFaceName = wxT("WarpSans");
481 break;
482
d8cde57b 483 case wxROMAN:
1b75810c 484 sFaceName = wxT("Tms Rmn");
d8cde57b
DW
485 break;
486
487 case wxTELETYPE:
1b75810c 488 sFaceName = wxT("Courier") ;
d8cde57b
DW
489 break;
490
e3bfcacf 491 case wxMODERN:
1b75810c 492 sFaceName = wxT("System VIO") ;
e3bfcacf
DW
493 break;
494
d8cde57b 495 case wxSWISS:
e3bfcacf 496 sFaceName = wxT("Helv") ;
d8cde57b
DW
497 break;
498
499 case wxDEFAULT:
500 default:
a23692f0 501 sFaceName = wxT("System VIO") ;
d8cde57b
DW
502 }
503
e99762c0 504 switch (pFont->GetWeight())
d8cde57b
DW
505 {
506 default:
507 wxFAIL_MSG(_T("unknown font weight"));
cc95f4f9
DW
508 // fall through
509 usWeightClass = FWEIGHT_DONT_CARE;
e99762c0 510 break;
d8cde57b
DW
511
512 case wxNORMAL:
cc95f4f9 513 usWeightClass = FWEIGHT_NORMAL;
d8cde57b
DW
514 break;
515
516 case wxLIGHT:
cc95f4f9 517 usWeightClass = FWEIGHT_LIGHT;
d8cde57b
DW
518 break;
519
520 case wxBOLD:
cc95f4f9 521 usWeightClass = FWEIGHT_BOLD;
e99762c0
DW
522 break;
523
cc95f4f9
DW
524 case wxFONTWEIGHT_MAX:
525 usWeightClass = FWEIGHT_ULTRA_BOLD;
d8cde57b
DW
526 break;
527 }
cc95f4f9 528 pFaceName->usWeightClass = usWeightClass;
d8cde57b 529
e99762c0
DW
530 switch (pFont->GetStyle())
531 {
532 case wxITALIC:
533 case wxSLANT:
cc95f4f9
DW
534 fsSelection = FM_SEL_ITALIC;
535 pFaceName->flOptions = FTYPE_ITALIC;
e99762c0
DW
536 break;
537
538 default:
539 wxFAIL_MSG(wxT("unknown font slant"));
540 // fall through
d8cde57b 541
e99762c0 542 case wxNORMAL:
cc95f4f9 543 fsSelection = 0;
e99762c0
DW
544 break;
545 }
cc95f4f9
DW
546
547 wxStrncpy(zFontFaceName, sFaceName.c_str(), WXSIZEOF(zFontFaceName));
548 nPointSize = pFont->GetPointSize();
e99762c0
DW
549
550 //
cc95f4f9 551 // Matching logic to find the right FM struct
e99762c0 552 //
cc95f4f9
DW
553 nIndex = 0;
554 for(i = 0, nIs = 0; i < nNumFonts; i++)
d8cde57b 555 {
cc95f4f9
DW
556 int nEmHeight = 0;
557 int nXHeight = 0;
558
0fba44b4 559 anDiff[0] = wxGpiStrcmp((wxChar*)pFM[i].szFacename, zFontFaceName);
cc95f4f9
DW
560 anDiff[1] = abs(pFM[i].lEmHeight - nPointSize);
561 anDiff[2] = abs(pFM[i].usWeightClass - usWeightClass);
562 anDiff[3] = abs((pFM[i].fsSelection & 0x2f) - fsSelection);
563 if(anDiff[0] == 0)
564 {
565 nEmHeight = (int)pFM[i].lEmHeight;
566 nXHeight =(int)pFM[i].lXHeight;
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}