]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/font.cpp
[ 1495131 ] wxODComboBox const methods to work prior to SetPopupControl.
[wxWidgets.git] / src / os2 / font.cpp
index db5ecb184a71ecb77d59e30f1e06b60930ca0cab..9871769c778a7b82cb6a8cb7dcd53d3fd8b1c5b2 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        font.cpp
+// Name:        src/os2/font.cpp
 // Purpose:     wxFont class
 // Author:      David Webster
 // Modified by:
@@ -9,6 +9,9 @@
 // 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"
-
 #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"
 
-    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
+#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
+                  ,int             nFamily
+                  ,int             nStyle
+                  ,int             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 int GetFamily(void) const
+    {
+        return m_nFamily;
+    }
 
-    int           m_fontId;
+    inline int GetStyle(void) const
+    {
+        return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetStyle()
+                                   : m_nStyle;
+    }
 
-    // font characterstics
-    int           m_pointSize;
-    int           m_family;
-    int           m_style;
-    int           m_weight;
-    bool          m_underlined;
-    wxString      m_faceName;
-    wxFontEncoding m_encoding;
+    inline int GetWeight(void) const
+    {
+        return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetWeight()
+                                   : m_nWeight;
+    }
+
+    inline bool GetUnderlined(void) const
+    {
+        return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetUnderlined()
+                                   : m_bUnderlined;
+    }
+
+    inline wxString GetFaceName(void) const
+    {
+        wxString                    sFaceName;
+
+        if (m_bNativeFontInfoOk)
+            sFaceName = m_vNativeFontInfo.GetFaceName();
+        else
+            sFaceName = m_sFaceName;
+
+        return sFaceName;
+    }
+
+    inline wxFontEncoding GetEncoding(void) const
+    {
+        return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetEncoding()
+                                   : m_vEncoding;
+    }
 
-    // Windows font handle
-    WXHFONT       m_hFont;
-};
+    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(int nFamily)
+    {
+        m_nFamily = nFamily;
+    }
+
+    inline void SetStyle(int nStyle)
+    {
+        if (m_bNativeFontInfoOk)
+            m_vNativeFontInfo.SetStyle((wxFontStyle)nStyle);
+        else
+            m_nStyle = nStyle;
+    }
+
+    inline void SetWeight(int nWeight)
+    {
+        if (m_bNativeFontInfoOk)
+            m_vNativeFontInfo.SetWeight((wxFontWeight)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
+              ,int             nFamily
+              ,int             nStyle
+              ,int             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;
+    int                             m_nFamily;
+    int                             m_nStyle;
+    int                             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
 
 // ============================================================================
 // implementation
@@ -110,339 +304,663 @@ protected:
 // 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
+, int                               nFamily
+, int                               nStyle
+, int                               nWeight
+, bool                              bUnderlined
+, const wxString&                   rsFaceName
+, wxFontEncoding                    vEncoding
+)
 {
-// TODO:
-//    if ( m_hFont )
-//    {
-//        if ( !::DeleteObject((HFONT) m_hFont) )
-//        {
-//            wxLogLastError("DeleteObject(font)");
-//        }
-//    }
-}
-
-// ----------------------------------------------------------------------------
-// wxFont
-// ----------------------------------------------------------------------------
-
-void wxFont::Init()
-{
-    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)
+    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
+)
 {
-    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(wxT("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 = wxROMAN;
+    else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman MT 30") == 0)
+        m_nFamily = wxROMAN;
+    else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "@Times New Roman MT 30") == 0)
+        m_nFamily = wxROMAN;
+    else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Tms Rmn") == 0)
+        m_nFamily = wxROMAN;
+    else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "WarpSans") == 0)
+        m_nFamily = wxDECORATIVE;
+    else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helvetica") == 0)
+        m_nFamily = wxSWISS;
+    else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helv") == 0)
+        m_nFamily = wxSWISS;
+    else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Script") == 0)
+        m_nFamily = wxSCRIPT;
+    else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier New") == 0)
+        m_nFamily = wxTELETYPE;
+    else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier") == 0)
+        m_nFamily = wxTELETYPE;
+    else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Monospaced") == 0)
+        m_nFamily = wxTELETYPE;
+    else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System VIO") == 0)
+        m_nFamily = wxMODERN;
+    else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Proportional") == 0)
+        m_nFamily = wxMODERN;
+    else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Arial") == 0)
+        m_nFamily = wxSWISS;
+    else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Swiss") == 0)
+        m_nFamily = wxSWISS;
+    else
+        m_nFamily = wxSWISS;
 
