From d8cde57b8367b4e853fbe45d88ee23cea4a301e9 Mon Sep 17 00:00:00 2001 From: David Webster Date: Mon, 3 Jan 2000 18:24:58 +0000 Subject: [PATCH] Two new font implementations for OS/2 git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5206 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/os2/fontenum.cpp | 214 +++++++++++++++++++++ src/os2/fontutil.cpp | 446 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 660 insertions(+) create mode 100644 src/os2/fontenum.cpp create mode 100644 src/os2/fontutil.cpp diff --git a/src/os2/fontenum.cpp b/src/os2/fontenum.cpp new file mode 100644 index 0000000000..b74beb0939 --- /dev/null +++ b/src/os2/fontenum.cpp @@ -0,0 +1,214 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: msw/fontenum.cpp +// Purpose: wxFontEnumerator class for Windows +// Author: Julian Smart +// Modified by: David Webster to add support for font encodings +// Created: 01/03/00 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifndef WX_PRECOMP + #include "wx/font.h" +#endif + +#include "wx/fontenum.h" +#include "wx/fontmap.h" + +#include "wx/os2/private.h" + +// ---------------------------------------------------------------------------- +// private classes +// ---------------------------------------------------------------------------- + +class wxFontEnumeratorHelper +{ +public: + wxFontEnumeratorHelper(wxFontEnumerator *fontEnum); + + // control what exactly are we enumerating + bool SetEncoding(wxFontEncoding encoding); + void SetFixedOnly(bool fixedOnly) + { m_fixedOnly = fixedOnly; } + + // call to start enumeration + void DoEnumerate(); + + // called by our font enumeration proc + bool OnFont(/*const LPLOGFONT lf, const LPTEXTMETRIC tm*/) const; + +private: + // the object we forward calls to OnFont() to + wxFontEnumerator *m_fontEnum; + + // if != -1, enum only fonts which have this encoding + int m_charset; + + // if not empty, enum only the fonts with this facename + wxString m_facename; + + // if TRUE, enum only fixed fonts + bool m_fixedOnly; +}; + +// ---------------------------------------------------------------------------- +// private functions +// ---------------------------------------------------------------------------- + +// TODO: +/* +int CALLBACK wxFontEnumeratorProc(LPLOGFONT lplf, LPTEXTMETRIC lptm, + DWORD dwStyle, LONG lParam); +*/ + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxFontEnumeratorHelper +// ---------------------------------------------------------------------------- + +wxFontEnumeratorHelper::wxFontEnumeratorHelper(wxFontEnumerator *fontEnum) +{ + m_fontEnum = fontEnum; + m_charset = -1; + m_fixedOnly = FALSE; +} + +bool wxFontEnumeratorHelper::SetEncoding(wxFontEncoding encoding) +{ + wxNativeEncodingInfo info; + if ( !wxGetNativeFontEncoding(encoding, &info) ) + { + if ( !wxTheFontMapper->GetAltForEncoding(encoding, &info) ) + { + // no such encodings at all + return FALSE; + } + } + m_charset = info.charset; + m_facename = info.facename; + + return TRUE; +} + +#define wxFONTENUMPROC FONTENUMPROC + +void wxFontEnumeratorHelper::DoEnumerate() +{ + // TODO: + /* + HDC hDC = ::GetDC(NULL); + +#ifdef __WIN32__ + LOGFONT lf; + lf.lfCharSet = m_charset; + wxStrncpy(lf.lfFaceName, m_facename, WXSIZEOF(lf.lfFaceName)); + lf.lfPitchAndFamily = 0; + ::EnumFontFamiliesEx(hDC, &lf, (wxFONTENUMPROC)wxFontEnumeratorProc, + (LPARAM)this, 0) ; +#else // Win16 + ::EnumFonts(hDC, (LPTSTR)NULL, (FONTENUMPROC)wxFontEnumeratorProc, + #ifdef STRICT + (LPARAM) + #else + (LPSTR) + #endif + this); +#endif // Win32/16 + + ::ReleaseDC(NULL, hDC); + */ +} + +bool wxFontEnumeratorHelper::OnFont(/*const LPLOGFONT lf, + const LPTEXTMETRIC tm */) const +{ + // TODO: + /* + if ( m_fixedOnly ) + { + // check that it's a fixed pitch font (there is *no* error here, the + // flag name is misleading!) + if ( tm->tmPitchAndFamily & TMPF_FIXED_PITCH ) + { + // not a fixed pitch font + return TRUE; + } + } + + if ( m_charset != -1 ) + { + // check that we have the right encoding + if ( lf->lfCharSet != m_charset ) + { + return TRUE; + } + } + + return m_fontEnum->OnFacename(lf->lfFaceName); + */ + return TRUE; +} + +// ---------------------------------------------------------------------------- +// wxFontEnumerator +// ---------------------------------------------------------------------------- + +bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding, + bool fixedWidthOnly) +{ + wxFontEnumeratorHelper fe(this); + if ( fe.SetEncoding(encoding) ) + { + fe.SetFixedOnly(fixedWidthOnly); + + fe.DoEnumerate(); + } + // else: no such fonts, unknown encoding + + return TRUE; +} + +bool wxFontEnumerator::EnumerateEncodings(const wxString& family) +{ + wxFAIL_MSG(wxT("TODO")); + + return TRUE; +} + +// ---------------------------------------------------------------------------- +// Windows callbacks +// ---------------------------------------------------------------------------- + +// TODO: +/* +int CALLBACK wxFontEnumeratorProc(LPLOGFONT lplf, LPTEXTMETRIC lptm, + DWORD dwStyle, LONG lParam) +{ + // Get rid of any fonts that we don't want... + if ( dwStyle != TRUETYPE_FONTTYPE ) + { + // continue enumeration + return TRUE; + } + + wxFontEnumeratorHelper *fontEnum = (wxFontEnumeratorHelper *)lParam; + + return fontEnum->OnFont(lplf, lptm); +} +*/ + diff --git a/src/os2/fontutil.cpp b/src/os2/fontutil.cpp new file mode 100644 index 0000000000..d36dbb08f5 --- /dev/null +++ b/src/os2/fontutil.cpp @@ -0,0 +1,446 @@ +/////////////////////////////////////////////////////////////////////////////// +// 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 +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// 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 +// facename[;charset] + +bool wxNativeEncodingInfo::FromString(const wxString& s) +{ + wxStringTokenizer tokenizer(s, _T(";")); + + 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(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) +{ + // 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 +