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