/////////////////////////////////////////////////////////////////////////////
-// Name: font.cpp
+// Name: src/os2/font.cpp
// Purpose: wxFont class
// Author: David Webster
// Modified by:
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
// ============================================================================
// declarations
// ============================================================================
// headers
// ----------------------------------------------------------------------------
-// For compilers that support precompilation, includes "wx.h".
-#include "wx/wxprec.h"
+#include "wx/font.h"
#ifndef WX_PRECOMP
#include <stdio.h>
- #include "wx/setup.h"
#include "wx/list.h"
#include "wx/utils.h"
#include "wx/app.h"
- #include "wx/font.h"
+ #include "wx/log.h"
#endif // WX_PRECOMP
#include "wx/os2/private.h"
-#if !USE_SHARED_LIBRARIES
- IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
+#include "wx/fontutil.h"
+#include "wx/fontmap.h"
+#include "wx/encinfo.h"
+
+#include "wx/tokenzr.h"
- #if wxUSE_PORTABLE_FONTS_IN_MSW
- IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
- #endif
-#endif
+#include <malloc.h>
+
+IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
// ----------------------------------------------------------------------------
// wxFontRefData - the internal description of the font
class WXDLLEXPORT wxFontRefData: public wxGDIRefData
{
-friend class WXDLLEXPORT wxFont;
-
public:
wxFontRefData()
{
- Init(12, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE,
- "", wxFONTENCODING_DEFAULT);
+ Init(-1, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false,
+ wxEmptyString, wxFONTENCODING_DEFAULT);
}
- wxFontRefData(const wxFontRefData& data)
+ wxFontRefData( int nSize
+ ,wxFontFamily nFamily
+ ,wxFontStyle nStyle
+ ,wxFontWeight nWeight
+ ,bool bUnderlined
+ ,const wxString& sFaceName
+ ,wxFontEncoding vEncoding
+ )
{
- Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
- data.m_underlined, data.m_faceName, data.m_encoding);
+ Init( nSize
+ ,nFamily
+ ,nStyle
+ ,nWeight
+ ,bUnderlined
+ ,sFaceName
+ ,vEncoding
+ );
+ }
- m_fontId = data.m_fontId;
+ wxFontRefData( const wxNativeFontInfo& rInfo
+ ,WXHFONT hFont = 0
+ ,WXHANDLE hPS = 0
+ )
+ {
+ Init( rInfo
+ ,hFont
+ ,hPS
+ );
}
- wxFontRefData(int size,
- int family,
- int style,
- int weight,
- bool underlined,
- const wxString& faceName,
- wxFontEncoding encoding)
+ wxFontRefData(const wxFontRefData& rData)
{
- Init(size, family, style, weight, underlined, faceName, encoding);
+ Init( rData.m_nPointSize
+ ,rData.m_nFamily
+ ,rData.m_nStyle
+ ,rData.m_nWeight
+ ,rData.m_bUnderlined
+ ,rData.m_sFaceName
+ ,rData.m_vEncoding
+ );
+ m_nFontId = rData.m_nFontId;
}
virtual ~wxFontRefData();
-protected:
- // common part of all ctors
- void Init(int size,
- int family,
- int style,
- int weight,
- bool underlined,
- const wxString& faceName,
- wxFontEncoding encoding);
-
- // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE
- // DELETED by destructor
- bool m_temporary;
+ //
+ // Operations
+ //
+ bool Alloc(wxFont* pFont);
+ void Free(void);
+
+ //
+ // All wxFont accessors
+ //
+ inline int GetPointSize(void) const
+ {
+ //
+ // We don't use the actual native font point size since it is
+ // the chosen physical font, which is usually only and approximation
+ // of the desired outline font. The actual displayable point size
+ // is the one stored in the refData
+ //
+ return m_nPointSize;
+ }
+
+ inline wxFontFamily GetFamily(void) const
+ {
+ return m_nFamily;
+ }
+
+ inline wxFontStyle GetStyle(void) const
+ {
+ return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetStyle()
+ : m_nStyle;
+ }
+
+ inline wxFontWeight GetWeight(void) const
+ {
+ return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetWeight()
+ : m_nWeight;
+ }
- int m_fontId;
+ inline bool GetUnderlined(void) const
+ {
+ return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetUnderlined()
+ : m_bUnderlined;
+ }
+
+ inline wxString GetFaceName(void) const
+ {
+ wxString sFaceName;
- // font characterstics
- int m_pointSize;
- int m_family;
- int m_style;
- int m_weight;
- bool m_underlined;
- wxString m_faceName;
- wxFontEncoding m_encoding;
+ if (m_bNativeFontInfoOk)
+ sFaceName = m_vNativeFontInfo.GetFaceName();
+ else
+ sFaceName = m_sFaceName;
- // Windows font handle
- WXHFONT m_hFont;
-};
+ return sFaceName;
+ }
+
+ inline wxFontEncoding GetEncoding(void) const
+ {
+ return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetEncoding()
+ : m_vEncoding;
+ }
+
+ inline WXHFONT GetHFONT(void) const { return m_hFont; }
+ inline HPS GetPS(void) const { return m_hPS; }
+ inline PFONTMETRICS GetFM(void) const { return m_pFM; }
+ inline int GetNumFonts(void) const { return m_nNumFonts; }
+
+ // ... and setters
+ inline void SetPointSize(int nPointSize)
+ {
+ if (m_bNativeFontInfoOk)
+ m_vNativeFontInfo.SetPointSize(nPointSize);
+ else
+ m_nPointSize = nPointSize;
+ }
+
+ inline void SetFamily(wxFontFamily nFamily)
+ {
+ m_nFamily = nFamily;
+ }
+
+ inline void SetStyle(wxFontStyle nStyle)
+ {
+ if (m_bNativeFontInfoOk)
+ m_vNativeFontInfo.SetStyle(nStyle);
+ else
+ m_nStyle = nStyle;
+ }
+
+ inline void SetWeight(wxFontWeight nWeight)
+ {
+ if (m_bNativeFontInfoOk)
+ m_vNativeFontInfo.SetWeight(nWeight);
+ else
+ m_nWeight = nWeight;
+ }
+
+ inline bool SetFaceName(const wxString& sFaceName)
+ {
+ if (m_bNativeFontInfoOk)
+ return m_vNativeFontInfo.SetFaceName(sFaceName);
+ else
+ m_sFaceName = sFaceName;
+ return true;
+ }
+
+ inline void SetUnderlined(bool bUnderlined)
+ {
+ if (m_bNativeFontInfoOk)
+ m_vNativeFontInfo.SetUnderlined(bUnderlined);
+ else
+ m_bUnderlined = bUnderlined;
+ }
+
+ inline void SetEncoding(wxFontEncoding vEncoding)
+ {
+ if (m_bNativeFontInfoOk)
+ m_vNativeFontInfo.SetEncoding(vEncoding);
+ else
+ m_vEncoding = vEncoding;
+ }
+
+ inline void SetPS(HPS hPS)
+ {
+ m_hPS = hPS;
+ }
+
+ inline void SetFM(PFONTMETRICS pFM)
+ {
+ m_pFM = pFM;
+ }
+
+ inline void SetNumFonts(int nNumFonts)
+ {
+ m_nNumFonts = nNumFonts;
+ }
+
+ //
+ // Native font info tests
+ //
+ bool HasNativeFontInfo() const { return m_bNativeFontInfoOk; }
+
+ const wxNativeFontInfo& GetNativeFontInfo() const
+ { return m_vNativeFontInfo; }
+
+protected:
+ //
+ // Common part of all ctors
+ //
+ void Init( int nSize
+ ,wxFontFamily nFamily
+ ,wxFontStyle nStyle
+ ,wxFontWeight nWeight
+ ,bool bUnderlined
+ ,const wxString& rsFaceName
+ ,wxFontEncoding vEncoding
+ );
+
+ void Init( const wxNativeFontInfo& rInfo
+ ,WXHFONT hFont = 0
+ ,WXHANDLE hPS = 0
+ );
+ //
+ // If true, the pointer to the actual font is temporary and SHOULD NOT BE
+ // DELETED by destructor
+ //
+ bool m_bTemporary;
+ int m_nFontId;
+
+ //
+ // Font characterstics
+ //
+ int m_nPointSize;
+ wxFontFamily m_nFamily;
+ wxFontStyle m_nStyle;
+ wxFontWeight m_nWeight;
+ bool m_bUnderlined;
+ wxString m_sFaceName;
+ wxFontEncoding m_vEncoding;
+ WXHFONT m_hFont;
+
+ //
+ // Native font info
+ //
+ wxNativeFontInfo m_vNativeFontInfo;
+ bool m_bNativeFontInfoOk;
+
+ //
+ // Some PM specific stuff
+ //
+ PFONTMETRICS m_pFM; // array of FONTMETRICS structs
+ int m_nNumFonts; // number of fonts in array
+ HPS m_hPS; // PS handle this font belongs to
+ FATTRS m_vFattrs; // Current fattrs struct
+ FACENAMEDESC m_vFname; // Current facename struct
+ bool m_bInternalPS; // Internally generated PS?
+}; // end of CLASS wxFontRefData
+
+#define M_FONTDATA ((wxFontRefData*)m_refData)
// ============================================================================
// implementation
// wxFontRefData
// ----------------------------------------------------------------------------
-void wxFontRefData::Init(int pointSize,
- int family,
- int style,
- int weight,
- bool underlined,
- const wxString& faceName,
- wxFontEncoding encoding)
-{
- m_style = style;
- m_pointSize = pointSize;
- m_family = family;
- m_style = style;
- m_weight = weight;
- m_underlined = underlined;
- m_faceName = faceName;
- m_encoding = encoding;
-
- m_fontId = 0;
- m_temporary = FALSE;
-
- m_hFont = 0;
-}
-
-wxFontRefData::~wxFontRefData()
+void wxFontRefData::Init(
+ int nPointSize
+, wxFontFamily nFamily
+, wxFontStyle nStyle
+, wxFontWeight nWeight
+, bool bUnderlined
+, const wxString& rsFaceName
+, wxFontEncoding vEncoding
+)
{
-// TODO:
-// if ( m_hFont )
-// {
-// if ( !::DeleteObject((HFONT) m_hFont) )
-// {
-// wxLogLastError("DeleteObject(font)");
-// }
-// }
-}
-
-// ----------------------------------------------------------------------------
-// wxFont
-// ----------------------------------------------------------------------------
-
-void wxFont::Init()
+ m_nStyle = nStyle;
+ m_nPointSize = nPointSize;
+ m_nFamily = nFamily;
+ m_nStyle = nStyle;
+ m_nWeight = nWeight;
+ m_bUnderlined = bUnderlined;
+ m_sFaceName = rsFaceName;
+ m_vEncoding = vEncoding;
+ m_hFont = 0;
+
+ m_bNativeFontInfoOk = false;
+
+ m_nFontId = 0;
+ m_bTemporary = false;
+ m_pFM = (PFONTMETRICS)NULL;
+ m_hPS = NULLHANDLE;
+ m_nNumFonts = 0;
+} // end of wxFontRefData::Init
+
+void wxFontRefData::Init(
+ const wxNativeFontInfo& rInfo
+, WXHFONT hFont //this is the FontId -- functions as the hFont for OS/2
+, WXHANDLE hPS // Presentation Space we are using
+)
{
- if ( wxTheFontList )
- wxTheFontList->Append(this);
-}
-
-/* Constructor for a font. Note that the real construction is done
- * in wxDC::SetFont, when information is available about scaling etc.
- */
-bool wxFont::Create(int pointSize,
- int family,
- int style,
- int weight,
- bool underlined,
- const wxString& faceName,
- wxFontEncoding encoding)
-{
- UnRef();
- m_refData = new wxFontRefData(pointSize, family, style, weight,
- underlined, faceName, encoding);
-
- RealizeResource();
+ //
+ // hFont may be zero, or it be passed in case we really want to
+ // use the exact font created in the underlying system
+ // (for example where we can't guarantee conversion from HFONT
+ // to LOGFONT back to HFONT)
+ //
+ m_hFont = hFont;
+ m_nFontId = (int)hFont;
+
+ m_bNativeFontInfoOk = true;
+ m_vNativeFontInfo = rInfo;
+
+ if (hPS == NULLHANDLE)
+ {
+ m_hPS = ::WinGetPS(HWND_DESKTOP);
+ m_bInternalPS = true;
+ }
+ else
+ m_hPS = (HPS)hPS;
- return TRUE;
-}
+ m_nFontId = 0;
+ m_bTemporary = false;
+ m_pFM = (PFONTMETRICS)NULL;
+ m_nNumFonts = 0;
+} // end of wxFontRefData::Init
-wxFont::~wxFont()
+wxFontRefData::~wxFontRefData()
{
- if ( wxTheFontList )
- wxTheFontList->DeleteObject(this);
+ Free();
}
-// ----------------------------------------------------------------------------
-// real implementation
-// ----------------------------------------------------------------------------
-
-bool wxFont::RealizeResource()
+bool wxFontRefData::Alloc( wxFont* pFont )
{
- if ( GetResourceHandle() )
- {
- // VZ: the old code returned FALSE in this case, but it doesn't seem
- // to make sense because the font _was_ created
- wxLogDebug(T("Calling wxFont::RealizeResource() twice"));
+ wxString sFaceName;
+ long flId = m_hFont;
+ long lRc;
+ ERRORID vError;
+ wxString sError;
- return TRUE;
+ if (!m_bNativeFontInfoOk)
+ {
+ wxFillLogFont( &m_vNativeFontInfo.fa
+ ,&m_vNativeFontInfo.fn
+ ,&m_hPS
+ ,&m_bInternalPS
+ ,&flId
+ ,sFaceName
+ ,pFont
+ );
+ m_bNativeFontInfoOk = true;
+ }
+ else
+ {
+ if (flId == 0L)
+ flId = 1L;
+ else
+ flId++;
+ if (flId > 254)
+ flId = 1L;
+ }
+ if((lRc = ::GpiCreateLogFont( m_hPS
+ ,NULL
+ ,flId
+ ,&m_vNativeFontInfo.fa
+ )) != GPI_ERROR)
+ {
+ m_hFont = (WXHFONT)flId;
+ m_nFontId = flId;
+ }
+ if (!m_hFont)
+ {
+ vError = ::WinGetLastError(vHabmain);
+ sError = wxPMErrorToStr(vError);
+ wxLogLastError(wxT("CreateFont"));
}
- int ff_family = 0;
- wxString ff_face;
-
-// OS/2 combines the family with styles to give a facename
+ ::GpiSetCharSet(m_hPS, flId); // sets font for presentation space
+ ::GpiQueryFontMetrics(m_hPS, sizeof(FONTMETRICS), &m_vNativeFontInfo.fm);
+
+ //
+ // Set refData members with the results
+ //
+ memcpy(&m_vFattrs, &m_vNativeFontInfo.fa, sizeof(m_vFattrs));
+ memcpy(&m_vFname, &m_vNativeFontInfo.fn, sizeof(m_vFname));
+ //
+ // Going to leave the point size alone. Mostly we use outline fonts
+ // that can be set to any point size inside of Presentation Parameters,
+ // regardless of whether or not the actual font is registered in the system.
+ // The GpiCreateLogFont will do enough by selecting the right family,
+ // and face name.
+ //
+ if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman") == 0)
+ m_nFamily = wxFONTFAMILY_ROMAN;
+ else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman MT 30") == 0)
+ m_nFamily = wxFONTFAMILY_ROMAN;
+ else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "@Times New Roman MT 30") == 0)
+ m_nFamily = wxFONTFAMILY_ROMAN;
+ else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Tms Rmn") == 0)
+ m_nFamily = wxFONTFAMILY_ROMAN;
+ else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "WarpSans") == 0)
+ m_nFamily = wxFONTFAMILY_DECORATIVE;
+ else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helvetica") == 0)
+ m_nFamily = wxFONTFAMILY_SWISS;
+ else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helv") == 0)
+ m_nFamily = wxFONTFAMILY_SWISS;
+ else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Script") == 0)
+ m_nFamily = wxFONTFAMILY_SCRIPT;
+ else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier New") == 0)
+ m_nFamily = wxFONTFAMILY_TELETYPE;
+ else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier") == 0)
+ m_nFamily = wxFONTFAMILY_TELETYPE;
+ else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Monospaced") == 0)
+ m_nFamily = wxFONTFAMILY_TELETYPE;
+ else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System VIO") == 0)
+ m_nFamily = wxFONTFAMILY_MODERN;
+ else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Proportional") == 0)
+ m_nFamily = wxFONTFAMILY_MODERN;
+ else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Arial") == 0)
+ m_nFamily = wxFONTFAMILY_SWISS;
+ else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Swiss") == 0)
+ m_nFamily = wxFONTFAMILY_SWISS;
+ else
+ m_nFamily = wxFONTFAMILY_SWISS;
- switch ( M_FONTDATA->m_family )
+ if (m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_ITALIC)
+ m_nStyle = wxFONTSTYLE_ITALIC;
+ else
+ m_nStyle = wxFONTSTYLE_NORMAL;
+ switch(m_vNativeFontInfo.fn.usWeightClass)
{
- case wxSCRIPT:
-// ff_family = FF_SCRIPT ;
- ff_face = T("Script") ;
- break ;
+ case FWEIGHT_DONT_CARE:
+ m_nWeight = wxFONTWEIGHT_NORMAL;
+ break;
- case wxDECORATIVE:
-// ff_family = FF_DECORATIVE;
+ case FWEIGHT_NORMAL:
+ m_nWeight = wxFONTWEIGHT_NORMAL;
break;
- case wxROMAN:
-// ff_family = FF_ROMAN;
- ff_face = T("Times New Roman") ;
+ case FWEIGHT_LIGHT:
+ m_nWeight = wxFONTWEIGHT_LIGHT;
break;
- case wxTELETYPE:
- case wxMODERN:
-// ff_family = FF_MODERN;
- ff_face = T("Courier New") ;
+ case FWEIGHT_BOLD:
+ m_nWeight = wxFONTWEIGHT_BOLD;
break;
- case wxSWISS:
-// ff_family = FF_SWISS;
- ff_face = T("Arial") ;
+ case FWEIGHT_ULTRA_BOLD:
+ m_nWeight = wxFONTWEIGHT_MAX;
break;
- case wxDEFAULT:
default:
-// ff_family = FF_SWISS;
- ff_face = T("Arial") ;
+ m_nWeight = wxFONTWEIGHT_NORMAL;
}
-
- BYTE ff_italic;
- switch ( M_FONTDATA->m_style )
+ m_bUnderlined = ((m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0);
+ m_sFaceName = (wxChar*)m_vNativeFontInfo.fa.szFacename;
+ m_vEncoding = wxGetFontEncFromCharSet(m_vNativeFontInfo.fa.usCodePage);
+
+ //
+ // We don't actuall keep the font around if using a temporary PS
+ //
+ if (m_bInternalPS)
{
- case wxITALIC:
- case wxSLANT:
- ff_italic = 1;
- break;
+ if(m_hFont)
+ ::GpiDeleteSetId( m_hPS
+ ,flId
+ );
- default:
- wxFAIL_MSG(T("unknown font slant"));
- // fall through
-
- case wxNORMAL:
- ff_italic = 0;
+ ::WinReleasePS(m_hPS);
}
+ else
+ //
+ // Select the font into the Presentation space
+ //
+ ::GpiSetCharSet(m_hPS, flId); // sets font for presentation space
+ return true;
+} // end of wxFontRefData::Alloc
+
+void wxFontRefData::Free()
+{
+ if (m_pFM)
+ delete [] m_pFM;
+ m_pFM = (PFONTMETRICS)NULL;
- int ff_weight = 0;
- switch ( M_FONTDATA->m_weight )
+ if ( m_hFont )
{
- default:
- wxFAIL_MSG(T("unknown font weight"));
- // fall through
+ ::GpiDeleteSetId(m_hPS, 1L); /* delete the logical font */
+ m_nFontId = 0;
+ m_hFont = 0;
+ }
+ if (m_bInternalPS)
+ ::WinReleasePS(m_hPS);
+ m_hPS = NULLHANDLE;
+} // end of wxFontRefData::Free
- case wxNORMAL:
-// ff_weight = FW_NORMAL;
- break;
+// ----------------------------------------------------------------------------
+// wxNativeFontInfo
+// ----------------------------------------------------------------------------
- case wxLIGHT:
-// ff_weight = FW_LIGHT;
- break;
+void wxNativeFontInfo::Init()
+{
+ memset(&fa, '\0', sizeof(FATTRS));
+} // end of wxNativeFontInfo::Init
- case wxBOLD:
-// ff_weight = FW_BOLD;
- break;
- }
+int wxNativeFontInfo::GetPointSize() const
+{
+ return fm.lEmHeight;
+} // end of wxNativeFontInfo::GetPointSize
- const wxChar* pzFace;
- if ( M_FONTDATA->m_faceName.IsEmpty() )
- pzFace = ff_face;
- else
- pzFace = M_FONTDATA->m_faceName ;
+wxFontStyle wxNativeFontInfo::GetStyle() const
+{
+ return fa.fsSelection & FATTR_SEL_ITALIC ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
+} // end of wxNativeFontInfo::GetStyle
-#if 0
- /* Always calculate fonts using the screen DC (is this the best strategy?)
- * There may be confusion if a font is selected into a printer
- * DC (say), because the height will be calculated very differently.
- */
- // What sort of display is it?
- int technology = ::GetDeviceCaps(dc, TECHNOLOGY);
+wxFontWeight wxNativeFontInfo::GetWeight() const
+{
+ switch(fn.usWeightClass)
+ {
+ case FWEIGHT_DONT_CARE:
+ return wxFONTWEIGHT_NORMAL;
- int nHeight;
+ case FWEIGHT_NORMAL:
+ return wxFONTWEIGHT_NORMAL;
- if (technology != DT_RASDISPLAY && technology != DT_RASPRINTER)
- {
- // Have to get screen DC Caps, because a metafile will return 0.
- HDC dc2 = ::GetDC(NULL);
- nHeight = M_FONTDATA->m_pointSize*GetDeviceCaps(dc2, LOGPIXELSY)/72;
- ::ReleaseDC(NULL, dc2);
- }
- else
- {
- nHeight = M_FONTDATA->m_pointSize*GetDeviceCaps(dc, LOGPIXELSY)/72;
+ case FWEIGHT_LIGHT:
+ return wxFONTWEIGHT_LIGHT;
+
+ case FWEIGHT_BOLD:
+ return wxFONTWEIGHT_BOLD;
+
+ case FWEIGHT_ULTRA_BOLD:
+ return wxFONTWEIGHT_MAX;
}
-#endif // 0
+ return wxFONTWEIGHT_NORMAL;
+} // end of wxNativeFontInfo::GetWeight
-#if 0
- // Have to get screen DC Caps, because a metafile will return 0.
- HDC dc2 = ::GetDC(NULL);
- ppInch = ::GetDeviceCaps(dc2, LOGPIXELSY);
- ::ReleaseDC(NULL, dc2);
-#endif // 0
+bool wxNativeFontInfo::GetUnderlined() const
+{
+ return ((fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0);
+} // end of wxNativeFontInfo::GetUnderlined
- // 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;
+wxString wxNativeFontInfo::GetFaceName() const
+{
+ return (wxChar*)fm.szFacename;
+} // end of wxNativeFontInfo::GetFaceName
-#if wxFONT_SIZE_COMPATIBILITY
- // Incorrect, but compatible with old wxWindows behaviour
- int nHeight = (M_FONTDATA->m_pointSize*ppInch/72);
-#else
- // Correct for Windows compatibility
- int nHeight = - (M_FONTDATA->m_pointSize*ppInch/72);
-#endif
+wxFontFamily wxNativeFontInfo::GetFamily() const
+{
+ int nFamily;
+
+ //
+ // Extract family from facename
+ //
+ if (strcmp(fm.szFamilyname, "Times New Roman") == 0)
+ nFamily = wxFONTFAMILY_ROMAN;
+ else if (strcmp(fm.szFamilyname, "Times New Roman MT 30") == 0)
+ nFamily = wxFONTFAMILY_ROMAN;
+ else if (strcmp(fm.szFamilyname, "@Times New Roman MT 30") == 0)
+ nFamily = wxFONTFAMILY_ROMAN;
+ else if (strcmp(fm.szFamilyname, "Tms Rmn") == 0)
+ nFamily = wxFONTFAMILY_ROMAN;
+ else if (strcmp(fm.szFamilyname, "WarpSans") == 0)
+ nFamily = wxFONTFAMILY_DECORATIVE;
+ else if (strcmp(fm.szFamilyname, "Helvetica") == 0)
+ nFamily = wxFONTFAMILY_SWISS;
+ else if (strcmp(fm.szFamilyname, "Helv") == 0)
+ nFamily = wxFONTFAMILY_SWISS;
+ else if (strcmp(fm.szFamilyname, "Script") == 0)
+ nFamily = wxFONTFAMILY_SCRIPT;
+ else if (strcmp(fm.szFamilyname, "Courier New") == 0)
+ nFamily = wxFONTFAMILY_TELETYPE;
+ else if (strcmp(fm.szFamilyname, "Courier") == 0)
+ nFamily = wxFONTFAMILY_TELETYPE;
+ else if (strcmp(fm.szFamilyname, "System Monospaced") == 0)
+ nFamily = wxFONTFAMILY_TELETYPE;
+ else if (strcmp(fm.szFamilyname, "System VIO") == 0)
+ nFamily = wxFONTFAMILY_MODERN;
+ else if (strcmp(fm.szFamilyname, "System Proportional") == 0)
+ nFamily = wxFONTFAMILY_MODERN;
+ else if (strcmp(fm.szFamilyname, "Arial") == 0)
+ nFamily = wxFONTFAMILY_SWISS;
+ else if (strcmp(fm.szFamilyname, "Swiss") == 0)
+ nFamily = wxFONTFAMILY_SWISS;
+ else
+ nFamily = wxFONTFAMILY_SWISS;
+ return (wxFontFamily)nFamily;
+} // end of wxNativeFontInfo::GetFamily
- BYTE ff_underline = M_FONTDATA->m_underlined;
+wxFontEncoding wxNativeFontInfo::GetEncoding() const
+{
+ return wxGetFontEncFromCharSet(fa.usCodePage);
+} // end of wxNativeFontInfo::GetEncoding
- wxFontEncoding encoding = M_FONTDATA->m_encoding;
- if ( encoding == wxFONTENCODING_DEFAULT )
+void wxNativeFontInfo::SetPointSize(
+ int nPointsize
+)
+{
+ fm.lEmHeight = (LONG)nPointsize;
+} // end of wxNativeFontInfo::SetPointSize
+
+void wxNativeFontInfo::SetStyle(
+ wxFontStyle eStyle
+)
+{
+ switch (eStyle)
{
- encoding = wxFont::GetDefaultEncoding();
+ default:
+ wxFAIL_MSG( wxT("unknown font style") );
+ // fall through
+
+ case wxFONTSTYLE_NORMAL:
+ break;
+
+ case wxFONTSTYLE_ITALIC:
+ case wxFONTSTYLE_SLANT:
+ fa.fsSelection |= FATTR_SEL_ITALIC;
+ break;
}
+} // end of wxNativeFontInfo::SetStyle
- DWORD charset;
- switch ( encoding )
+void wxNativeFontInfo::SetWeight(
+ wxFontWeight eWeight
+)
+{
+ switch (eWeight)
{
- case wxFONTENCODING_ISO8859_1:
- case wxFONTENCODING_ISO8859_15:
- case wxFONTENCODING_CP1250:
-// charset = ANSI_CHARSET;
- break;
+ default:
+ wxFAIL_MSG( wxT("unknown font weight") );
+ // fall through
- case wxFONTENCODING_ISO8859_2:
- case wxFONTENCODING_CP1252:
-// charset = EASTEUROPE_CHARSET;
+ case wxFONTWEIGHT_NORMAL:
+ fn.usWeightClass = FWEIGHT_NORMAL;
break;
- case wxFONTENCODING_ISO8859_4:
- case wxFONTENCODING_ISO8859_10:
-// charset = BALTIC_CHARSET;
+ case wxFONTWEIGHT_LIGHT:
+ fn.usWeightClass = FWEIGHT_LIGHT;
break;
- case wxFONTENCODING_ISO8859_5:
- case wxFONTENCODING_CP1251:
-// charset = RUSSIAN_CHARSET;
+ case wxFONTWEIGHT_BOLD:
+ fn.usWeightClass = FWEIGHT_BOLD;
break;
+ }
+} // end of wxNativeFontInfo::SetWeight
+
+void wxNativeFontInfo::SetUnderlined(
+ bool bUnderlined
+)
+{
+ if(bUnderlined)
+ fa.fsSelection |= FATTR_SEL_UNDERSCORE;
+} // end of wxNativeFontInfo::SetUnderlined
+
+bool wxNativeFontInfo::SetFaceName(
+ const wxString& sFacename
+)
+{
+ wxStrlcpy((wxChar*)fa.szFacename, sFacename, WXSIZEOF(fa.szFacename));
+ return true;
+} // end of wxNativeFontInfo::SetFaceName
+
+void wxNativeFontInfo::SetFamily(
+ wxFontFamily eFamily
+)
+{
+ wxString sFacename;
- case wxFONTENCODING_ISO8859_6:
-// charset = ARABIC_CHARSET;
+ switch (eFamily)
+ {
+ case wxFONTFAMILY_SCRIPT:
+ sFacename = wxT("Tms Rmn");
break;
- case wxFONTENCODING_ISO8859_7:
-// charset = GREEK_CHARSET;
+ case wxFONTFAMILY_DECORATIVE:
+ sFacename = wxT("WarpSans");
break;
- case wxFONTENCODING_ISO8859_8:
-// charset = HEBREW_CHARSET;
+ case wxFONTFAMILY_ROMAN:
+ sFacename = wxT("Tms Rmn");
break;
- case wxFONTENCODING_ISO8859_9:
-// charset = TURKISH_CHARSET;
+ case wxFONTFAMILY_TELETYPE:
+ sFacename = wxT("Courier") ;
break;
- case wxFONTENCODING_ISO8859_11:
-// charset = THAI_CHARSET;
+ case wxFONTFAMILY_MODERN:
+ sFacename = wxT("System VIO") ;
break;
- case wxFONTENCODING_CP437:
-// charset = OEM_CHARSET;
+ case wxFONTFAMILY_SWISS:
+ sFacename = wxT("Helv") ;
break;
+ case wxFONTFAMILY_DEFAULT:
default:
- wxFAIL_MSG(T("unsupported encoding"));
- // fall through
-
- case wxFONTENCODING_SYSTEM:
-// charset = ANSI_CHARSET;
- break;
+ sFacename = wxT("System VIO") ;
}
-// TODO:
-WXHFONT hFont;
-// HFONT hFont = ::CreateFont
-// (
-// nHeight, // height
-// 0, // width (choose best)
-// 0, // escapement
-// 0, // orientation
-// ff_weight, // weight
-// ff_italic, // italic?
-// ff_underline, // underlined?
-// 0, // strikeout?
-// charset, // charset
-// OUT_DEFAULT_PRECIS, // precision
-// CLIP_DEFAULT_PRECIS, // clip precision
-// PROOF_QUALITY, // quality of match
-// DEFAULT_PITCH | // fixed or variable
-// ff_family, // family id
-// pzFace // face name
-// );
-
- M_FONTDATA->m_hFont = (WXHFONT)hFont;
- if ( !hFont )
- {
- wxLogLastError("CreateFont");
- }
-
- return hFont != 0;
-}
+ if (!wxStrlen((wxChar*)fa.szFacename) )
+ {
+ SetFaceName(sFacename);
+ }
+} // end of wxNativeFontInfo::SetFamily
-bool wxFont::FreeResource(bool force)
+void wxNativeFontInfo::SetEncoding( wxFontEncoding eEncoding )
{
- if ( GetResourceHandle() )
+ wxNativeEncodingInfo vInfo;
+
+ if ( !wxGetNativeFontEncoding( eEncoding
+ ,&vInfo
+ ))
{
-// TODO:
-// if ( !::DeleteObject((HFONT) M_FONTDATA->m_hFont) )
-// {
-// wxLogLastError("DeleteObject(font)");
-// }
+ if (wxFontMapper::Get()->GetAltForEncoding( eEncoding
+ ,&vInfo
+ ))
+ {
+ if (!vInfo.facename.empty())
+ {
+ //
+ // If we have this encoding only in some particular facename, use
+ // the facename - it is better to show the correct characters in a
+ // wrong facename than unreadable text in a correct one
+ //
+ SetFaceName(vInfo.facename);
+ }
+ }
+ else
+ {
+ // unsupported encoding, replace with the default
+ vInfo.charset = 850;
+ }
+ }
+ fa.usCodePage = (USHORT)vInfo.charset;
+} // end of wxNativeFontInfo::SetFaceName
- M_FONTDATA->m_hFont = 0;
+bool wxNativeFontInfo::FromString( const wxString& rsStr )
+{
+ long lVal;
+
+ wxStringTokenizer vTokenizer(rsStr, wxT(";"));
+
+ //
+ // First the version
+ //
+ wxString sToken = vTokenizer.GetNextToken();
+
+ if (sToken != wxT('0'))
+ return false;
+
+ sToken = vTokenizer.GetNextToken();
+ if (!sToken.ToLong(&lVal))
+ return false;
+ fm.lEmHeight = lVal;
+
+ sToken = vTokenizer.GetNextToken();
+ if (!sToken.ToLong(&lVal))
+ return false;
+ fa.lAveCharWidth = lVal;
+
+ sToken = vTokenizer.GetNextToken();
+ if (!sToken.ToLong(&lVal))
+ return false;
+ fa.fsSelection = (USHORT)lVal;
+
+ sToken = vTokenizer.GetNextToken();
+ if (!sToken.ToLong(&lVal))
+ return false;
+ fa.fsType = (USHORT)lVal;
+
+ sToken = vTokenizer.GetNextToken();
+ if (!sToken.ToLong(&lVal))
+ return false;
+ fa.fsFontUse = (USHORT)lVal;
+
+ sToken = vTokenizer.GetNextToken();
+ if (!sToken.ToLong(&lVal))
+ return false;
+ fa.idRegistry = (USHORT)lVal;
+
+ sToken = vTokenizer.GetNextToken();
+ if (!sToken.ToLong(&lVal))
+ return false;
+ fa.usCodePage = (USHORT)lVal;
+
+ sToken = vTokenizer.GetNextToken();
+ if (!sToken.ToLong(&lVal))
+ return false;
+ fa.lMatch = lVal;
+
+ sToken = vTokenizer.GetNextToken();
+ if (!sToken.ToLong(&lVal))
+ return false;
+ fn.usWeightClass = (USHORT)lVal;
+
+ sToken = vTokenizer.GetNextToken();
+ if(!sToken)
+ return false;
+ wxStrcpy((wxChar*)fa.szFacename, sToken.c_str());
+ return true;
+} // end of wxNativeFontInfo::FromString
+
+wxString wxNativeFontInfo::ToString() const
+{
+ wxString sStr;
+
+ sStr.Printf(wxT("%d;%ld;%ld;%ld;%d;%d;%d;%d;%d;%ld;%d;%s"),
+ 0, // version, in case we want to change the format later
+ fm.lEmHeight,
+ fa.lAveCharWidth,
+ fa.lMaxBaselineExt,
+ fa.fsSelection,
+ fa.fsType,
+ fa.fsFontUse,
+ fa.idRegistry,
+ fa.usCodePage,
+ fa.lMatch,
+ fn.usWeightClass,
+ (char *)fa.szFacename);
+ return sStr;
+} // end of wxNativeFontInfo::ToString
+
+// ----------------------------------------------------------------------------
+// wxFont
+// ----------------------------------------------------------------------------
+
+bool wxFont::Create( const wxNativeFontInfo& rInfo,
+ WXHFONT hFont )
+{
+ UnRef();
+ m_refData = new wxFontRefData( rInfo
+ ,hFont
+ );
+ RealizeResource();
+ return true;
+} // end of wxFont::Create
+
+wxFont::wxFont(
+ const wxString& rsFontdesc
+)
+{
+ wxNativeFontInfo vInfo;
+
+ if (vInfo.FromString(rsFontdesc))
+ (void)Create(vInfo);
+} // end of wxFont::wxFont
+
+// ----------------------------------------------------------------------------
+// Constructor for a font. Note that the real construction is done
+// in wxDC::SetFont, when information is available about scaling etc.
+// ----------------------------------------------------------------------------
+bool wxFont::Create( int nPointSize,
+ wxFontFamily nFamily,
+ wxFontStyle nStyle,
+ wxFontWeight nWeight,
+ bool bUnderlined,
+ const wxString& rsFaceName,
+ wxFontEncoding vEncoding )
+{
+ UnRef();
- return TRUE;
+ //
+ // wxDEFAULT is a valid value for the font size too so we must treat it
+ // specially here (otherwise the size would be 70 == wxDEFAULT value)
+ //
+ if (nPointSize == wxDEFAULT)
+ {
+ nPointSize = wxNORMAL_FONT->GetPointSize();
}
- return FALSE;
-}
+ m_refData = new wxFontRefData( nPointSize
+ ,nFamily
+ ,nStyle
+ ,nWeight
+ ,bUnderlined
+ ,rsFaceName
+ ,vEncoding
+ );
+ RealizeResource();
+ return true;
+} // end of wxFont::Create
-WXHANDLE wxFont::GetResourceHandle()
+wxFont::~wxFont()
{
- if ( !M_FONTDATA )
- return 0;
- else
- return (WXHANDLE)M_FONTDATA->m_hFont ;
+} // end of wxFont::~wxFont
+
+// ----------------------------------------------------------------------------
+// real implementation
+// Boris' Kovalenko comments:
+// Because OS/2 fonts are associated with PS we can not create the font
+// here, but we may check that font definition is true
+// ----------------------------------------------------------------------------
+
+wxGDIRefData *wxFont::CreateGDIRefData() const
+{
+ return new wxFontRefData();
}
-bool wxFont::IsFree() const
+wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
{
- return (M_FONTDATA && (M_FONTDATA->m_hFont == 0));
+ return new wxFontRefData(*static_cast<const wxFontRefData *>(data));
}
-void wxFont::Unshare()
+bool wxFont::RealizeResource()
{
- // Don't change shared data
- if ( !m_refData )
+ if ( GetResourceHandle() )
{
- m_refData = new wxFontRefData();
+ return true;
}
- else
+ return M_FONTDATA->Alloc(this);
+} // end of wxFont::RealizeResource
+
+bool wxFont::FreeResource( bool WXUNUSED(bForce) )
+{
+ if (GetResourceHandle())
{
- wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
- UnRef();
- m_refData = ref;
+ M_FONTDATA->Free();
+ return true;
}
-}
+ return false;
+} // end of wxFont::FreeResource
+
+WXHANDLE wxFont::GetResourceHandle() const
+{
+ return GetHFONT();
+} // end of wxFont::GetResourceHandle
+
+WXHFONT wxFont::GetHFONT() const
+{
+ return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
+} // end of wxFont::GetHFONT
+
+bool wxFont::IsFree() const
+{
+ return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0);
+} // end of wxFont::IsFree
// ----------------------------------------------------------------------------
// change font attribute: we recreate font when doing it
// ----------------------------------------------------------------------------
-void wxFont::SetPointSize(int pointSize)
+void wxFont::SetPointSize(
+ int nPointSize
+)
{
- Unshare();
+ AllocExclusive();
- M_FONTDATA->m_pointSize = pointSize;
+ M_FONTDATA->SetPointSize(nPointSize);
RealizeResource();
-}
+} // end of wxFont::SetPointSize
-void wxFont::SetFamily(int family)
+void wxFont::SetFamily(
+ wxFontFamily nFamily
+)
{
- Unshare();
+ AllocExclusive();
- M_FONTDATA->m_family = family;
+ M_FONTDATA->SetFamily(nFamily);
RealizeResource();
-}
+} // end of wxFont::SetFamily
-void wxFont::SetStyle(int style)
+void wxFont::SetStyle(
+ wxFontStyle nStyle
+)
{
- Unshare();
+ AllocExclusive();
- M_FONTDATA->m_style = style;
+ M_FONTDATA->SetStyle(nStyle);
RealizeResource();
-}
+} // end of wxFont::SetStyle
-void wxFont::SetWeight(int weight)
+void wxFont::SetWeight(
+ wxFontWeight nWeight
+)
{
- Unshare();
+ AllocExclusive();
- M_FONTDATA->m_weight = weight;
+ M_FONTDATA->SetWeight(nWeight);
RealizeResource();
-}
+} // end of wxFont::SetWeight
-void wxFont::SetFaceName(const wxString& faceName)
+bool wxFont::SetFaceName(
+ const wxString& rsFaceName
+)
{
- Unshare();
+ AllocExclusive();
- M_FONTDATA->m_faceName = faceName;
+ bool refdataok = M_FONTDATA->SetFaceName(rsFaceName);
RealizeResource();
-}
-void wxFont::SetUnderlined(bool underlined)
+ return refdataok && wxFontBase::SetFaceName(rsFaceName);
+} // end of wxFont::SetFaceName
+
+void wxFont::SetUnderlined(
+ bool bUnderlined
+)
{
- Unshare();
+ AllocExclusive();
- M_FONTDATA->m_underlined = underlined;
+ M_FONTDATA->SetUnderlined(bUnderlined);
RealizeResource();
-}
+} // end of wxFont::SetUnderlined
+
+void wxFont::SetEncoding(
+ wxFontEncoding vEncoding
+)
+{
+ AllocExclusive();
+
+ M_FONTDATA->SetEncoding(vEncoding);
+
+ RealizeResource();
+} // end of wxFont::SetEncoding
-void wxFont::SetEncoding(wxFontEncoding encoding)
+void wxFont::DoSetNativeFontInfo(
+ const wxNativeFontInfo& rInfo
+)
{
- Unshare();
+ AllocExclusive();
- M_FONTDATA->m_encoding = encoding;
+ FreeResource();
+
+ *M_FONTDATA = wxFontRefData(rInfo);
RealizeResource();
}
int wxFont::GetPointSize() const
{
- return M_FONTDATA->m_pointSize;
-}
+ wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
-int wxFont::GetFamily() const
-{
- return M_FONTDATA->m_family;
-}
+ return M_FONTDATA->GetPointSize();
+} // end of wxFont::GetPointSize
-int wxFont::GetFontId() const
+wxFontFamily wxFont::GetFamily() const
{
- return M_FONTDATA->m_fontId;
-}
+ wxCHECK_MSG( Ok(), wxFONTFAMILY_MAX, wxT("invalid font") );
+
+ return M_FONTDATA->GetFamily();
+} // end of wxFont::GetFamily
-int wxFont::GetStyle() const
+wxFontStyle wxFont::GetStyle() const
{
- return M_FONTDATA->m_style;
-}
+ wxCHECK_MSG( Ok(), wxFONTSTYLE_MAX, wxT("invalid font") );
+
+ return M_FONTDATA->GetStyle();
+} // end of wxFont::GetStyle
-int wxFont::GetWeight() const
+wxFontWeight wxFont::GetWeight() const
{
- return M_FONTDATA->m_weight;
+ wxCHECK_MSG( Ok(), wxFONTWEIGHT_MAX, wxT("invalid font") );
+
+ return M_FONTDATA->GetWeight();
}
bool wxFont::GetUnderlined() const
{
- return M_FONTDATA->m_underlined;
-}
+ wxCHECK_MSG( Ok(), false, wxT("invalid font") );
+
+ return M_FONTDATA->GetUnderlined();
+} // end of wxFont::GetUnderlined
wxString wxFont::GetFaceName() const
{
- wxString str;
- if ( M_FONTDATA )
- str = M_FONTDATA->m_faceName ;
- return str;
-}
+ wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
+
+ return M_FONTDATA->GetFaceName();
+} // end of wxFont::GetFaceName
wxFontEncoding wxFont::GetEncoding() const
{
- return M_FONTDATA->m_encoding;
-}
+ wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
+ return M_FONTDATA->GetEncoding();
+} // end of wxFont::GetEncoding
+
+const wxNativeFontInfo* wxFont::GetNativeFontInfo() const
+{
+ return M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
+ : NULL;
+} // end of wxFont::GetNativeFontInfo
+
+//
+// Internal use only method to set the FONTMETRICS array
+//
+void wxFont::SetFM( PFONTMETRICS pFM, int nNumFonts )
+{
+ M_FONTDATA->SetFM(pFM);
+ M_FONTDATA->SetNumFonts(nNumFonts);
+} // end of wxFont::SetFM
+
+
+void wxFont::SetPS( HPS hPS )
+{
+ AllocExclusive();
+
+ M_FONTDATA->SetPS(hPS);
+
+ RealizeResource();
+} // end of wxFont::SetPS