home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / os2 / font.cpp < prev    next >
C/C++ Source or Header  |  2002-09-08  |  33KB  |  1,173 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        font.cpp
  3. // Purpose:     wxFont class
  4. // Author:      David Webster
  5. // Modified by:
  6. // Created:     10/06/99
  7. // RCS-ID:      $Id: FONT.CPP,v 1.27 2002/09/08 12:50:07 SN Exp $
  8. // Copyright:   (c) David Webster
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ============================================================================
  13. // declarations
  14. // ============================================================================
  15.  
  16. // ----------------------------------------------------------------------------
  17. // headers
  18. // ----------------------------------------------------------------------------
  19.  
  20.  #include <malloc.h>
  21. // For compilers that support precompilation, includes "wx.h".
  22. #include "wx/wxprec.h"
  23.  
  24. #ifndef WX_PRECOMP
  25.     #include <stdio.h>
  26.     #include "wx/setup.h"
  27.     #include "wx/list.h"
  28.     #include "wx/utils.h"
  29.     #include "wx/app.h"
  30.     #include "wx/font.h"
  31.     #include "wx/log.h"
  32. #endif // WX_PRECOMP
  33.  
  34. #include "wx/os2/private.h"
  35.  
  36. #include "wx/fontutil.h"
  37. #include "wx/fontmap.h"
  38.  
  39. #include "wx/tokenzr.h"
  40.  
  41. IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
  42.  
  43. // ----------------------------------------------------------------------------
  44. // wxFontRefData - the internal description of the font
  45. // ----------------------------------------------------------------------------
  46.  
  47. class WXDLLEXPORT wxFontRefData: public wxGDIRefData
  48. {
  49. public:
  50.     wxFontRefData()
  51.     {
  52.         Init(-1, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, FALSE,
  53.              "", wxFONTENCODING_DEFAULT);
  54.     }
  55.  
  56.     wxFontRefData( int             nSize
  57.                   ,int             nFamily
  58.                   ,int             nStyle
  59.                   ,int             nWeight
  60.                   ,bool            bUnderlined
  61.                   ,const wxString& sFaceName
  62.                   ,wxFontEncoding  vEncoding
  63.                  )
  64.     {
  65.         Init( nSize
  66.              ,nFamily
  67.              ,nStyle
  68.              ,nWeight
  69.              ,bUnderlined
  70.              ,sFaceName
  71.              ,vEncoding
  72.             );
  73.     }
  74.  
  75.     wxFontRefData( const wxNativeFontInfo& rInfo
  76.                   ,WXHFONT                 hFont = 0
  77.                   ,WXHANDLE                hPS   = 0
  78.                  )
  79.     {
  80.         Init( rInfo
  81.              ,hFont
  82.              ,hPS
  83.             );
  84.     }
  85.  
  86.     wxFontRefData(const wxFontRefData& rData)
  87.     {
  88.         Init( rData.m_nPointSize
  89.              ,rData.m_nFamily
  90.              ,rData.m_nStyle
  91.              ,rData.m_nWeight
  92.              ,rData.m_bUnderlined
  93.              ,rData.m_sFaceName
  94.              ,rData.m_vEncoding
  95.             );
  96.         m_nFontId = rData.m_nFontId;
  97.     }
  98.  
  99.     virtual ~wxFontRefData();
  100.  
  101.     //
  102.     // Operations
  103.     //
  104.     bool Alloc(wxFont* pFont);
  105.     void Free(void);
  106.  
  107.     //
  108.     // All wxFont accessors
  109.     //
  110.     inline int GetPointSize(void) const
  111.     {
  112.         //
  113.         // We don't use the actual native font point size since it is
  114.         // the chosen physical font, which is usually only and approximation
  115.         // of the desired outline font.  The actual displayable point size
  116.         // is the one stored in the refData
  117.         //
  118.         return m_nPointSize;
  119.     }
  120.  
  121.     inline int GetFamily(void) const
  122.     {
  123.         return m_nFamily;
  124.     }
  125.  
  126.     inline int GetStyle(void) const
  127.     {
  128.         return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetStyle()
  129.                                    : m_nStyle;
  130.     }
  131.  
  132.     inline int GetWeight(void) const
  133.     {
  134.         return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetWeight()
  135.                                    : m_nWeight;
  136.     }
  137.  
  138.     inline bool GetUnderlined(void) const
  139.     {
  140.         return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetUnderlined()
  141.                                    : m_bUnderlined;
  142.     }
  143.  
  144.     inline wxString GetFaceName(void) const
  145.     {
  146.         wxString                    sFaceName;
  147.  
  148.         if (m_bNativeFontInfoOk)
  149.             sFaceName = m_vNativeFontInfo.GetFaceName();
  150.         else
  151.             sFaceName = m_sFaceName;
  152.  
  153.         return sFaceName;
  154.     }
  155.  
  156.     inline wxFontEncoding GetEncoding(void) const
  157.     {
  158.         return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetEncoding()
  159.                                    : m_vEncoding;
  160.     }
  161.  
  162.     inline WXHFONT      GetHFONT(void) const { return m_hFont; }
  163.     inline HPS          GetPS(void) const { return m_hPS; }
  164.     inline PFONTMETRICS GetFM(void) const { return m_pFM; }
  165.     inline int          GetNumFonts(void) const { return m_nNumFonts; }
  166.  
  167.     // ... and setters
  168.     inline void SetPointSize(int nPointSize)
  169.     {
  170.         if (m_bNativeFontInfoOk)
  171.             m_vNativeFontInfo.SetPointSize(nPointSize);
  172.         else
  173.             m_nPointSize = nPointSize;
  174.     }
  175.  
  176.     inline void SetFamily(int nFamily)
  177.     {
  178.         m_nFamily = nFamily;
  179.     }
  180.  
  181.     inline void SetStyle(int nStyle)
  182.     {
  183.         if (m_bNativeFontInfoOk)
  184.             m_vNativeFontInfo.SetStyle((wxFontStyle)nStyle);
  185.         else
  186.             m_nStyle = nStyle;
  187.     }
  188.  
  189.     inline void SetWeight(int nWeight)
  190.     {
  191.         if (m_bNativeFontInfoOk)
  192.             m_vNativeFontInfo.SetWeight((wxFontWeight)nWeight);
  193.         else
  194.             m_nWeight = nWeight;
  195.     }
  196.  
  197.     inline void SetFaceName(const wxString& sFaceName)
  198.     {
  199.         if (m_bNativeFontInfoOk)
  200.             m_vNativeFontInfo.SetFaceName(sFaceName);
  201.         else
  202.             m_sFaceName = sFaceName;
  203.     }
  204.  
  205.     inline void SetUnderlined(bool bUnderlined)
  206.     {
  207.         if (m_bNativeFontInfoOk)
  208.             m_vNativeFontInfo.SetUnderlined(bUnderlined);
  209.         else
  210.             m_bUnderlined = bUnderlined;
  211.     }
  212.  
  213.     inline void SetEncoding(wxFontEncoding vEncoding)
  214.     {
  215.         if (m_bNativeFontInfoOk)
  216.             m_vNativeFontInfo.SetEncoding(vEncoding);
  217.         else
  218.             m_vEncoding = vEncoding;
  219.     }
  220.  
  221.     inline void SetPS(HPS hPS)
  222.     {
  223.         m_hPS = hPS;
  224.     }
  225.  
  226.     inline void SetFM(PFONTMETRICS pFM)
  227.     {
  228.         m_pFM = pFM;
  229.     }
  230.  
  231.     inline void SetNumFonts(int nNumFonts)
  232.     {
  233.         m_nNumFonts = nNumFonts;
  234.     }
  235.  
  236.     //
  237.     // Native font info tests
  238.     //
  239.     bool HasNativeFontInfo() const { return m_bNativeFontInfoOk; }
  240.  
  241.     const wxNativeFontInfo& GetNativeFontInfo() const
  242.         { return m_vNativeFontInfo; }
  243.  
  244. protected:
  245.     //
  246.     // Common part of all ctors
  247.     //
  248.     void Init( int             nSize
  249.               ,int             nFamily
  250.               ,int             nStyle
  251.               ,int             nWeight
  252.               ,bool            bUnderlined
  253.               ,const wxString& rsFaceName
  254.               ,wxFontEncoding  vEncoding
  255.              );
  256.  
  257.     void Init( const wxNativeFontInfo& rInfo
  258.               ,WXHFONT                 hFont = 0
  259.               ,WXHANDLE                hPS   = 0
  260.              );
  261.     //
  262.     // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE
  263.     // DELETED by destructor
  264.     //
  265.     bool                            m_bTemporary;
  266.     int                             m_nFontId;
  267.  
  268.     //
  269.     // Font characterstics
  270.     //
  271.     int                             m_nPointSize;
  272.     int                             m_nFamily;
  273.     int                             m_nStyle;
  274.     int                             m_nWeight;
  275.     bool                            m_bUnderlined;
  276.     wxString                        m_sFaceName;
  277.     wxFontEncoding                  m_vEncoding;
  278.     WXHFONT                         m_hFont;
  279.  
  280.     //
  281.     // Native font info
  282.     //
  283.     wxNativeFontInfo                m_vNativeFontInfo;
  284.     bool                            m_bNativeFontInfoOk;
  285.  
  286.     //
  287.     // Some PM specific stuff
  288.     //
  289.     PFONTMETRICS                    m_pFM;         // array of FONTMETRICS structs
  290.     int                             m_nNumFonts;   // number of fonts in array
  291.     HPS                             m_hPS;         // PS handle this font belongs to
  292.     FATTRS                          m_vFattrs;     // Current fattrs struct
  293.     FACENAMEDESC                    m_vFname;      // Current facename struct
  294.     bool                            m_bInternalPS; // Internally generated PS?
  295. }; // end of CLASS wxFontRefData
  296.  
  297. // ============================================================================
  298. // implementation
  299. // ============================================================================
  300.  
  301. // ----------------------------------------------------------------------------
  302. // wxFontRefData
  303. // ----------------------------------------------------------------------------
  304.  
  305. void wxFontRefData::Init(
  306.   int                               nPointSize
  307. , int                               nFamily
  308. , int                               nStyle
  309. , int                               nWeight
  310. , bool                              bUnderlined
  311. , const wxString&                   rsFaceName
  312. , wxFontEncoding                    vEncoding
  313. )
  314. {
  315.     m_nStyle      = nStyle;
  316.     m_nPointSize  = nPointSize;
  317.     m_nFamily     = nFamily;
  318.     m_nStyle      = nStyle;
  319.     m_nWeight     = nWeight;
  320.     m_bUnderlined = bUnderlined;
  321.     m_sFaceName   = rsFaceName;
  322.     m_vEncoding   = vEncoding;
  323.     m_hFont       = 0;
  324.  
  325.     m_bNativeFontInfoOk = FALSE;
  326.  
  327.     m_nFontId     = 0;
  328.     m_bTemporary  = FALSE;
  329.     m_pFM         = (PFONTMETRICS)NULL;
  330.     m_hPS         = NULLHANDLE;
  331.     m_nNumFonts   = 0;
  332. } // end of wxFontRefData::Init
  333.  
  334. void wxFontRefData::Init(
  335.   const wxNativeFontInfo&           rInfo
  336. , WXHFONT                           hFont //this is the FontId -- functions as the hFont for OS/2
  337. , WXHANDLE                          hPS   // Presentation Space we are using
  338. )
  339. {
  340.     //
  341.     // hFont may be zero, or it be passed in case we really want to
  342.     // use the exact font created in the underlying system
  343.     // (for example where we can't guarantee conversion from HFONT
  344.     // to LOGFONT back to HFONT)
  345.     //
  346.     m_hFont = hFont;
  347.     m_nFontId = (int)hFont;
  348.  
  349.     m_bNativeFontInfoOk = TRUE;
  350.     m_vNativeFontInfo = rInfo;
  351.  
  352.     if (hPS == NULLHANDLE)
  353.     {
  354.         m_hPS = ::WinGetPS(HWND_DESKTOP);
  355.         m_bInternalPS = TRUE;
  356.     }
  357.     else
  358.         m_hPS = (HPS)hPS;
  359.  
  360.     m_nFontId     = 0;
  361.     m_bTemporary  = FALSE;
  362.     m_pFM         = (PFONTMETRICS)NULL;
  363.     m_nNumFonts   = 0;
  364. } // end of wxFontRefData::Init
  365.  
  366. wxFontRefData::~wxFontRefData()
  367. {
  368.     Free();
  369. }
  370.  
  371. bool wxFontRefData::Alloc(
  372.   wxFont*                           pFont
  373. )
  374. {
  375.     wxString                        sFaceName;
  376.     long                            flId = m_hFont;
  377.     long                            lRc;
  378.     short                           nIndex = 0;
  379.     PFONTMETRICS                    pFM = NULL;
  380.     ERRORID                         vError;
  381.     wxString                        sError;
  382.  
  383.     if (!m_bNativeFontInfoOk)
  384.     {
  385.         wxFillLogFont( &m_vNativeFontInfo.fa
  386.                       ,&m_vNativeFontInfo.fn
  387.                       ,&m_hPS
  388.                       ,&m_bInternalPS
  389.                       ,&flId
  390.                       ,sFaceName
  391.                       ,pFont
  392.                      );
  393.         m_bNativeFontInfoOk = TRUE;
  394.     }
  395.     else
  396.     {
  397.         if (flId == 0L)
  398.             flId = 1L;
  399.         else
  400.             flId++;
  401.         if (flId > 254)
  402.             flId = 1L;
  403.     }
  404.     if((lRc = ::GpiCreateLogFont( m_hPS
  405.                                  ,NULL
  406.                                  ,flId
  407.                                  ,&m_vNativeFontInfo.fa
  408.                                 )) != GPI_ERROR)
  409.     {
  410.        m_hFont = (WXHFONT)flId;
  411.        m_nFontId = flId;
  412.     }
  413.     if (!m_hFont)
  414.     {
  415.         vError = ::WinGetLastError(vHabmain);
  416.         sError = wxPMErrorToStr(vError);
  417.         wxLogLastError("CreateFont");
  418.     }
  419.  
  420.     ::GpiSetCharSet(m_hPS, flId); // sets font for presentation space
  421.     ::GpiQueryFontMetrics(m_hPS, sizeof(FONTMETRICS), &m_vNativeFontInfo.fm);
  422.  
  423.     //
  424.     // Set refData members with the results
  425.     //
  426.     memcpy(&m_vFattrs, &m_vNativeFontInfo.fa, sizeof(m_vFattrs));
  427.     memcpy(&m_vFname, &m_vNativeFontInfo.fn, sizeof(m_vFname));
  428.     //
  429.     // Going to leave the point size alone.  Mostly we use outline fonts
  430.     // that can be set to any point size inside of Presentation Parameters,
  431.     // regardless of whether or not the actual font is registered in the system.
  432.     // The GpiCreateLogFont will do enough by selecting the right family,
  433.     // and face name.
  434.     //
  435.     if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman") == 0)
  436.         m_nFamily = wxROMAN;
  437.     else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman MT 30") == 0)
  438.         m_nFamily = wxROMAN;
  439.     else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "@Times New Roman MT 30") == 0)
  440.         m_nFamily = wxROMAN;
  441.     else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Tms Rmn") == 0)
  442.         m_nFamily = wxROMAN;
  443.     else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "WarpSans") == 0)
  444.         m_nFamily = wxDECORATIVE;
  445.     else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helvetica") == 0)
  446.         m_nFamily = wxSWISS;
  447.     else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helv") == 0)
  448.         m_nFamily = wxSWISS;
  449.     else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Script") == 0)
  450.         m_nFamily = wxSCRIPT;
  451.     else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier New") == 0)
  452.         m_nFamily = wxTELETYPE;
  453.     else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier") == 0)
  454.         m_nFamily = wxTELETYPE;
  455.     else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Monospaced") == 0)
  456.         m_nFamily = wxTELETYPE;
  457.     else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System VIO") == 0)
  458.         m_nFamily = wxMODERN;
  459.     else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Proportional") == 0)
  460.         m_nFamily = wxMODERN;
  461.     else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Arial") == 0)
  462.         m_nFamily = wxSWISS;
  463.     else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Swiss") == 0)
  464.         m_nFamily = wxSWISS;
  465.     else
  466.         m_nFamily = wxSWISS;
  467.  
  468.     if (m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_ITALIC)
  469.         m_nStyle = wxFONTSTYLE_ITALIC;
  470.     else
  471.         m_nStyle = wxFONTSTYLE_NORMAL;
  472.     switch(m_vNativeFontInfo.fn.usWeightClass)
  473.     {
  474.         case FWEIGHT_DONT_CARE:
  475.             m_nWeight = wxFONTWEIGHT_NORMAL;
  476.             break;
  477.  
  478.         case FWEIGHT_NORMAL:
  479.             m_nWeight = wxFONTWEIGHT_NORMAL;
  480.             break;
  481.  
  482.         case FWEIGHT_LIGHT:
  483.             m_nWeight = wxFONTWEIGHT_LIGHT;
  484.             break;
  485.  
  486.         case FWEIGHT_BOLD:
  487.             m_nWeight = wxFONTWEIGHT_BOLD;
  488.             break;
  489.  
  490.         case FWEIGHT_ULTRA_BOLD:
  491.             m_nWeight = wxFONTWEIGHT_MAX;
  492.             break;
  493.  
  494.         default:
  495.             m_nWeight = wxFONTWEIGHT_NORMAL;
  496.     }
  497.     m_bUnderlined = ((m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0);
  498.     m_sFaceName = m_vNativeFontInfo.fa.szFacename;
  499.     m_vEncoding = wxGetFontEncFromCharSet(m_vNativeFontInfo.fa.usCodePage);
  500.  
  501.     //
  502.     // We don't actuall keep the font around if using a temporary PS
  503.     //
  504.     if (m_bInternalPS)
  505.     {
  506.         if(m_hFont)
  507.             ::GpiDeleteSetId( m_hPS
  508.                              ,flId
  509.                             );
  510.  
  511.         ::WinReleasePS(m_hPS);
  512.     }
  513.     else
  514.         //
  515.         // Select the font into the Presentation space
  516.         //
  517.         ::GpiSetCharSet(m_hPS, flId); // sets font for presentation space
  518.     return TRUE;
  519. } // end of wxFontRefData::Alloc
  520.  
  521. void wxFontRefData::Free()
  522. {
  523.     if (m_pFM)
  524.         delete [] m_pFM;
  525.     m_pFM = (PFONTMETRICS)NULL;
  526.  
  527.     if ( m_hFont )
  528.     {
  529.         ::GpiDeleteSetId(m_hPS, 1L); /* delete the logical font          */
  530.         m_nFontId = 0;
  531.         m_hFont   = 0;
  532.     }
  533.     if (m_bInternalPS)
  534.         ::WinReleasePS(m_hPS);
  535.     m_hPS = NULLHANDLE;
  536. } // end of wxFontRefData::Free
  537.  
  538. // ----------------------------------------------------------------------------
  539. // wxNativeFontInfo
  540. // ----------------------------------------------------------------------------
  541.  
  542. void wxNativeFontInfo::Init()
  543. {
  544.     memset(&fa, '\0', sizeof(FATTRS));
  545. } // end of wxNativeFontInfo::Init
  546.  
  547. int wxNativeFontInfo::GetPointSize() const
  548. {
  549.     return fm.lEmHeight;
  550. } // end of wxNativeFontInfo::GetPointSize
  551.  
  552. wxFontStyle wxNativeFontInfo::GetStyle() const
  553. {
  554.     return fa.fsSelection & FATTR_SEL_ITALIC ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
  555. } // end of wxNativeFontInfo::GetStyle
  556.  
  557. wxFontWeight wxNativeFontInfo::GetWeight() const
  558. {
  559.     switch(fn.usWeightClass)
  560.     {
  561.         case FWEIGHT_DONT_CARE:
  562.             return wxFONTWEIGHT_NORMAL;
  563.  
  564.         case FWEIGHT_NORMAL:
  565.             return wxFONTWEIGHT_NORMAL;
  566.  
  567.         case FWEIGHT_LIGHT:
  568.             return wxFONTWEIGHT_LIGHT;
  569.  
  570.         case FWEIGHT_BOLD:
  571.             return wxFONTWEIGHT_BOLD;
  572.  
  573.         case FWEIGHT_ULTRA_BOLD:
  574.             return wxFONTWEIGHT_MAX;
  575.     }
  576.     return wxFONTWEIGHT_NORMAL;
  577. } // end of wxNativeFontInfo::GetWeight
  578.  
  579. bool wxNativeFontInfo::GetUnderlined() const
  580. {
  581.     return ((fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0);
  582. } // end of wxNativeFontInfo::GetUnderlined
  583.  
  584. wxString wxNativeFontInfo::GetFaceName() const
  585. {
  586.     return fm.szFacename;
  587. } // end of wxNativeFontInfo::GetFaceName
  588.  
  589. wxFontFamily wxNativeFontInfo::GetFamily() const
  590. {
  591.     int                             nFamily;
  592.  
  593.     //
  594.     // Extract family from facename
  595.     //
  596.     if (strcmp(fm.szFamilyname, "Times New Roman") == 0)
  597.         nFamily = wxROMAN;
  598.     else if (strcmp(fm.szFamilyname, "Times New Roman MT 30") == 0)
  599.         nFamily = wxROMAN;
  600.     else if (strcmp(fm.szFamilyname, "@Times New Roman MT 30") == 0)
  601.         nFamily = wxROMAN;
  602.     else if (strcmp(fm.szFamilyname, "Tms Rmn") == 0)
  603.         nFamily = wxROMAN;
  604.     else if (strcmp(fm.szFamilyname, "WarpSans") == 0)
  605.         nFamily = wxDECORATIVE;
  606.     else if (strcmp(fm.szFamilyname, "Helvetica") == 0)
  607.         nFamily = wxSWISS;
  608.     else if (strcmp(fm.szFamilyname, "Helv") == 0)
  609.         nFamily = wxSWISS;
  610.     else if (strcmp(fm.szFamilyname, "Script") == 0)
  611.         nFamily = wxSCRIPT;
  612.     else if (strcmp(fm.szFamilyname, "Courier New") == 0)
  613.         nFamily = wxTELETYPE;
  614.     else if (strcmp(fm.szFamilyname, "Courier") == 0)
  615.         nFamily = wxTELETYPE;
  616.     else if (strcmp(fm.szFamilyname, "System Monospaced") == 0)
  617.         nFamily = wxTELETYPE;
  618.     else if (strcmp(fm.szFamilyname, "System VIO") == 0)
  619.         nFamily = wxMODERN;
  620.     else if (strcmp(fm.szFamilyname, "System Proportional") == 0)
  621.         nFamily = wxMODERN;
  622.     else if (strcmp(fm.szFamilyname, "Arial") == 0)
  623.         nFamily = wxSWISS;
  624.     else if (strcmp(fm.szFamilyname, "Swiss") == 0)
  625.         nFamily = wxSWISS;
  626.     else
  627.         nFamily = wxSWISS;
  628.     return (wxFontFamily)nFamily;
  629. } // end of wxNativeFontInfo::GetFamily
  630.  
  631. wxFontEncoding wxNativeFontInfo::GetEncoding() const
  632. {
  633.     return wxGetFontEncFromCharSet(fa.usCodePage);
  634. } // end of wxNativeFontInfo::GetEncoding
  635.  
  636. void wxNativeFontInfo::SetPointSize(
  637.   int                               nPointsize
  638. )
  639. {
  640.     fm.lEmHeight = (LONG)nPointsize;
  641. } // end of wxNativeFontInfo::SetPointSize
  642.  
  643. void wxNativeFontInfo::SetStyle(
  644.   wxFontStyle                       eStyle
  645. )
  646. {
  647.     switch (eStyle)
  648.     {
  649.         default:
  650.             wxFAIL_MSG( _T("unknown font style") );
  651.             // fall through
  652.  
  653.         case wxFONTSTYLE_NORMAL:
  654.             break;
  655.  
  656.         case wxFONTSTYLE_ITALIC:
  657.         case wxFONTSTYLE_SLANT:
  658.             fa.fsSelection |= FATTR_SEL_ITALIC;
  659.             break;
  660.     }
  661. } // end of wxNativeFontInfo::SetStyle
  662.  
  663. void wxNativeFontInfo::SetWeight(
  664.   wxFontWeight                      eWeight
  665. )
  666. {
  667.     switch (eWeight)
  668.     {
  669.         default:
  670.             wxFAIL_MSG( _T("unknown font weight") );
  671.             // fall through
  672.  
  673.         case wxFONTWEIGHT_NORMAL:
  674.             fn.usWeightClass = FWEIGHT_NORMAL;
  675.             break;
  676.  
  677.         case wxFONTWEIGHT_LIGHT:
  678.             fn.usWeightClass = FWEIGHT_LIGHT;
  679.             break;
  680.  
  681.         case wxFONTWEIGHT_BOLD:
  682.             fn.usWeightClass = FWEIGHT_BOLD;
  683.             break;
  684.     }
  685. } // end of wxNativeFontInfo::SetWeight
  686.  
  687. void wxNativeFontInfo::SetUnderlined(
  688.   bool                              bUnderlined
  689. )
  690. {
  691.     if(bUnderlined)
  692.         fa.fsSelection |= FATTR_SEL_UNDERSCORE;
  693. } // end of wxNativeFontInfo::SetUnderlined
  694.  
  695. void wxNativeFontInfo::SetFaceName(
  696.   wxString                          sFacename
  697. )
  698. {
  699.     wxStrncpy(fa.szFacename, sFacename, WXSIZEOF(fa.szFacename));
  700. } // end of wxNativeFontInfo::SetFaceName
  701.  
  702. void wxNativeFontInfo::SetFamily(
  703.   wxFontFamily                      eFamily
  704. )
  705. {
  706.     wxString                        sFacename;
  707.  
  708.     switch (eFamily)
  709.     {
  710.         case wxSCRIPT:
  711.             sFacename = wxT("Tms Rmn");
  712.             break;
  713.  
  714.         case wxDECORATIVE:
  715.             sFacename = wxT("WarpSans");
  716.             break;
  717.  
  718.         case wxROMAN:
  719.             sFacename = wxT("Tms Rmn");
  720.             break;
  721.  
  722.         case wxTELETYPE:
  723.             sFacename = wxT("Courier") ;
  724.             break;
  725.  
  726.         case wxMODERN:
  727.             sFacename = wxT("System VIO") ;
  728.             break;
  729.  
  730.         case wxSWISS:
  731.             sFacename = wxT("Helv") ;
  732.             break;
  733.  
  734.         case wxDEFAULT:
  735.         default:
  736.             sFacename = wxT("System VIO") ;
  737.     }
  738.  
  739.     if (!wxStrlen(fa.szFacename) )
  740.     {
  741.         SetFaceName(sFacename);
  742.     }
  743. } // end of wxNativeFontInfo::SetFamily
  744.  
  745. void wxNativeFontInfo::SetEncoding(
  746.   wxFontEncoding                    eEncoding
  747. )
  748. {
  749.     wxNativeEncodingInfo            vInfo;
  750.  
  751.     if ( !wxGetNativeFontEncoding( eEncoding
  752.                                   ,&vInfo
  753.                                  ))
  754.     {
  755.         if (wxFontMapper::Get()->GetAltForEncoding( eEncoding
  756.                                                ,&vInfo
  757.                                               ))
  758.         {
  759.             if (!vInfo.facename.empty())
  760.             {
  761.                 //
  762.                 // If we have this encoding only in some particular facename, use
  763.                 // the facename - it is better to show the correct characters in a
  764.                 // wrong facename than unreadable text in a correct one
  765.                 //
  766.                 SetFaceName(vInfo.facename);
  767.             }
  768.         }
  769.         else
  770.         {
  771.             // unsupported encoding, replace with the default
  772.             vInfo.charset = 850;
  773.         }
  774.     }
  775.     fa.usCodePage = vInfo.charset;
  776. } // end of wxNativeFontInfo::SetFaceName
  777.  
  778. bool wxNativeFontInfo::FromString(
  779.   const wxString&                   rsStr
  780. )
  781. {
  782.     long                            lVal;
  783.  
  784.     wxStringTokenizer               vTokenizer(rsStr, _T(";"));
  785.  
  786.     //
  787.     // First the version
  788.     //
  789.     wxString                        sToken = vTokenizer.GetNextToken();
  790.  
  791.     if (sToken != _T('0'))
  792.         return FALSE;
  793.  
  794.     sToken = vTokenizer.GetNextToken();
  795.     if (!sToken.ToLong(&lVal))
  796.         return FALSE;
  797.     fm.lEmHeight = lVal;
  798.  
  799.     sToken = vTokenizer.GetNextToken();
  800.     if (!sToken.ToLong(&lVal))
  801.         return FALSE;
  802.     fa.lAveCharWidth = lVal;
  803.  
  804.     sToken = vTokenizer.GetNextToken();
  805.     if (!sToken.ToLong(&lVal))
  806.         return FALSE;
  807.     fa.fsSelection = (USHORT)lVal;
  808.  
  809.     sToken = vTokenizer.GetNextToken();
  810.     if (!sToken.ToLong(&lVal))
  811.         return FALSE;
  812.     fa.fsType = (USHORT)lVal;
  813.  
  814.     sToken = vTokenizer.GetNextToken();
  815.     if (!sToken.ToLong(&lVal))
  816.         return FALSE;
  817.     fa.fsFontUse = (USHORT)lVal;
  818.  
  819.     sToken = vTokenizer.GetNextToken();
  820.     if (!sToken.ToLong(&lVal))
  821.         return FALSE;
  822.     fa.idRegistry = (USHORT)lVal;
  823.  
  824.     sToken = vTokenizer.GetNextToken();
  825.     if (!sToken.ToLong(&lVal))
  826.         return FALSE;
  827.     fa.usCodePage = (USHORT)lVal;
  828.  
  829.     sToken = vTokenizer.GetNextToken();
  830.     if (!sToken.ToLong(&lVal))
  831.         return FALSE;
  832.     fa.lMatch = lVal;
  833.  
  834.     sToken = vTokenizer.GetNextToken();
  835.     if (!sToken.ToLong(&lVal))
  836.         return FALSE;
  837.     fn.usWeightClass = (USHORT)lVal;
  838.  
  839.     sToken = vTokenizer.GetNextToken();
  840.     if(!sToken)
  841.         return FALSE;
  842.     wxStrcpy(fa.szFacename, sToken.c_str());
  843.     return TRUE;
  844. } // end of wxNativeFontInfo::FromString
  845.  
  846. wxString wxNativeFontInfo::ToString() const
  847. {
  848.     wxString sStr;
  849.  
  850.     sStr.Printf(_T("%d;%ld;%ld;%ld;%d;%d;%d;%d;%d;%ld;%d;%s"),
  851.                 0, // version, in case we want to change the format later
  852.                 fm.lEmHeight,
  853.                 fa.lAveCharWidth,
  854.                 fa.lMaxBaselineExt,
  855.                 fa.fsSelection,
  856.                 fa.fsType,
  857.                 fa.fsFontUse,
  858.                 fa.idRegistry,
  859.                 fa.usCodePage,
  860.                 fa.lMatch,
  861.                 fn.usWeightClass,
  862.                 fa.szFacename);
  863.     return sStr;
  864. } // end of wxNativeFontInfo::ToString
  865.  
  866. // ----------------------------------------------------------------------------
  867. // wxFont
  868. // ----------------------------------------------------------------------------
  869.  
  870. void wxFont::Init()
  871. {
  872. } // end of wxFont::Init
  873.  
  874. bool wxFont::Create(
  875.   const wxNativeFontInfo&           rInfo
  876. , WXHFONT                           hFont
  877. )
  878. {
  879.     UnRef();
  880.     m_refData = new wxFontRefData( rInfo
  881.                                   ,hFont
  882.                                  );
  883.     RealizeResource();
  884.     return TRUE;
  885. } // end of wxFont::Create
  886.  
  887. wxFont::wxFont(
  888.   const wxString&                   rsFontdesc
  889. )
  890. {
  891.     wxNativeFontInfo                vInfo;
  892.  
  893.     if (vInfo.FromString(rsFontdesc))
  894.         (void)Create(vInfo);
  895. } // end of wxFont::wxFont
  896.  
  897. // ----------------------------------------------------------------------------
  898. // Constructor for a font. Note that the real construction is done
  899. // in wxDC::SetFont, when information is available about scaling etc.
  900. // ----------------------------------------------------------------------------
  901. bool wxFont::Create(
  902.   int                               nPointSize
  903. , int                               nFamily
  904. , int                               nStyle
  905. , int                               nWeight
  906. , bool                              bUnderlined
  907. , const wxString&                   rsFaceName
  908. , wxFontEncoding                    vEncoding
  909. )
  910. {
  911.     UnRef();
  912.  
  913.     //
  914.     // wxDEFAULT is a valid value for the font size too so we must treat it
  915.     // specially here (otherwise the size would be 70 == wxDEFAULT value)
  916.     //
  917.     if (nPointSize == wxDEFAULT)
  918.     {
  919.         nPointSize = wxNORMAL_FONT->GetPointSize();
  920.     }
  921.     m_refData = new wxFontRefData( nPointSize
  922.                                   ,nFamily
  923.                                   ,nStyle
  924.                                   ,nWeight
  925.                                   ,bUnderlined
  926.                                   ,rsFaceName
  927.                                   ,vEncoding
  928.                                  );
  929.     RealizeResource();
  930.     return TRUE;
  931. } // end of wxFont::Create
  932.  
  933. wxFont::~wxFont()
  934. {
  935. } // end of wxFont::~wxFont
  936.  
  937. // ----------------------------------------------------------------------------
  938. // real implementation
  939. // Boris' Kovalenko comments:
  940. //   Because OS/2 fonts are associated with PS we can not create the font
  941. //   here, but we may check that font definition is true
  942. // ----------------------------------------------------------------------------
  943.  
  944. bool wxFont::RealizeResource()
  945. {
  946.     if ( GetResourceHandle() )
  947.     {
  948.         return TRUE;
  949.     }
  950.     return M_FONTDATA->Alloc(this);
  951. } // end of wxFont::RealizeResource
  952.  
  953. bool wxFont::FreeResource(
  954.   bool                              bForce
  955. )
  956. {
  957.     if (GetResourceHandle())
  958.     {
  959.         M_FONTDATA->Free();
  960.         return TRUE;
  961.     }
  962.     return FALSE;
  963. } // end of wxFont::FreeResource
  964.  
  965. WXHANDLE wxFont::GetResourceHandle()
  966. {
  967.     return GetHFONT();
  968. } // end of wxFont::GetResourceHandle
  969.  
  970. WXHFONT wxFont::GetHFONT() const
  971. {
  972.     return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
  973. } // end of wxFont::GetHFONT
  974.  
  975. bool wxFont::IsFree() const
  976. {
  977.     return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0);
  978. } // end of wxFont::IsFree
  979.  
  980. void wxFont::Unshare()
  981. {
  982.     // Don't change shared data
  983.     if ( !m_refData )
  984.     {
  985.         m_refData = new wxFontRefData();
  986.     }
  987.     else
  988.     {
  989.         wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
  990.         UnRef();
  991.         m_refData = ref;
  992.     }
  993. } // end of wxFont::Unshare
  994.  
  995. // ----------------------------------------------------------------------------
  996. // change font attribute: we recreate font when doing it
  997. // ----------------------------------------------------------------------------
  998.  
  999. void wxFont::SetPointSize(
  1000.   int                               nPointSize
  1001. )
  1002. {
  1003.     Unshare();
  1004.  
  1005.     M_FONTDATA->SetPointSize(nPointSize);
  1006.  
  1007.     RealizeResource();
  1008. } // end of wxFont::SetPointSize
  1009.  
  1010. void wxFont::SetFamily(
  1011.   int                               nFamily
  1012. )
  1013. {
  1014.     Unshare();
  1015.  
  1016.     M_FONTDATA->SetFamily(nFamily);
  1017.  
  1018.     RealizeResource();
  1019. } // end of wxFont::SetFamily
  1020.  
  1021. void wxFont::SetStyle(
  1022.   int                               nStyle
  1023. )
  1024. {
  1025.     Unshare();
  1026.  
  1027.     M_FONTDATA->SetStyle(nStyle);
  1028.  
  1029.     RealizeResource();
  1030. } // end of wxFont::SetStyle
  1031.  
  1032. void wxFont::SetWeight(
  1033.   int                               nWeight
  1034. )
  1035. {
  1036.     Unshare();
  1037.  
  1038.     M_FONTDATA->SetWeight(nWeight);
  1039.  
  1040.     RealizeResource();
  1041. } // end of wxFont::SetWeight
  1042.  
  1043. void wxFont::SetFaceName(
  1044.   const wxString&                   rsFaceName
  1045. )
  1046. {
  1047.     Unshare();
  1048.  
  1049.     M_FONTDATA->SetFaceName(rsFaceName);
  1050.  
  1051.     RealizeResource();
  1052. } // end of wxFont::SetFaceName
  1053.  
  1054. void wxFont::SetUnderlined(
  1055.   bool                              bUnderlined
  1056. )
  1057. {
  1058.     Unshare();
  1059.  
  1060.     M_FONTDATA->SetUnderlined(bUnderlined);
  1061.  
  1062.     RealizeResource();
  1063. } // end of wxFont::SetUnderlined
  1064.  
  1065. void wxFont::SetEncoding(
  1066.   wxFontEncoding                    vEncoding
  1067. )
  1068. {
  1069.     Unshare();
  1070.  
  1071.     M_FONTDATA->SetEncoding(vEncoding);
  1072.  
  1073.     RealizeResource();
  1074. } // end of wxFont::SetEncoding
  1075.  
  1076. void wxFont::SetNativeFontInfo(
  1077.   const wxNativeFontInfo&           rInfo
  1078. )
  1079. {
  1080.     Unshare();
  1081.  
  1082.     FreeResource();
  1083.  
  1084.     *M_FONTDATA = wxFontRefData(rInfo);
  1085.  
  1086.     RealizeResource();
  1087. }
  1088.  
  1089. // ----------------------------------------------------------------------------
  1090. // accessors
  1091. // ----------------------------------------------------------------------------
  1092.  
  1093. int wxFont::GetPointSize() const
  1094. {
  1095.     wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
  1096.  
  1097.     return M_FONTDATA->GetPointSize();
  1098. } // end of wxFont::GetPointSize
  1099.  
  1100. int wxFont::GetFamily() const
  1101. {
  1102.     wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
  1103.  
  1104.     return M_FONTDATA->GetFamily();
  1105. } // end of wxFont::GetFamily
  1106.  
  1107. int wxFont::GetStyle() const
  1108. {
  1109.     wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
  1110.  
  1111.     return M_FONTDATA->GetStyle();
  1112. } // end of wxFont::GetStyle
  1113.  
  1114. int wxFont::GetWeight() const
  1115. {
  1116.     wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
  1117.  
  1118.     return M_FONTDATA->GetWeight();
  1119. }
  1120.  
  1121. bool wxFont::GetUnderlined() const
  1122. {
  1123.     wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") );
  1124.  
  1125.     return M_FONTDATA->GetUnderlined();
  1126. } // end of wxFont::GetUnderlined
  1127.  
  1128. wxString wxFont::GetFaceName() const
  1129. {
  1130.     wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
  1131.  
  1132.     return M_FONTDATA->GetFaceName();
  1133. } // end of wxFont::GetFaceName
  1134.  
  1135. wxFontEncoding wxFont::GetEncoding() const
  1136. {
  1137.     wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
  1138.  
  1139.     return M_FONTDATA->GetEncoding();
  1140. } // end of wxFont::GetEncoding
  1141.  
  1142. wxNativeFontInfo* wxFont::GetNativeFontInfo() const
  1143. {
  1144.     if (M_FONTDATA->HasNativeFontInfo())
  1145.         return new wxNativeFontInfo(M_FONTDATA->GetNativeFontInfo());
  1146.     return 0;
  1147. } // end of wxFont::GetNativeFontInfo
  1148.  
  1149. //
  1150. // Internal use only method to set the FONTMETRICS array
  1151. //
  1152. void wxFont::SetFM(
  1153.   PFONTMETRICS                      pFM
  1154. , int                               nNumFonts
  1155. )
  1156. {
  1157.     M_FONTDATA->SetFM(pFM);
  1158.     M_FONTDATA->SetNumFonts(nNumFonts);
  1159. } // end of wxFont::SetFM
  1160.  
  1161.  
  1162. void wxFont::SetPS(
  1163.   HPS                               hPS
  1164. )
  1165. {
  1166.     Unshare();
  1167.  
  1168.     M_FONTDATA->SetPS(hPS);
  1169.  
  1170.     RealizeResource();
  1171. } // end of wxFont::SetPS
  1172.  
  1173.