/////////////////////////////////////////////////////////////////////////////// // Name: 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 // Licence: wxWindows license /////////////////////////////////////////////////////////////////////////////// #define DEBUG_PRINTF(NAME) { static int raz=0; \ printf( #NAME " %i\n",raz); fflush(stdout); \ raz++; \ } // ============================================================================ // declarations // ============================================================================ // ---------------------------------------------------------------------------- // headers // ---------------------------------------------------------------------------- #ifdef __GNUG__ #pragma implementation "fontutil.h" #endif // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifndef WX_PRECOMP #include "wx/string.h" #include "wx/log.h" #include "wx/intl.h" #endif //WX_PRECOMP #include "wx/os2/private.h" #include "wx/fontutil.h" #include "wx/fontmap.h" #include "wx/tokenzr.h" // ============================================================================ // implementation // ============================================================================ // ---------------------------------------------------------------------------- // wxNativeEncodingInfo // ---------------------------------------------------------------------------- // convert to/from the string representation: format is // encodingid;facename[;charset] bool wxNativeEncodingInfo::FromString(const wxString& s) { wxStringTokenizer tokenizer(s, _T(";")); wxString encid = tokenizer.GetNextToken(); long enc; if ( !encid.ToLong(&enc) ) return FALSE; encoding = (wxFontEncoding)enc; facename = tokenizer.GetNextToken(); if ( !facename ) return FALSE; wxString tmp = tokenizer.GetNextToken(); if ( !tmp ) { // 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; } else { if ( wxSscanf(tmp, _T("%u"), &charset) != 1 ) { // should be a number! return FALSE; } } return TRUE; } wxString wxNativeEncodingInfo::ToString() const { wxString s; s << (long)encoding << _T(';') << facename; // TODO: what is this for OS/2? /* if ( charset != ANSI_CHARSET ) { s << _T(';') << charset; } */ return s; } // ---------------------------------------------------------------------------- // helper functions // ---------------------------------------------------------------------------- bool wxGetNativeFontEncoding(wxFontEncoding encoding, wxNativeEncodingInfo *info) { wxCHECK_MSG( info, FALSE, _T("bad pointer in wxGetNativeFontEncoding") ); if ( encoding == wxFONTENCODING_DEFAULT ) { encoding = wxFont::GetDefaultEncoding(); } switch ( encoding ) { // 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; break; case wxFONTENCODING_CP1250: info->charset = EASTEUROPE_CHARSET; break; case wxFONTENCODING_CP1251: info->charset = RUSSIAN_CHARSET; break; case wxFONTENCODING_CP1253: info->charset = GREEK_CHARSET; break; case wxFONTENCODING_CP1254: info->charset = TURKISH_CHARSET; break; case wxFONTENCODING_CP1255: info->charset = HEBREW_CHARSET; break; case wxFONTENCODING_CP1256: info->charset = ARABIC_CHARSET; break; case wxFONTENCODING_CP1257: info->charset = BALTIC_CHARSET; break; case wxFONTENCODING_CP874: info->charset = THAI_CHARSET; break; case wxFONTENCODING_CP437: info->charset = OEM_CHARSET; break; */ default: // no way to translate this encoding into a Windows charset return FALSE; } return TRUE; } bool wxTestFontEncoding(const wxNativeEncodingInfo& info) { // 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)); HFONT hfont = ::CreateFontIndirect(&lf); if ( !hfont ) { // no such font return FALSE; } ::DeleteObject((HGDIOBJ)hfont); */ return TRUE; } // ---------------------------------------------------------------------------- // wxFont <-> LOGFONT conversion // ---------------------------------------------------------------------------- #if 0 void wxFillLogFont(LOGFONT *logFont, const wxFont *font) { int ff_family; wxString ff_face; switch ( font->GetFamily() ) { case wxSCRIPT: ff_family = FF_SCRIPT; ff_face = _T("Script"); break; case wxDECORATIVE: ff_family = FF_DECORATIVE; break; case wxROMAN: ff_family = FF_ROMAN; ff_face = _T("Times New Roman"); break; case wxTELETYPE: case wxMODERN: ff_family = FF_MODERN; ff_face = _T("Courier New"); break; case wxSWISS: ff_family = FF_SWISS; ff_face = _T("Arial"); break; case wxDEFAULT: default: ff_family = FF_SWISS; ff_face = _T("MS Sans Serif"); } BYTE ff_italic; switch ( font->GetStyle() ) { case wxITALIC: case wxSLANT: ff_italic = 1; break; default: wxFAIL_MSG(wxT("unknown font slant")); // fall through case wxNORMAL: ff_italic = 0; } int ff_weight; switch ( font->GetWeight() ) { default: wxFAIL_MSG(_T("unknown font weight")); // fall through case wxNORMAL: ff_weight = FW_NORMAL; break; case wxLIGHT: ff_weight = FW_LIGHT; break; case wxBOLD: ff_weight = FW_BOLD; break; } #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 ) { ff_face = facename; } //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) ) { if ( !wxTheFontMapper->GetAltForEncoding(encoding, &info) ) { // unsupported encoding, replace with the default info.charset = ANSI_CHARSET; } } if ( !info.facename.IsEmpty() ) { // the facename determined by the encoding overrides everything else ff_face = info.facename; } // 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) { DEBUG_PRINTF(wxCreateFontFromLogFont) // 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 ) { case FF_ROMAN: fontFamily = wxROMAN; break; case FF_SWISS: fontFamily = wxSWISS; break; case FF_SCRIPT: fontFamily = wxSCRIPT; break; case FF_MODERN: fontFamily = wxMODERN; break; case FF_DECORATIVE: fontFamily = wxDECORATIVE; break; default: fontFamily = wxSWISS; } // weight and style int fontWeight = wxNORMAL; switch ( logFont->lfWeight ) { case FW_LIGHT: fontWeight = wxLIGHT; break; default: case FW_NORMAL: fontWeight = wxNORMAL; break; case FW_BOLD: fontWeight = wxBOLD; break; } 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 ) { default: wxFAIL_MSG(wxT("unsupported charset")); // fall through case ANSI_CHARSET: fontEncoding = wxFONTENCODING_CP1252; break; #ifdef __WIN32__ case EASTEUROPE_CHARSET: fontEncoding = wxFONTENCODING_CP1250; break; case BALTIC_CHARSET: fontEncoding = wxFONTENCODING_CP1257; break; case RUSSIAN_CHARSET: fontEncoding = wxFONTENCODING_CP1251; break; case ARABIC_CHARSET: fontEncoding = wxFONTENCODING_CP1256; break; case GREEK_CHARSET: fontEncoding = wxFONTENCODING_CP1253; break; case HEBREW_CHARSET: fontEncoding = wxFONTENCODING_CP1255; break; case TURKISH_CHARSET: fontEncoding = wxFONTENCODING_CP1254; break; case THAI_CHARSET: fontEncoding = wxFONTENCODING_CP437; break; #endif case OEM_CHARSET: fontEncoding = wxFONTENCODING_CP437; break; } return wxFont(fontPoints, fontFamily, fontStyle, fontWeight, fontUnderline, fontFace, fontEncoding); } #endif // 0