X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e99762c031bf2c71af7f856c1d713bce0422acaa..718970e5906a1fe0f84cc6ea9418cd79377767cd:/src/os2/font.cpp diff --git a/src/os2/font.cpp b/src/os2/font.cpp index 38289bdeba..517053a915 100644 --- a/src/os2/font.cpp +++ b/src/os2/font.cpp @@ -28,15 +28,18 @@ #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 +IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject) // ---------------------------------------------------------------------------- // wxFontRefData - the internal description of the font @@ -44,23 +47,13 @@ IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject) class WXDLLEXPORT wxFontRefData: public wxGDIRefData { -friend class WXDLLEXPORT wxFont; - public: wxFontRefData() { - Init(12, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE, + Init(-1, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, FALSE, "", wxFONTENCODING_DEFAULT); } - wxFontRefData(const wxFontRefData& data) - { - Init(data.m_nPointSize, data.m_nFamily, data.m_nStyle, data.m_nWeight, - data.m_bUnderlined, data.m_sFaceName, data.m_vEncoding); - - m_nFontId = data.m_nFontId; - } - wxFontRefData( int nSize ,int nFamily ,int nStyle @@ -70,13 +63,189 @@ public: ,wxFontEncoding vEncoding ) { - Init(nSize, nFamily, nStyle, nWeight, bUnderlined, sFaceName, vEncoding); + Init( nSize + ,nFamily + ,nStyle + ,nWeight + ,bUnderlined + ,sFaceName + ,vEncoding + ); + } + + wxFontRefData( const wxNativeFontInfo& rInfo + ,WXHFONT hFont = 0 + ,WXHANDLE hPS = 0 + ) + { + Init( rInfo + ,hFont + ,hPS + ); + } + + wxFontRefData(const wxFontRefData& rData) + { + 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(); + // + // 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; + } + + inline int GetStyle(void) const + { + return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetStyle() + : m_nStyle; + } + + 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; + } + + 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 void SetFaceName(const wxString& sFaceName) + { + if (m_bNativeFontInfoOk) + m_vNativeFontInfo.SetFaceName(sFaceName); + else + m_sFaceName = sFaceName; + } + + 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 + // + // Common part of all ctors + // void Init( int nSize ,int nFamily ,int nStyle @@ -86,6 +255,10 @@ protected: ,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 @@ -103,16 +276,23 @@ protected: 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 // - WXHFONT m_hFont; - 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 + 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 // ============================================================================ @@ -141,21 +321,546 @@ void wxFontRefData::Init( m_bUnderlined = bUnderlined; m_sFaceName = rsFaceName; m_vEncoding = vEncoding; + m_hFont = 0; + + m_bNativeFontInfoOk = FALSE; + m_nFontId = 0; m_bTemporary = FALSE; - - m_hFont = 0; 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 +) +{ + // + // 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; + + m_nFontId = 0; + m_bTemporary = FALSE; + m_pFM = (PFONTMETRICS)NULL; + m_nNumFonts = 0; +} // end of wxFontRefData::Init + wxFontRefData::~wxFontRefData() +{ + Free(); +} + +bool wxFontRefData::Alloc( + wxFont* pFont +) +{ + wxString sFaceName; + long flId = m_hFont; + long lRc; + ERRORID vError; + wxString sError; + + 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("CreateFont"); + } + + ::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; + + if (m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_ITALIC) + m_nStyle = wxFONTSTYLE_ITALIC; + else + m_nStyle = wxFONTSTYLE_NORMAL; + switch(m_vNativeFontInfo.fn.usWeightClass) + { + case FWEIGHT_DONT_CARE: + m_nWeight = wxFONTWEIGHT_NORMAL; + break; + + case FWEIGHT_NORMAL: + m_nWeight = wxFONTWEIGHT_NORMAL; + break; + + case FWEIGHT_LIGHT: + m_nWeight = wxFONTWEIGHT_LIGHT; + break; + + case FWEIGHT_BOLD: + m_nWeight = wxFONTWEIGHT_BOLD; + break; + + case FWEIGHT_ULTRA_BOLD: + m_nWeight = wxFONTWEIGHT_MAX; + break; + + default: + m_nWeight = wxFONTWEIGHT_NORMAL; + } + m_bUnderlined = ((m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0); + m_sFaceName = 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) + { + if(m_hFont) + ::GpiDeleteSetId( m_hPS + ,flId + ); + + ::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; -} + + if ( m_hFont ) + { + ::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 + +// ---------------------------------------------------------------------------- +// wxNativeFontInfo +// ---------------------------------------------------------------------------- + +void wxNativeFontInfo::Init() +{ + memset(&fa, '\0', sizeof(FATTRS)); +} // end of wxNativeFontInfo::Init + +int wxNativeFontInfo::GetPointSize() const +{ + return fm.lEmHeight; +} // end of wxNativeFontInfo::GetPointSize + +wxFontStyle wxNativeFontInfo::GetStyle() const +{ + return fa.fsSelection & FATTR_SEL_ITALIC ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL; +} // end of wxNativeFontInfo::GetStyle + +wxFontWeight wxNativeFontInfo::GetWeight() const +{ + switch(fn.usWeightClass) + { + case FWEIGHT_DONT_CARE: + return wxFONTWEIGHT_NORMAL; + + case FWEIGHT_NORMAL: + return wxFONTWEIGHT_NORMAL; + + case FWEIGHT_LIGHT: + return wxFONTWEIGHT_LIGHT; + + case FWEIGHT_BOLD: + return wxFONTWEIGHT_BOLD; + + case FWEIGHT_ULTRA_BOLD: + return wxFONTWEIGHT_MAX; + } + return wxFONTWEIGHT_NORMAL; +} // end of wxNativeFontInfo::GetWeight + +bool wxNativeFontInfo::GetUnderlined() const +{ + return ((fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0); +} // end of wxNativeFontInfo::GetUnderlined + +wxString wxNativeFontInfo::GetFaceName() const +{ + return fm.szFacename; +} // end of wxNativeFontInfo::GetFaceName + +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 + +wxFontEncoding wxNativeFontInfo::GetEncoding() const +{ + return wxGetFontEncFromCharSet(fa.usCodePage); +} // end of wxNativeFontInfo::GetEncoding + +void wxNativeFontInfo::SetPointSize( + int nPointsize +) +{ + fm.lEmHeight = (LONG)nPointsize; +} // end of wxNativeFontInfo::SetPointSize + +void wxNativeFontInfo::SetStyle( + wxFontStyle eStyle +) +{ + switch (eStyle) + { + 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 + +void wxNativeFontInfo::SetWeight( + wxFontWeight eWeight +) +{ + switch (eWeight) + { + default: + wxFAIL_MSG( _T("unknown font weight") ); + // fall through + + case wxFONTWEIGHT_NORMAL: + fn.usWeightClass = FWEIGHT_NORMAL; + break; + + case wxFONTWEIGHT_LIGHT: + fn.usWeightClass = FWEIGHT_LIGHT; + break; + + 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 + +void wxNativeFontInfo::SetFaceName( + wxString sFacename +) +{ + wxStrncpy(fa.szFacename, sFacename, WXSIZEOF(fa.szFacename)); +} // end of wxNativeFontInfo::SetFaceName + +void wxNativeFontInfo::SetFamily( + wxFontFamily eFamily +) +{ + wxString sFacename; + + switch (eFamily) + { + case wxSCRIPT: + sFacename = wxT("Tms Rmn"); + break; + + case wxDECORATIVE: + sFacename = wxT("WarpSans"); + break; + + case wxROMAN: + sFacename = wxT("Tms Rmn"); + break; + + case wxTELETYPE: + sFacename = wxT("Courier") ; + break; + + case wxMODERN: + sFacename = wxT("System VIO") ; + break; + + case wxSWISS: + sFacename = wxT("Helv") ; + break; + + case wxDEFAULT: + default: + sFacename = wxT("System VIO") ; + } + + if (!wxStrlen(fa.szFacename) ) + { + SetFaceName(sFacename); + } +} // end of wxNativeFontInfo::SetFamily + +void wxNativeFontInfo::SetEncoding( + wxFontEncoding eEncoding +) +{ + wxNativeEncodingInfo vInfo; + + 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 = vInfo.charset; +} // end of wxNativeFontInfo::SetFaceName + +bool wxNativeFontInfo::FromString( + const wxString& rsStr +) +{ + 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(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 @@ -163,9 +868,30 @@ wxFontRefData::~wxFontRefData() void wxFont::Init() { - if ( wxTheFontList ) - wxTheFontList->Append(this); -} +} // end of wxFont::Init + +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 @@ -182,6 +908,15 @@ bool wxFont::Create( ) { 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) + { + nPointSize = wxNORMAL_FONT->GetPointSize(); + } m_refData = new wxFontRefData( nPointSize ,nFamily ,nStyle @@ -196,8 +931,6 @@ bool wxFont::Create( wxFont::~wxFont() { - if (wxTheFontList) - wxTheFontList->DeleteObject(this); } // end of wxFont::~wxFont // ---------------------------------------------------------------------------- @@ -209,179 +942,11 @@ wxFont::~wxFont() bool wxFont::RealizeResource() { - LONG lNumFonts = 0L; - LONG lTemp = 0L; - PFONTMETRICS pFM = NULL; - ERRORID vError; - 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")); - - return TRUE; - } - - LONG flId; - bool bInternalPS = FALSE; // if we have to create one - - // - // Now cheking - // - flId = 1L; - if (!M_FONTDATA->m_hPS) - { - M_FONTDATA->m_hPS = ::WinGetPS(HWND_DESKTOP); - bInternalPS = TRUE; - } - - if (M_FONTDATA->m_pFM) - { - delete [] M_FONTDATA->m_pFM; - M_FONTDATA->m_pFM = NULL; - } - // - // Determine the number of fonts. - // - lNumFonts = ::GpiQueryFonts( M_FONTDATA->m_hPS - ,QF_PUBLIC - ,NULL - ,&lTemp - ,(LONG) sizeof(FONTMETRICS) - ,NULL - ); - - // - // Allocate space for the font metrics. - // - pFM = new FONTMETRICS[lNumFonts + 1]; - - // - // Retrieve the font metrics. - // - lTemp = lNumFonts; - lTemp = ::GpiQueryFonts( M_FONTDATA->m_hPS - ,QF_PUBLIC - ,NULL - ,&lTemp - ,(LONG) sizeof(FONTMETRICS) - ,pFM - ); - SetFM( pFM - ,(int)lNumFonts - ); - - wxString sVals; - - for (int i = 0; i < lNumFonts; i++) - { - sVals << "Face: " <m_pFM[i].szFacename - << "Family: " <m_pFM[i].szFamilyname - << " PointSize: " << M_FONTDATA->m_pFM[i].lEmHeight - << " Height: " << M_FONTDATA->m_pFM[i].lXHeight - ; - sVals = ""; - } - M_FONTDATA->m_vFattrs.usRecordLength = sizeof(FATTRS); - M_FONTDATA->m_vFattrs.fsFontUse = FATTR_FONTUSE_OUTLINE | // only outline fonts allowed - FATTR_FONTUSE_TRANSFORMABLE; // may be transformed - M_FONTDATA->m_vFattrs.fsType = 0; - M_FONTDATA->m_vFattrs.lMaxBaselineExt = M_FONTDATA->m_vFattrs.lAveCharWidth = 0; - M_FONTDATA->m_vFattrs.idRegistry = 0; - M_FONTDATA->m_vFattrs.lMatch = 0; - - M_FONTDATA->m_vFname.usSize = sizeof(FACENAMEDESC); - M_FONTDATA->m_vFname.usWidthClass = FWIDTH_NORMAL; - M_FONTDATA->m_vFname.usReserved = 0; - M_FONTDATA->m_vFname.flOptions = 0; - - OS2SelectMatchingFontByName(); - - long lNumLids = ::GpiQueryNumberSetIds(M_FONTDATA->m_hPS); - long lGpiError; - - // - // First we should generate unique id - // - if(lNumLids ) - { - long alTypes[255]; - STR8 azNames[255]; - long alIds[255]; - - if(!::GpiQuerySetIds( M_FONTDATA->m_hPS - ,lNumLids - ,alTypes - ,azNames - ,alIds - )) - { - if (bInternalPS) - ::WinReleasePS(M_FONTDATA->m_hPS); - return 0; - } - - for(unsigned long LCNum = 0; LCNum < lNumLids; LCNum++) - if(alIds[LCNum] == flId) - ++flId; - if(flId > 254) // wow, no id available! - { - if (bInternalPS) - ::WinReleasePS(M_FONTDATA->m_hPS); - return 0; - } - } - - // - // Release and delete the current font - // - ::GpiSetCharSet(M_FONTDATA->m_hPS, LCID_DEFAULT);/* release the font before deleting */ - ::GpiDeleteSetId(M_FONTDATA->m_hPS, 1L); /* delete the logical font */ - - // - // Now build a facestring - // - char zFacename[128]; - strcpy(zFacename, M_FONTDATA->m_vFattrs.szFacename); - - if(::GpiQueryFaceString( M_FONTDATA->m_hPS - ,zFacename - ,&M_FONTDATA->m_vFname - ,FACESIZE - ,M_FONTDATA->m_vFattrs.szFacename - ) == GPI_ERROR) - { - vError = ::WinGetLastError(vHabmain); - } - - strcpy(zFacename, M_FONTDATA->m_vFattrs.szFacename); - - if(::GpiCreateLogFont( M_FONTDATA->m_hPS - ,NULL - ,flId - ,&M_FONTDATA->m_vFattrs - ) != GPI_ERROR) - M_FONTDATA->m_hFont = (WXHFONT)1; - - - if (bInternalPS) - { - if(M_FONTDATA->m_hFont) - ::GpiDeleteSetId( M_FONTDATA->m_hPS - ,flId - ); - - ::WinReleasePS(M_FONTDATA->m_hPS); - } - else - ::GpiSetCharSet(M_FONTDATA->m_hPS, flId); // sets font for presentation space - if (!M_FONTDATA->m_hFont) - { - wxLogLastError("CreateFont"); + return TRUE; } - M_FONTDATA->m_nFontId = flId; - return(M_FONTDATA->m_hFont != 0); + return M_FONTDATA->Alloc(this); } // end of wxFont::RealizeResource bool wxFont::FreeResource( @@ -390,10 +955,7 @@ bool wxFont::FreeResource( { if (GetResourceHandle()) { - M_FONTDATA->m_hFont = 0; - ::GpiDeleteSetId( M_FONTDATA->m_hPS - ,M_FONTDATA->m_nFontId - ); + M_FONTDATA->Free(); return TRUE; } return FALSE; @@ -401,15 +963,17 @@ bool 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() @@ -437,7 +1001,7 @@ void wxFont::SetPointSize( { Unshare(); - M_FONTDATA->m_nPointSize = nPointSize; + M_FONTDATA->SetPointSize(nPointSize); RealizeResource(); } // end of wxFont::SetPointSize @@ -448,7 +1012,7 @@ void wxFont::SetFamily( { Unshare(); - M_FONTDATA->m_nFamily = nFamily; + M_FONTDATA->SetFamily(nFamily); RealizeResource(); } // end of wxFont::SetFamily @@ -459,7 +1023,7 @@ void wxFont::SetStyle( { Unshare(); - M_FONTDATA->m_nStyle = nStyle; + M_FONTDATA->SetStyle(nStyle); RealizeResource(); } // end of wxFont::SetStyle @@ -470,7 +1034,7 @@ void wxFont::SetWeight( { Unshare(); - M_FONTDATA->m_nWeight = nWeight; + M_FONTDATA->SetWeight(nWeight); RealizeResource(); } // end of wxFont::SetWeight @@ -481,7 +1045,7 @@ void wxFont::SetFaceName( { Unshare(); - M_FONTDATA->m_sFaceName = rsFaceName; + M_FONTDATA->SetFaceName(rsFaceName); RealizeResource(); } // end of wxFont::SetFaceName @@ -492,7 +1056,7 @@ void wxFont::SetUnderlined( { Unshare(); - M_FONTDATA->m_bUnderlined = bUnderlined; + M_FONTDATA->SetUnderlined(bUnderlined); RealizeResource(); } // end of wxFont::SetUnderlined @@ -503,33 +1067,23 @@ void wxFont::SetEncoding( { Unshare(); - M_FONTDATA->m_vEncoding = vEncoding; + M_FONTDATA->SetEncoding(vEncoding); RealizeResource(); } // end of wxFont::SetEncoding -void wxFont::SetPS( - HPS hPS +void wxFont::DoSetNativeFontInfo( + const wxNativeFontInfo& rInfo ) { Unshare(); - M_FONTDATA->m_hPS = hPS; + FreeResource(); - RealizeResource(); -} // end of wxFont::SetPS + *M_FONTDATA = wxFontRefData(rInfo); -void wxFont::SetFM( - PFONTMETRICS pFM -, int nNumFonts -) -{ - // - // Don't realize the font with this one - // - M_FONTDATA->m_pFM = pFM; - M_FONTDATA->m_nNumFonts = nNumFonts; -} // end of wxFont::SetFM + RealizeResource(); +} // ---------------------------------------------------------------------------- // accessors @@ -537,253 +1091,80 @@ void wxFont::SetFM( int wxFont::GetPointSize() const { - wxFontRefData* pTmp; + wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); - pTmp = M_FONTDATA; - if(pTmp) - return pTmp->m_nPointSize; - else - return 10; + return M_FONTDATA->GetPointSize(); } // end of wxFont::GetPointSize int wxFont::GetFamily() const { - return M_FONTDATA->m_nFamily; -} // end of wxFont::GetFamily + wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); -int wxFont::GetFontId() const -{ - return M_FONTDATA->m_nFontId; -} // end of wxFont::GetFontId + return M_FONTDATA->GetFamily(); +} // end of wxFont::GetFamily int wxFont::GetStyle() const { - return M_FONTDATA->m_nStyle; + wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); + + return M_FONTDATA->GetStyle(); } // end of wxFont::GetStyle int wxFont::GetWeight() const { - return M_FONTDATA->m_nWeight; + wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); + + return M_FONTDATA->GetWeight(); } bool wxFont::GetUnderlined() const { - return M_FONTDATA->m_bUnderlined; + wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") ); + + return M_FONTDATA->GetUnderlined(); } // end of wxFont::GetUnderlined wxString wxFont::GetFaceName() const { - wxString sStr; + wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") ); - if ( M_FONTDATA ) - sStr = M_FONTDATA->m_sFaceName ; - return sStr; + return M_FONTDATA->GetFaceName(); } // end of wxFont::GetFaceName wxFontEncoding wxFont::GetEncoding() const { - return M_FONTDATA->m_vEncoding; -} // end of wxFont::GetEncoding - -HPS wxFont::GetPS() const -{ - return M_FONTDATA->m_hPS; -} // end of wxFont::GetPS - -void wxFont::OS2SelectMatchingFontByName() -{ - int i; - int nDiff0; - int nDiff; - int nIs; - int nIndex; - int nMinDiff; - int nMinDiff0; - int nApirc; - int anDiff[16]; - int anMinDiff[16]; - STR8 zFn; - char zFontFaceName[FACESIZE]; - wxString sFaceName; - USHORT usWeightClass; - int fsSelection = 0; - - nMinDiff0 = 0xf000; - for(i = 0;i < 16; i++) - anMinDiff[i] = nMinDiff0; - - switch (GetFamily()) - { - case wxSCRIPT: - sFaceName = wxT("Script"); - break; - - case wxDECORATIVE: - case wxROMAN: - sFaceName = wxT("Times New Roman"); - break; - - case wxTELETYPE: - case wxMODERN: - sFaceName = wxT("Courier") ; - break; - - case wxSWISS: - sFaceName = wxT("WarpSans") ; - break; - - case wxDEFAULT: - default: - sFaceName = wxT("Helv") ; - } - - switch (GetWeight()) - { - default: - wxFAIL_MSG(_T("unknown font weight")); - // fall through - usWeightClass = FWEIGHT_DONT_CARE; - break; - - case wxNORMAL: - usWeightClass = FWEIGHT_NORMAL; - break; + wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") ); - case wxLIGHT: - usWeightClass = FWEIGHT_LIGHT; - break; - - case wxBOLD: - usWeightClass = FWEIGHT_BOLD; - break; - - case wxFONTWEIGHT_MAX: - usWeightClass = FWEIGHT_ULTRA_BOLD; - break; - } - M_FONTDATA->m_vFname.usWeightClass = usWeightClass; - - switch (GetStyle()) - { - case wxITALIC: - case wxSLANT: - fsSelection = FM_SEL_ITALIC; - M_FONTDATA->m_vFname.flOptions = FTYPE_ITALIC; - break; - - default: - wxFAIL_MSG(wxT("unknown font slant")); - // fall through - - case wxNORMAL: - fsSelection = 0; - break; - } + return M_FONTDATA->GetEncoding(); +} // end of wxFont::GetEncoding - wxStrncpy(zFontFaceName, sFaceName.c_str(), WXSIZEOF(zFontFaceName)); - M_FONTDATA->m_nPointSize = GetPointSize(); - nIndex = 0; - for(i = 0, nIs = 0; i < M_FONTDATA->m_nNumFonts; i++) - { - // Debug code - int nPointSize = M_FONTDATA->m_nPointSize; - int nEmHeight = 0; - int nXHeight = 0; - anDiff[0] = wxGpiStrcmp(M_FONTDATA->m_pFM[i].szFamilyname, zFontFaceName); - anDiff[1] = abs(M_FONTDATA->m_pFM[i].lEmHeight - M_FONTDATA->m_nPointSize); - anDiff[2] = abs(M_FONTDATA->m_pFM[i].usWeightClass - usWeightClass); - anDiff[3] = abs((M_FONTDATA->m_pFM[i].fsSelection & 0x2f) - fsSelection); - if(anDiff[0] == 0) - { - nEmHeight = (int)M_FONTDATA->m_pFM[i].lEmHeight; - nXHeight =(int)M_FONTDATA->m_pFM[i].lXHeight; - if( (nIs & 0x01) == 0) - { - nIs = 1; - nIndex = i; - anMinDiff[1] = anDiff[1]; - anMinDiff[2] = anDiff[2]; - anMinDiff[3] = anDiff[3]; - } - else if(anDiff[3] < anMinDiff[3]) - { - nIndex = i; - anMinDiff[3] = anDiff[3]; - } - else if(anDiff[2] < anMinDiff[2]) - { - nIndex = i; - anMinDiff[2] = anDiff[2]; - } - else if(anDiff[1] < anMinDiff[1]) - { - nIndex = i; - anMinDiff[1] = anDiff[1]; - } - anMinDiff[0] = 0; - } - else if(anDiff[0] < anMinDiff[0]) - { - nIs = 2; - nIndex = i; - anMinDiff[3] = anDiff[3]; - anMinDiff[2] = anDiff[2]; - anMinDiff[1] = anDiff[1]; - anMinDiff[0] = anDiff[0]; - } - else if(anDiff[0] == anMinDiff[0]) - { - if(anDiff[3] < anMinDiff[3]) - { - nIndex = i; - anMinDiff[3] = anDiff[3]; - nIs = 2; - } - else if(anDiff[2] < anMinDiff[2]) - { - nIndex = i; - anMinDiff[2] = anDiff[2]; - nIs = 2; - } - else if(anDiff[1] < anMinDiff[1]) - { - nIndex = i; - anMinDiff[1] = anDiff[1]; - nIs = 2; - } - } - } +const wxNativeFontInfo* wxFont::GetNativeFontInfo() const +{ + return M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo()) + : NULL; +} // end of wxFont::GetNativeFontInfo - M_FONTDATA->m_vFattrs.usRecordLength = sizeof(FATTRS); // sets size of structure - M_FONTDATA->m_vFattrs.fsSelection = M_FONTDATA->m_pFM[nIndex].fsSelection; // uses default selection - M_FONTDATA->m_vFattrs.lMatch = M_FONTDATA->m_pFM[nIndex].lMatch; // force match - M_FONTDATA->m_vFattrs.idRegistry = M_FONTDATA->m_pFM[nIndex].idRegistry; // uses default registry - M_FONTDATA->m_vFattrs.usCodePage = M_FONTDATA->m_pFM[nIndex].usCodePage; // code-page - if(M_FONTDATA->m_pFM[nIndex].lMatch) - { - M_FONTDATA->m_vFattrs.lMaxBaselineExt = M_FONTDATA->m_pFM[nIndex].lMaxBaselineExt; // requested font height - M_FONTDATA->m_vFattrs.lAveCharWidth = M_FONTDATA->m_pFM[nIndex].lAveCharWidth ; // requested font width - } - else - { - M_FONTDATA->m_vFattrs.lMaxBaselineExt = 0; - M_FONTDATA->m_vFattrs.lAveCharWidth = 0; - } - M_FONTDATA->m_vFattrs.fsType = 0;// pfm->fsType; /* uses default type */ - M_FONTDATA->m_vFattrs.fsFontUse = 0; +// +// 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 - wxStrcpy(M_FONTDATA->m_vFattrs.szFacename, M_FONTDATA->m_pFM[nIndex].szFacename); - // Debug - strcpy(zFontFaceName, M_FONTDATA->m_pFM[nIndex].szFacename); - strcpy(zFontFaceName, M_FONTDATA->m_vFattrs.szFacename); - if(usWeightClass >= FWEIGHT_BOLD) - M_FONTDATA->m_vFattrs.fsSelection |= FATTR_SEL_BOLD; - if(GetUnderlined()) - M_FONTDATA->m_vFattrs.fsSelection |= FATTR_SEL_UNDERSCORE; - if(fsSelection & FM_SEL_ITALIC) - M_FONTDATA->m_vFattrs.fsSelection |= FATTR_SEL_ITALIC; -} +void wxFont::SetPS( + HPS hPS +) +{ + Unshare(); + M_FONTDATA->SetPS(hPS); + RealizeResource(); +} // end of wxFont::SetPS