///////////////////////////////////////////////////////////////////////////////
-// Name: msw/fontutil.cpp
+// Name: src/msw/fontutil.cpp
// Purpose: font-related helper functions for wxMSW
// Author: Modified by David Webster for OS/2
// Modified by:
// Created: 01.03.00
// RCS-ID: $Id$
// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
-// Licence: wxWindows license
+// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// ============================================================================
// headers
// ----------------------------------------------------------------------------
-#ifdef __GNUG__
- #pragma implementation "fontutil.h"
-#endif
-
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
+#define DEBUG_PRINTF(NAME) \
+ { \
+ static int raz=0; \
+ printf( #NAME " %i\n",raz); fflush(stdout); \
+ raz++; \
+ }
+
#ifndef WX_PRECOMP
+ #include "wx/app.h"
#include "wx/string.h"
#include "wx/log.h"
#include "wx/intl.h"
#include "wx/fontutil.h"
#include "wx/fontmap.h"
+#include "wx/encinfo.h"
#include "wx/tokenzr.h"
// convert to/from the string representation: format is
// encodingid;facename[;charset]
-bool wxNativeEncodingInfo::FromString(const wxString& s)
+bool wxNativeEncodingInfo::FromString( const wxString& rsStr )
{
- wxStringTokenizer tokenizer(s, _T(";"));
+ wxStringTokenizer vTokenizer(rsStr, wxT(";"));
+ wxString sEncid = vTokenizer.GetNextToken();
+ long lEnc;
- wxString encid = tokenizer.GetNextToken();
- long enc;
- if ( !encid.ToLong(&enc) )
+ if (!sEncid.ToLong(&lEnc))
return FALSE;
- encoding = (wxFontEncoding)enc;
-
- facename = tokenizer.GetNextToken();
- if ( !facename )
+ encoding = (wxFontEncoding)lEnc;
+ facename = vTokenizer.GetNextToken();
+ if (!facename)
return FALSE;
- wxString tmp = tokenizer.GetNextToken();
- if ( !tmp )
+ wxString sTmp = vTokenizer.GetNextToken();
+
+ if (!sTmp)
{
- // default charset (don't use DEFAULT_CHARSET though because of subtle
- // Windows 9x/NT differences in handling it)
-// TODO: what is this for OS/2?
-// charset = ANSI_CHARSET;
+ charset = 850;
}
else
{
- if ( wxSscanf(tmp, _T("%u"), &charset) != 1 )
+ if ( wxSscanf(sTmp, wxT("%u"), &charset) != 1 )
{
// should be a number!
return FALSE;
}
}
-
- return TRUE;
-}
+ return true;
+} // end of wxNativeEncodingInfo::FromString
wxString wxNativeEncodingInfo::ToString() const
{
- wxString s;
-
- s << (long)encoding << _T(';') << facename;
+ wxString sStr;
-// TODO: what is this for OS/2?
-/*
- if ( charset != ANSI_CHARSET )
+ sStr << (long)encoding << wxT(';') << facename;
+
+ if (charset != 850)
{
- s << _T(';') << charset;
+ sStr << wxT(';') << charset;
}
-*/
- return s;
-}
+ return sStr;
+} // end of wxNativeEncodingInfo::ToString
// ----------------------------------------------------------------------------
// helper functions
// ----------------------------------------------------------------------------
-bool wxGetNativeFontEncoding(wxFontEncoding encoding,
- wxNativeEncodingInfo *info)
+bool wxGetNativeFontEncoding( wxFontEncoding vEncoding,
+ wxNativeEncodingInfo* pInfo )
{
- wxCHECK_MSG( info, FALSE, _T("bad pointer in wxGetNativeFontEncoding") );
-
- if ( encoding == wxFONTENCODING_DEFAULT )
+ wxCHECK_MSG(pInfo, FALSE, wxT("bad pointer in wxGetNativeFontEncoding") );
+ if (vEncoding == wxFONTENCODING_DEFAULT)
{
- encoding = wxFont::GetDefaultEncoding();
+ vEncoding = wxFont::GetDefaultEncoding();
}
-
- switch ( encoding )
+ switch (vEncoding)
{
-// TODO: fix this for OS2
-/*
- // although this function is supposed to return an exact match, do do
- // some mappings here for the most common case of "standard" encoding
- case wxFONTENCODING_SYSTEM:
case wxFONTENCODING_ISO8859_1:
case wxFONTENCODING_ISO8859_15:
- case wxFONTENCODING_CP1252:
- info->charset = ANSI_CHARSET;
+ case wxFONTENCODING_CP1250:
+ pInfo->charset = 1250;
break;
- case wxFONTENCODING_CP1250:
- info->charset = EASTEUROPE_CHARSET;
+ case wxFONTENCODING_ISO8859_2:
+ case wxFONTENCODING_CP1252:
+ pInfo->charset = 1252;
break;
- case wxFONTENCODING_CP1251:
- info->charset = RUSSIAN_CHARSET;
+ case wxFONTENCODING_ISO8859_4:
+ case wxFONTENCODING_ISO8859_10:
+ pInfo->charset = 921; // what is baltic?
break;
- case wxFONTENCODING_CP1253:
- info->charset = GREEK_CHARSET;
+ case wxFONTENCODING_ISO8859_5:
+ case wxFONTENCODING_CP1251:
+ pInfo->charset = 1251;
break;
- case wxFONTENCODING_CP1254:
- info->charset = TURKISH_CHARSET;
+ case wxFONTENCODING_ISO8859_6:
+ pInfo->charset = 864;
break;
- case wxFONTENCODING_CP1255:
- info->charset = HEBREW_CHARSET;
+ case wxFONTENCODING_ISO8859_7:
+ pInfo->charset = 869;
break;
- case wxFONTENCODING_CP1256:
- info->charset = ARABIC_CHARSET;
+ case wxFONTENCODING_ISO8859_8:
+ pInfo->charset = 862;
break;
- case wxFONTENCODING_CP1257:
- info->charset = BALTIC_CHARSET;
+ case wxFONTENCODING_ISO8859_9:
+ pInfo->charset = 857;
break;
- case wxFONTENCODING_CP874:
- info->charset = THAI_CHARSET;
+ case wxFONTENCODING_ISO8859_11:
+ pInfo->charset = 874; // what is thai
break;
case wxFONTENCODING_CP437:
- info->charset = OEM_CHARSET;
+ pInfo->charset = 437;
break;
-*/
+
default:
- // no way to translate this encoding into a Windows charset
- return FALSE;
- }
+ wxFAIL_MSG(wxT("unsupported encoding"));
+ // fall through
- return TRUE;
-}
+ case wxFONTENCODING_SYSTEM:
+ pInfo->charset = 850;
+ break;
+ }
+ return true;
+} // end of wxGetNativeFontEncoding
-bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
+wxFontEncoding wxGetFontEncFromCharSet(
+ int nCharSet
+)
{
- // TODO:
- /*
- // try to create such font
- LOGFONT lf;
- wxZeroMemory(lf); // all default values
-
- lf.lfCharSet = info.charset;
- strncpy(lf.lfFaceName, info.facename, sizeof(lf.lfFaceName));
+ wxFontEncoding eFontEncoding;
- HFONT hfont = ::CreateFontIndirect(&lf);
- if ( !hfont )
+ switch (nCharSet)
{
- // no such font
- return FALSE;
- }
+ default:
+ case 1250:
+ eFontEncoding = wxFONTENCODING_CP1250;
+ break;
- ::DeleteObject((HGDIOBJ)hfont);
-*/
- return TRUE;
-}
+ case 1252:
+ eFontEncoding = wxFONTENCODING_CP1252;
+ break;
-// ----------------------------------------------------------------------------
-// wxFont <-> LOGFONT conversion
-// ----------------------------------------------------------------------------
+ case 921:
+ eFontEncoding = wxFONTENCODING_ISO8859_4;
+ break;
-#if 0
-void wxFillLogFont(LOGFONT *logFont, const wxFont *font)
-{
- int ff_family;
- wxString ff_face;
+ case 1251:
+ eFontEncoding = wxFONTENCODING_CP1251;
+ break;
- switch ( font->GetFamily() )
- {
- case wxSCRIPT:
- ff_family = FF_SCRIPT;
- ff_face = _T("Script");
+ case 864:
+ eFontEncoding = wxFONTENCODING_ISO8859_6;
break;
- case wxDECORATIVE:
- ff_family = FF_DECORATIVE;
+ case 869:
+ eFontEncoding = wxFONTENCODING_ISO8859_7;
break;
- case wxROMAN:
- ff_family = FF_ROMAN;
- ff_face = _T("Times New Roman");
+ case 862:
+ eFontEncoding = wxFONTENCODING_ISO8859_8;
break;
- case wxTELETYPE:
- case wxMODERN:
- ff_family = FF_MODERN;
- ff_face = _T("Courier New");
+ case 857:
+ eFontEncoding = wxFONTENCODING_ISO8859_9;
break;
- case wxSWISS:
- ff_family = FF_SWISS;
- ff_face = _T("Arial");
+ case 874:
+ eFontEncoding = wxFONTENCODING_ISO8859_11;
break;
- case wxDEFAULT:
- default:
- ff_family = FF_SWISS;
- ff_face = _T("MS Sans Serif");
+ case 437:
+ eFontEncoding = wxFONTENCODING_CP437;
+ break;
}
+ return eFontEncoding;
+} // end of wxGetNativeFontEncoding
- BYTE ff_italic;
- switch ( font->GetStyle() )
+bool wxTestFontEncoding( const wxNativeEncodingInfo& rInfo )
+{
+ FATTRS vLogFont;
+ HPS hPS;
+
+ hPS = ::WinGetPS(HWND_DESKTOP);
+
+ memset(&vLogFont, '\0', sizeof(FATTRS)); // all default values
+ vLogFont.usRecordLength = sizeof(FATTRS);
+ vLogFont.usCodePage = (USHORT)rInfo.charset;
+ vLogFont.lMaxBaselineExt = 0L; // Outline fonts should use 0
+ vLogFont.lAveCharWidth = 0L; // Outline fonts should use 0
+ vLogFont.fsFontUse = FATTR_FONTUSE_OUTLINE | // only outline fonts allowed
+ FATTR_FONTUSE_TRANSFORMABLE; // may be transformed
+
+ wxStrlcpy((wxChar*)vLogFont.szFacename, rInfo.facename.c_str(), WXSIZEOF(vLogFont.szFacename));
+
+ if (!::GpiCreateLogFont( hPS
+ ,NULL
+ ,1L
+ ,&vLogFont
+ ))
{
- case wxITALIC:
- case wxSLANT:
- ff_italic = 1;
- break;
-
- default:
- wxFAIL_MSG(wxT("unknown font slant"));
- // fall through
-
- case wxNORMAL:
- ff_italic = 0;
+ ::WinReleasePS(hPS);
+ return FALSE;
}
+ ::WinReleasePS(hPS);
+ return true;
+} // end of wxTestFontEncoding
- int ff_weight;
- switch ( font->GetWeight() )
+// ----------------------------------------------------------------------------
+// wxFont <-> LOGFONT conversion
+// ----------------------------------------------------------------------------
+
+void wxConvertVectorFontSize(
+ FIXED fxPointSize
+, PFATTRS pFattrs
+)
+{
+ HPS hPS;
+ HDC hDC;
+ LONG lXFontResolution;
+ LONG lYFontResolution;
+ SIZEF vSizef;
+
+ hPS = WinGetScreenPS(HWND_DESKTOP); // Screen presentation space
+
+ //
+ // Query device context for the screen and then query
+ // the resolution of the device for the device context.
+ //
+
+ hDC = GpiQueryDevice(hPS);
+ DevQueryCaps( hDC, CAPS_HORIZONTAL_FONT_RES, (LONG)1, &lXFontResolution);
+ DevQueryCaps( hDC, CAPS_VERTICAL_FONT_RES, (LONG)1, &lYFontResolution);
+
+ //
+ // Calculate the size of the character box, based on the
+ // point size selected and the resolution of the device.
+ // The size parameters are of type FIXED, NOT int.
+ // NOTE: 1 point == 1/72 of an inch.
+ //
+
+ // multiply first to avoid getting vSizef.cx,cy = 0 since fxPointSize
+ // is normally < 72 and FontResolution is typically ca. 100
+ vSizef.cx = (FIXED)( (fxPointSize * lXFontResolution) / 72 );
+ vSizef.cy = (FIXED)( (fxPointSize * lYFontResolution) / 72 );
+
+ if (pFattrs)
{
- default:
- wxFAIL_MSG(_T("unknown font weight"));
- // fall through
+ pFattrs->lMaxBaselineExt = MAKELONG( HIUSHORT( vSizef.cy ), 0 );
+ pFattrs->lAveCharWidth = MAKELONG( HIUSHORT( vSizef.cx ), 0 );
+ }
+ WinReleasePS(hPS);
- case wxNORMAL:
- ff_weight = FW_NORMAL;
- break;
+} // end of wxConvertVectorPointSize
- case wxLIGHT:
- ff_weight = FW_LIGHT;
- break;
-
- case wxBOLD:
- ff_weight = FW_BOLD;
- break;
+void wxFillLogFont( LOGFONT* pFattrs, // OS2 GPI FATTRS
+ PFACENAMEDESC pFaceName,
+ HPS* phPS,
+ bool* pbInternalPS,
+ long* pflId,
+ wxString& sFaceName,
+ wxFont* pFont )
+{
+ LONG lNumFonts = 0L; // For system font count
+ ERRORID vError; // For logging API errors
+ LONG lTemp = 0L;
+ bool bInternalPS = false; // if we have to create one
+ PFONTMETRICS pFM = NULL;
+
+ //
+ // Initial house cleaning to free data buffers and ensure we have a
+ // functional PS to work with
+ //
+ if (!*phPS)
+ {
+ *phPS = ::WinGetPS(HWND_DESKTOP);
+ bInternalPS = true;
}
-#if 0
- HDC dc = ::GetDC(NULL);
- int ppInch = ::GetDeviceCaps(dc, LOGPIXELSY);
- ::ReleaseDC(NULL, dc);
-#else
- // New behaviour: apparently ppInch varies according to Large/Small Fonts
- // setting in Windows. This messes up fonts. So, set ppInch to a constant
- // 96 dpi.
- static const int ppInch = 96;
-#endif // 0/1
-
-#if wxFONT_SIZE_COMPATIBILITY
- // Incorrect, but compatible with old wxWindows behaviour
- int nHeight = (font->GetPointSize()*ppInch/72);
-#else
- // Correct for Windows compatibility
- int nHeight = - (font->GetPointSize()*ppInch/72);
-#endif
-
- wxString facename = font->GetFaceName();
- if ( !!facename )
+ //
+ // Determine the number of fonts.
+ //
+ if((lNumFonts = ::GpiQueryFonts( *phPS
+ ,QF_PUBLIC | QF_PRIVATE
+ ,NULL
+ ,&lTemp
+ ,(LONG) sizeof(FONTMETRICS)
+ ,NULL
+ )) < 0L)
{
- ff_face = facename;
+ ERRORID vError;
+ wxString sError;
+
+ vError = ::WinGetLastError(wxGetInstance());
+ sError = wxPMErrorToStr(vError);
+ return;
}
- //else: ff_face is a reasonable default facename for this font family
- // deal with encoding now
- wxNativeEncodingInfo info;
- wxFontEncoding encoding = font->GetEncoding();
- if ( !wxGetNativeFontEncoding(encoding, &info) )
+ //
+ // Allocate space for the font metrics.
+ //
+ pFM = new FONTMETRICS[lNumFonts + 1];
+
+ //
+ // Retrieve the font metrics.
+ //
+ lTemp = lNumFonts;
+ lTemp = ::GpiQueryFonts( *phPS
+ ,QF_PUBLIC
+ ,NULL
+ ,&lTemp
+ ,(LONG) sizeof(FONTMETRICS)
+ ,pFM
+ );
+ pFont->SetFM( pFM
+ ,(int)lNumFonts
+ );
+
+ //
+ // Initialize FATTR and FACENAMEDESC
+ //
+ pFattrs->usRecordLength = sizeof(FATTRS);
+ pFattrs->fsFontUse = FATTR_FONTUSE_OUTLINE; // only outline fonts allowed
+ pFattrs->fsType = 0;
+ pFattrs->lMaxBaselineExt = pFattrs->lAveCharWidth = 0;
+ pFattrs->idRegistry = 0;
+ pFattrs->lMatch = 0;
+
+ pFaceName->usSize = sizeof(FACENAMEDESC);
+ pFaceName->usWeightClass = FWEIGHT_DONT_CARE;
+ pFaceName->usWidthClass = FWIDTH_DONT_CARE;
+ pFaceName->usReserved = 0;
+ pFaceName->flOptions = 0;
+
+ //
+ // This does the actual selection of fonts
+ //
+ wxOS2SelectMatchingFontByName( pFattrs
+ ,pFaceName
+ ,pFM
+ ,(int)lNumFonts
+ ,pFont
+ );
+ //
+ // We should now have the correct FATTRS set with the selected
+ // font, so now we need to generate an ID
+ //
+ long lNumLids = ::GpiQueryNumberSetIds(*phPS);
+
+ if(lNumLids )
{
- if ( !wxTheFontMapper->GetAltForEncoding(encoding, &info) )
+ long alTypes[255];
+ STR8 azNames[255];
+ long alIds[255];
+
+ memset(alIds, 0, sizeof(long) * 255);
+ if(!::GpiQuerySetIds( *phPS
+ ,lNumLids
+ ,alTypes
+ ,azNames
+ ,alIds
+ ))
+ {
+ if (bInternalPS)
+ ::WinReleasePS(*phPS);
+ return;
+ }
+ if (*pflId == 0L)
+ *pflId = 1L;
+ for(unsigned long LCNum = 0; LCNum < (unsigned long)lNumLids; LCNum++)
+ if(alIds[LCNum] == *pflId)
+ ++*pflId;
+ if(*pflId > 254) // wow, no id available!
{
- // unsupported encoding, replace with the default
- info.charset = ANSI_CHARSET;
+ if (bInternalPS)
+ ::WinReleasePS(*phPS);
+ return;
}
}
-
- if ( !info.facename.IsEmpty() )
+ else
+ *pflId = 1L;
+ //
+ // Release and delete the current font
+ //
+ ::GpiSetCharSet(*phPS, LCID_DEFAULT);/* release the font before deleting */
+ ::GpiDeleteSetId(*phPS, 1L); /* delete the logical font */
+
+ //
+ // Now build a facestring
+ //
+ char zFacename[128];
+
+ strcpy(zFacename, pFattrs->szFacename);
+
+ if(::GpiQueryFaceString( *phPS
+ ,zFacename
+ ,pFaceName
+ ,FACESIZE
+ ,pFattrs->szFacename
+ ) == GPI_ERROR)
{
- // the facename determined by the encoding overrides everything else
- ff_face = info.facename;
+ vError = ::WinGetLastError(vHabmain);
}
-
- // transfer all the data to LOGFONT
- logFont->lfHeight = nHeight;
- logFont->lfWidth = 0;
- logFont->lfEscapement = 0;
- logFont->lfOrientation = 0;
- logFont->lfWeight = ff_weight;
- logFont->lfItalic = ff_italic;
- logFont->lfUnderline = (BYTE)font->GetUnderlined();
- logFont->lfStrikeOut = 0;
- logFont->lfCharSet = info.charset;
- logFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
- logFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
- logFont->lfQuality = PROOF_QUALITY;
- logFont->lfPitchAndFamily = DEFAULT_PITCH | ff_family;
- wxStrncpy(logFont->lfFaceName, ff_face, WXSIZEOF(logFont->lfFaceName));
-}
-
-wxFont wxCreateFontFromLogFont(const LOGFONT *logFont)
+ sFaceName = (wxChar*)zFacename;
+ *pbInternalPS = bInternalPS;
+
+ //
+ // That's it, we now have everything we need to actually create the font
+ //
+} // end of wxFillLogFont
+
+void wxOS2SelectMatchingFontByName(
+ PFATTRS pFattrs
+, PFACENAMEDESC pFaceName
+, PFONTMETRICS pFM
+, int nNumFonts
+, const wxFont* pFont
+)
{
- // extract family from pitch-and-family
- int lfFamily = logFont->lfPitchAndFamily;
- if ( lfFamily & FIXED_PITCH )
- lfFamily -= FIXED_PITCH;
- if ( lfFamily & VARIABLE_PITCH )
- lfFamily -= VARIABLE_PITCH;
-
- int fontFamily;
- switch ( lfFamily )
+ int i;
+ int nPointSize;
+ int nIs;
+ int nMinDiff0;
+ int anDiff[16];
+ int anMinDiff[16];
+ int nIndex = 0;
+ wxChar zFontFaceName[FACESIZE];
+ wxString sFaceName;
+ USHORT usWeightClass;
+ int fsSelection = 0;
+
+ nMinDiff0 = 0xf000;
+ for(i = 0;i < 16; i++)
+ anMinDiff[i] = nMinDiff0;
+
+ switch (pFont->GetFamily())
{
- case FF_ROMAN:
- fontFamily = wxROMAN;
+ case wxSCRIPT:
+ sFaceName = wxT("Tms Rmn");
break;
- case FF_SWISS:
- fontFamily = wxSWISS;
+ case wxDECORATIVE:
+ sFaceName = wxT("WarpSans");
break;
- case FF_SCRIPT:
- fontFamily = wxSCRIPT;
+ case wxROMAN:
+ sFaceName = wxT("Tms Rmn");
break;
- case FF_MODERN:
- fontFamily = wxMODERN;
+ case wxTELETYPE:
+ sFaceName = wxT("Courier") ;
break;
- case FF_DECORATIVE:
- fontFamily = wxDECORATIVE;
+ case wxMODERN:
+ sFaceName = wxT("System VIO") ;
break;
- default:
- fontFamily = wxSWISS;
- }
-
- // weight and style
- int fontWeight = wxNORMAL;
- switch ( logFont->lfWeight )
- {
- case FW_LIGHT:
- fontWeight = wxLIGHT;
+ case wxSWISS:
+ sFaceName = wxT("Helv") ;
break;
+ case wxDEFAULT:
default:
- case FW_NORMAL:
- fontWeight = wxNORMAL;
- break;
-
- case FW_BOLD:
- fontWeight = wxBOLD;
- break;
+ sFaceName = wxT("System VIO") ;
}
- int fontStyle = logFont->lfItalic ? wxITALIC : wxNORMAL;
-
- bool fontUnderline = logFont->lfUnderline != 0;
-
- wxString fontFace = logFont->lfFaceName;
-
- // font size
- HDC dc = ::GetDC(NULL);
-
- // remember that 1pt = 1/72inch
- int height = abs(logFont->lfHeight);
- int fontPoints = (72*height)/GetDeviceCaps(dc, LOGPIXELSY);
-
- ::ReleaseDC(NULL, dc);
-
- wxFontEncoding fontEncoding;
- switch ( logFont->lfCharSet )
+ switch (pFont->GetWeight())
{
default:
- wxFAIL_MSG(wxT("unsupported charset"));
+ wxFAIL_MSG(wxT("unknown font weight"));
// fall through
-
- case ANSI_CHARSET:
- fontEncoding = wxFONTENCODING_CP1252;
+ usWeightClass = FWEIGHT_DONT_CARE;
break;
-#ifdef __WIN32__
- case EASTEUROPE_CHARSET:
- fontEncoding = wxFONTENCODING_CP1250;
+ case wxNORMAL:
+ usWeightClass = FWEIGHT_NORMAL;
break;
- case BALTIC_CHARSET:
- fontEncoding = wxFONTENCODING_CP1257;
+ case wxLIGHT:
+ usWeightClass = FWEIGHT_LIGHT;
break;
- case RUSSIAN_CHARSET:
- fontEncoding = wxFONTENCODING_CP1251;
+ case wxBOLD:
+ usWeightClass = FWEIGHT_BOLD;
break;
- case ARABIC_CHARSET:
- fontEncoding = wxFONTENCODING_CP1256;
+ case wxFONTWEIGHT_MAX:
+ usWeightClass = FWEIGHT_ULTRA_BOLD;
break;
+ }
+ pFaceName->usWeightClass = usWeightClass;
- case GREEK_CHARSET:
- fontEncoding = wxFONTENCODING_CP1253;
+ switch (pFont->GetStyle())
+ {
+ case wxITALIC:
+ case wxSLANT:
+ fsSelection = FM_SEL_ITALIC;
+ pFaceName->flOptions = FTYPE_ITALIC;
break;
- case HEBREW_CHARSET:
- fontEncoding = wxFONTENCODING_CP1255;
- break;
+ default:
+ wxFAIL_MSG(wxT("unknown font slant"));
+ // fall through
- case TURKISH_CHARSET:
- fontEncoding = wxFONTENCODING_CP1254;
+ case wxNORMAL:
+ fsSelection = 0;
break;
+ }
- case THAI_CHARSET:
- fontEncoding = wxFONTENCODING_CP437;
- break;
-#endif
+ wxStrlcpy(zFontFaceName, sFaceName.c_str(), WXSIZEOF(zFontFaceName));
+ nPointSize = pFont->GetPointSize();
- case OEM_CHARSET:
- fontEncoding = wxFONTENCODING_CP437;
- break;
+ //
+ // Matching logic to find the right FM struct
+ //
+ nIndex = 0;
+ for(i = 0, nIs = 0; i < nNumFonts; i++)
+ {
+ int nEmHeight = 0;
+ int nXHeight = 0;
+
+ anDiff[0] = wxGpiStrcmp((wxChar*)pFM[i].szFacename, zFontFaceName);
+ anDiff[1] = abs(pFM[i].lEmHeight - nPointSize);
+ anDiff[2] = abs(pFM[i].usWeightClass - usWeightClass);
+ anDiff[3] = abs((pFM[i].fsSelection & 0x2f) - fsSelection);
+ if(anDiff[0] == 0)
+ {
+ nEmHeight = (int)pFM[i].lEmHeight;
+ nXHeight =(int)pFM[i].lXHeight;
+ if( (nIs & 0x01) == 0)
+ {
+ nIs = 1;
+ nIndex = i;
+ anMinDiff[1] = anDiff[1];
+ anMinDiff[2] = anDiff[2];
+ anMinDiff[3] = anDiff[3];
+ }
+ else if(anDiff[3] < anMinDiff[3])
+ {
+ nIndex = i;
+ anMinDiff[3] = anDiff[3];
+ }
+ else if(anDiff[2] < anMinDiff[2])
+ {
+ nIndex = i;
+ anMinDiff[2] = anDiff[2];
+ }
+ else if(anDiff[1] < anMinDiff[1])
+ {
+ nIndex = i;
+ anMinDiff[1] = anDiff[1];
+ }
+ anMinDiff[0] = 0;
+ }
+ else if(anDiff[0] < anMinDiff[0])
+ {
+ nIs = 2;
+ nIndex = i;
+ anMinDiff[3] = anDiff[3];
+ anMinDiff[2] = anDiff[2];
+ anMinDiff[1] = anDiff[1];
+ anMinDiff[0] = anDiff[0];
+ }
+ else if(anDiff[0] == anMinDiff[0])
+ {
+ if(anDiff[3] < anMinDiff[3])
+ {
+ nIndex = i;
+ anMinDiff[3] = anDiff[3];
+ nIs = 2;
+ }
+ else if(anDiff[2] < anMinDiff[2])
+ {
+ nIndex = i;
+ anMinDiff[2] = anDiff[2];
+ nIs = 2;
+ }
+ else if(anDiff[1] < anMinDiff[1])
+ {
+ nIndex = i;
+ anMinDiff[1] = anDiff[1];
+ nIs = 2;
+ }
+ }
}
- return wxFont(fontPoints, fontFamily, fontStyle,
- fontWeight, fontUnderline, fontFace,
- fontEncoding);
-}
-#endif // 0
+ //
+ // Fill in the FATTRS with the best match from FONTMETRICS
+ //
+ pFattrs->usRecordLength = sizeof(FATTRS); // Sets size of structure
+ pFattrs->lMatch = pFM[nIndex].lMatch; // Force match
+ pFattrs->idRegistry = 0;
+ pFattrs->usCodePage = 0;
+ pFattrs->fsFontUse = 0;
+ pFattrs->fsType = 0;
+ pFattrs->lMaxBaselineExt = 0;
+ pFattrs->lAveCharWidth = 0;
+ wxStrcpy((wxChar*)pFattrs->szFacename, (wxChar*)pFM[nIndex].szFacename);
+ if (pFont->GetWeight() == wxNORMAL)
+ pFattrs->fsSelection = 0;
+ else
+ pFattrs->fsSelection = FATTR_SEL_BOLD;
+
+ if (pFont->GetStyle() == wxITALIC || pFont->GetStyle() == wxSLANT)
+ pFattrs->fsSelection |= FATTR_SEL_ITALIC;
+ if (pFont->GetUnderlined())
+ pFattrs->fsSelection |= FATTR_SEL_UNDERSCORE;
+} // end of wxOS2SelectMatchingFontByName
+
+wxFont wxCreateFontFromLogFont(
+ const LOGFONT* pLogFont
+, const PFONTMETRICS pFM
+, PFACENAMEDESC pFaceName
+)
+{
+ wxNativeFontInfo vInfo;
+
+ vInfo.fa = *pLogFont;
+ vInfo.fm = *pFM;
+ vInfo.fn = *pFaceName;
+ return wxFont(vInfo);
+} // end of wxCreateFontFromLogFont
+
+int wxGpiStrcmp(
+ wxChar* s0
+, wxChar* s1
+)
+{ int l0;
+ int l1;
+ int l;
+ int d;
+ int d1;
+ int i;
+ int rc;
+
+ rc = 0;
+ if(s0 == NULL)
+ {
+ if(s1 == NULL)
+ return 0;
+ else
+ return 32;
+ }
+ else if(s1 == NULL)
+ return 32;
+
+ l0 = wxStrlen(s0);
+ l1 = wxStrlen(s1);
+ l = l0;
+ if(l0 != l1)
+ {
+ rc++;
+ if(l1 < l0)
+ l = l1;
+ }
+ for(i=0;i<l;i++)
+ {
+ d = s0[i]-s1[i];
+ if(!d)
+ continue;
+ d1 = wxToupper(s0[i]) - wxToupper(s1[i]);
+ if(!d1)
+ continue;
+ rc += abs(d);
+ }
+ return rc;
+}