-    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 = wxT("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 = wxT("Times New Roman") ;
+        case FWEIGHT_LIGHT:
+            m_nWeight = wxFONTWEIGHT_LIGHT;
             break;
 
-        case wxTELETYPE:
-        case wxMODERN:
-//            ff_family = FF_MODERN;
-            ff_face = wxT("Courier New") ;
+        case FWEIGHT_BOLD:
+            m_nWeight = wxFONTWEIGHT_BOLD;
             break;
 
-        case wxSWISS:
-//            ff_family = FF_SWISS;
-            ff_face = wxT("Arial") ;
+        case FWEIGHT_ULTRA_BOLD:
+            m_nWeight = wxFONTWEIGHT_MAX;
             break;
 
-        case wxDEFAULT:
         default:
-//            ff_family = FF_SWISS;
-            ff_face = wxT("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;
-
-        default:
-            wxFAIL_MSG(wxT("unknown font slant"));
-            // fall through
+        if(m_hFont)
+            ::GpiDeleteSetId( m_hPS
+                             ,flId
+                            );
 
-        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(wxT("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 = wxROMAN;
+    else if (strcmp(fm.szFamilyname, "Times New Roman MT 30") == 0)
+        nFamily = wxROMAN;
+    else if (strcmp(fm.szFamilyname, "@Times New Roman MT 30") == 0)
+        nFamily = wxROMAN;
+    else if (strcmp(fm.szFamilyname, "Tms Rmn") == 0)
+        nFamily = wxROMAN;
+    else if (strcmp(fm.szFamilyname, "WarpSans") == 0)
+        nFamily = wxDECORATIVE;
+    else if (strcmp(fm.szFamilyname, "Helvetica") == 0)
+        nFamily = wxSWISS;
+    else if (strcmp(fm.szFamilyname, "Helv") == 0)
+        nFamily = wxSWISS;
+    else if (strcmp(fm.szFamilyname, "Script") == 0)
+        nFamily = wxSCRIPT;
+    else if (strcmp(fm.szFamilyname, "Courier New") == 0)
+        nFamily = wxTELETYPE;
+    else if (strcmp(fm.szFamilyname, "Courier") == 0)
+        nFamily = wxTELETYPE;
+    else if (strcmp(fm.szFamilyname, "System Monospaced") == 0)
+        nFamily = wxTELETYPE;
+    else if (strcmp(fm.szFamilyname, "System VIO") == 0)
+        nFamily = wxMODERN;
+    else if (strcmp(fm.szFamilyname, "System Proportional") == 0)
+        nFamily = wxMODERN;
+    else if (strcmp(fm.szFamilyname, "Arial") == 0)
+        nFamily = wxSWISS;
+    else if (strcmp(fm.szFamilyname, "Swiss") == 0)
+        nFamily = wxSWISS;
+    else
+        nFamily = wxSWISS;
+    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( _T("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( _T("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
+)
+{
+    wxStrncpy((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 wxSCRIPT:
+            sFacename = wxT("Tms Rmn");
             break;
 
-        case wxFONTENCODING_ISO8859_7:
-//            charset = GREEK_CHARSET;
+        case wxDECORATIVE:
+            sFacename = wxT("WarpSans");
             break;
 
-        case wxFONTENCODING_ISO8859_8:
-//            charset = HEBREW_CHARSET;
+        case wxROMAN:
+            sFacename = wxT("Tms Rmn");
             break;
 
-        case wxFONTENCODING_ISO8859_9:
-//            charset = TURKISH_CHARSET;
+        case wxTELETYPE:
+            sFacename = wxT("Courier") ;
             break;
 
-        case wxFONTENCODING_ISO8859_11:
-//            charset = THAI_CHARSET;
+        case wxMODERN:
+            sFacename = wxT("System VIO") ;
             break;
 
-        case wxFONTENCODING_CP437:
-//            charset = OEM_CHARSET;
+        case wxSWISS:
+            sFacename = wxT("Helv") ;
             break;
 
+        case wxDEFAULT:
         default:
-            wxFAIL_MSG(wxT("unsupported encoding"));
-            // fall through
+            sFacename = wxT("System VIO") ;
+    }
 
-        case wxFONTENCODING_SYSTEM:
-//            charset = ANSI_CHARSET;
-            break;
+    if (!wxStrlen((wxChar*)fa.szFacename) )
+    {
+        SetFaceName(sFacename);
     }
+} // end of wxNativeFontInfo::SetFamily
 
-// TODO:
-WXHFONT hFont = 0;
-//    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;
-}
+void wxNativeFontInfo::SetEncoding( wxFontEncoding eEncoding )
+{
+    wxNativeEncodingInfo            vInfo;
 
-bool wxFont::FreeResource(bool force)
+    if ( !wxGetNativeFontEncoding( eEncoding
+                                  ,&vInfo
+                                 ))
+    {
+        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
+
+bool wxNativeFontInfo::FromString( const wxString& rsStr )
 {
-    if ( GetResourceHandle() )
+    long                            lVal;
+
+    wxStringTokenizer               vTokenizer(rsStr, _T(";"));
+
+    //
+    // First the version
+    //
+    wxString                        sToken = vTokenizer.GetNextToken();
+
+    if (sToken != _T('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(_T("%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,
+                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,
+                     int             nFamily,
+                     int             nStyle,
+                     int             nWeight,
+                     bool            bUnderlined,
+                     const wxString& rsFaceName,
+                     wxFontEncoding  vEncoding )
+{
+    UnRef();
+
+    //
+    // 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)
     {
-// TODO:
-//        if ( !::DeleteObject((HFONT) M_FONTDATA->m_hFont) )
-//        {
-//            wxLogLastError("DeleteObject(font)");
-//        }
+        nPointSize = wxNORMAL_FONT->GetPointSize();
+    }
+    m_refData = new wxFontRefData( nPointSize
+                                  ,nFamily
+                                  ,nStyle
+                                  ,nWeight
+                                  ,bUnderlined
+                                  ,rsFaceName
+                                  ,vEncoding
+                                 );
+    RealizeResource();
+    return true;
+} // end of wxFont::Create
 
-        M_FONTDATA->m_hFont = 0;
+wxFont::~wxFont()
+{
+} // 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
+// ----------------------------------------------------------------------------
 
-        return TRUE;
+bool wxFont::RealizeResource()
+{
+    if ( GetResourceHandle() )
+    {
+        return true;
     }
-    return FALSE;
-}
+    return M_FONTDATA->Alloc(this);
+} // end of wxFont::RealizeResource
+
+bool wxFont::FreeResource( bool WXUNUSED(bForce) )
+{
+    if (GetResourceHandle())
+    {
+        M_FONTDATA->Free();
+        return true;
+    }
+    return false;
+} // end of wxFont::FreeResource
 
 WXHANDLE wxFont::GetResourceHandle()
 {
-    if ( !M_FONTDATA )
-        return 0;
-    else
-        return (WXHANDLE)M_FONTDATA->m_hFont ;
-}
+    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->m_hFont == 0));
-}
+    return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0);
+} // end of wxFont::IsFree
 
 void wxFont::Unshare()
 {
@@ -457,71 +975,100 @@ void wxFont::Unshare()
         UnRef();
         m_refData = ref;
     }
-}
+} // end of wxFont::Unshare
 
 // ----------------------------------------------------------------------------
 // change font attribute: we recreate font when doing it
 // ----------------------------------------------------------------------------
 
-void wxFont::SetPointSize(int pointSize)
+void wxFont::SetPointSize(
+  int                               nPointSize
+)
 {
     Unshare();
 
-    M_FONTDATA->m_pointSize = pointSize;
+    M_FONTDATA->SetPointSize(nPointSize);
 
     RealizeResource();
-}
+} // end of wxFont::SetPointSize
 
