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