home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / os2 / fontutil.cpp < prev    next >
C/C++ Source or Header  |  2002-08-30  |  21KB  |  721 lines

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