-void wxFont::SetFamily(int family)
+void wxFont::SetFamily(
+  int                               nFamily
+)
 {
     Unshare();
 
-    M_FONTDATA->m_family = family;
+    M_FONTDATA->SetFamily(nFamily);
 
     RealizeResource();
-}
+} // end of wxFont::SetFamily
 
-void wxFont::SetStyle(int style)
+void wxFont::SetStyle(
+  int                               nStyle
+)
 {
     Unshare();
 
-    M_FONTDATA->m_style = style;
+    M_FONTDATA->SetStyle(nStyle);
 
     RealizeResource();
-}
+} // end of wxFont::SetStyle
 
-void wxFont::SetWeight(int weight)
+void wxFont::SetWeight(
+  int                               nWeight
+)
 {
     Unshare();
 
-    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();
 
-    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();
 
-    M_FONTDATA->m_underlined = underlined;
+    M_FONTDATA->SetUnderlined(bUnderlined);
 
     RealizeResource();
-}
+} // end of wxFont::SetUnderlined
 
-void wxFont::SetEncoding(wxFontEncoding encoding)
+void wxFont::SetEncoding(
+  wxFontEncoding                    vEncoding
+)
 {
     Unshare();
 
-    M_FONTDATA->m_encoding = encoding;
+    M_FONTDATA->SetEncoding(vEncoding);
+
+    RealizeResource();
+} // end of wxFont::SetEncoding
+
+void wxFont::DoSetNativeFontInfo(
+  const wxNativeFontInfo&           rInfo
+)
+{
+    Unshare();
+
+    FreeResource();
+
+    *M_FONTDATA = wxFontRefData(rInfo);
 
     RealizeResource();
 }
@@ -532,44 +1079,79 @@ void wxFont::SetEncoding(wxFontEncoding encoding)
 
 int wxFont::GetPointSize() const
 {
-    return M_FONTDATA->m_pointSize;
-}
+    wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
+
+    return M_FONTDATA->GetPointSize();
+} // end of wxFont::GetPointSize
 
 int wxFont::GetFamily() const
 {
-    return M_FONTDATA->m_family;
-}
+    wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
 
-int wxFont::GetFontId() const
-{
-    return M_FONTDATA->m_fontId;
-}
+    return M_FONTDATA->GetFamily();
+} // end of wxFont::GetFamily
 
 int wxFont::GetStyle() const
 {
-    return M_FONTDATA->m_style;
-}
+    wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
+
+    return M_FONTDATA->GetStyle();
+} // end of wxFont::GetStyle
 
 int wxFont::GetWeight() const
 {
-    return M_FONTDATA->m_weight;
+    wxCHECK_MSG( Ok(), 0, 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
+)
+{
+    Unshare();
 
+    M_FONTDATA->SetPS(hPS);
+
+    RealizeResource();
+} // end of wxFont::SetPS