X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/987da0d4116e93c1d326b29272c28ee9f989b87c..d949570b6673dadd764686213afb89bddb6f19da:/src/os2/font.cpp diff --git a/src/os2/font.cpp b/src/os2/font.cpp index d33d991d89..4ed240007c 100644 --- a/src/os2/font.cpp +++ b/src/os2/font.cpp @@ -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 // ============================================================================ @@ -17,26 +20,27 @@ // headers // ---------------------------------------------------------------------------- - #include -// For compilers that support precompilation, includes "wx.h". -#include "wx/wxprec.h" +#include "wx/font.h" #ifndef WX_PRECOMP #include - #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 + +IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject) // ---------------------------------------------------------------------------- // wxFontRefData - the internal description of the font @@ -44,21 +48,11 @@ IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject) class WXDLLEXPORT wxFontRefData: public wxGDIRefData { -friend class WXDLLEXPORT wxFont; - public: wxFontRefData() { - Init(12, wxDEFAULT, wxNORMAL, wxNORMAL, 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; + Init(-1, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, + wxEmptyString, wxFONTENCODING_DEFAULT); } wxFontRefData( int nSize @@ -70,13 +64,190 @@ 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 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 + // + // Common part of all ctors + // void Init( int nSize ,int nFamily ,int nStyle @@ -86,8 +257,12 @@ 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 + // If true, the pointer to the actual font is temporary and SHOULD NOT BE // DELETED by destructor // bool m_bTemporary; @@ -103,18 +278,27 @@ 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 +#define M_FONTDATA ((wxFontRefData*)m_refData) + // ============================================================================ // implementation // ============================================================================ @@ -141,295 +325,644 @@ void wxFontRefData::Init( m_bUnderlined = bUnderlined; m_sFaceName = rsFaceName; m_vEncoding = vEncoding; - m_nFontId = 0; - m_bTemporary = FALSE; - 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 +) +{ + // + // 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() { - if (m_pFM) - delete [] m_pFM; - m_pFM = (PFONTMETRICS)NULL; + Free(); } -// ---------------------------------------------------------------------------- -// wxFont -// ---------------------------------------------------------------------------- +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(wxT("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; -wxFont::wxFont(const wxNativeFontInfo& rInfo) + if (m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_ITALIC) + m_nStyle = wxFONTSTYLE_ITALIC; + else + m_nStyle = wxFONTSTYLE_NORMAL; + switch(m_vNativeFontInfo.fn.usWeightClass) { - Init(); + 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; - (void)Create( rInfo.pointSize - ,rInfo.family - ,rInfo.style - ,rInfo.weight - ,rInfo.underlined - ,rInfo.faceName - ,rInfo.encoding - ); + 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 = (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) + { + if(m_hFont) + ::GpiDeleteSetId( m_hPS + ,flId + ); -void wxFont::Init() + ::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 ( wxTheFontList ) - wxTheFontList->Append(this); -} + 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 // ---------------------------------------------------------------------------- -// Constructor for a font. Note that the real construction is done -// in wxDC::SetFont, when information is available about scaling etc. +// wxNativeFontInfo // ---------------------------------------------------------------------------- -bool wxFont::Create( - int nPointSize -, int nFamily -, int nStyle -, int nWeight -, bool bUnderlined -, const wxString& rsFaceName -, wxFontEncoding vEncoding -) -{ - UnRef(); - m_refData = new wxFontRefData( nPointSize - ,nFamily - ,nStyle - ,nWeight - ,bUnderlined - ,rsFaceName - ,vEncoding - ); - RealizeResource(); - return TRUE; -} // end of wxFont::Create -wxFont::~wxFont() +void wxNativeFontInfo::Init() { - if (wxTheFontList) - wxTheFontList->DeleteObject(this); -} // end of wxFont::~wxFont + memset(&fa, '\0', sizeof(FATTRS)); +} // end of wxNativeFontInfo::Init -// ---------------------------------------------------------------------------- -// 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 -// ---------------------------------------------------------------------------- +int wxNativeFontInfo::GetPointSize() const +{ + return fm.lEmHeight; +} // end of wxNativeFontInfo::GetPointSize -bool wxFont::RealizeResource() +wxFontStyle wxNativeFontInfo::GetStyle() const { - LONG lNumFonts = 0L; - LONG lTemp = 0L; - PFONTMETRICS pFM = NULL; - ERRORID vError; + return fa.fsSelection & FATTR_SEL_ITALIC ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL; +} // end of wxNativeFontInfo::GetStyle - if ( GetResourceHandle() ) +wxFontWeight wxNativeFontInfo::GetWeight() const +{ + switch(fn.usWeightClass) { - // 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")); + case FWEIGHT_DONT_CARE: + return wxFONTWEIGHT_NORMAL; + + case FWEIGHT_NORMAL: + return wxFONTWEIGHT_NORMAL; + + case FWEIGHT_LIGHT: + return wxFONTWEIGHT_LIGHT; - return TRUE; + 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 - LONG flId; - bool bInternalPS = FALSE; // if we have to create one +wxString wxNativeFontInfo::GetFaceName() const +{ + return (wxChar*)fm.szFacename; +} // end of wxNativeFontInfo::GetFaceName + +wxFontFamily wxNativeFontInfo::GetFamily() const +{ + int nFamily; // - // Now cheking + // Extract family from facename // - flId = 1L; - if (!M_FONTDATA->m_hPS) + 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) { - M_FONTDATA->m_hPS = ::WinGetPS(HWND_DESKTOP); - bInternalPS = TRUE; + 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 - if (M_FONTDATA->m_pFM) +void wxNativeFontInfo::SetWeight( + wxFontWeight eWeight +) +{ + switch (eWeight) { - delete [] M_FONTDATA->m_pFM; - M_FONTDATA->m_pFM = NULL; + 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; } - // - // Determine the number of fonts. - // - lNumFonts = ::GpiQueryFonts( M_FONTDATA->m_hPS - ,QF_PUBLIC - ,NULL - ,&lTemp - ,(LONG) sizeof(FONTMETRICS) - ,NULL - ); +} // end of wxNativeFontInfo::SetWeight - // - // Allocate space for the font metrics. - // - pFM = new FONTMETRICS[lNumFonts + 1]; +void wxNativeFontInfo::SetUnderlined( + bool bUnderlined +) +{ + if(bUnderlined) + fa.fsSelection |= FATTR_SEL_UNDERSCORE; +} // end of wxNativeFontInfo::SetUnderlined - // - // 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; +bool wxNativeFontInfo::SetFaceName( + const wxString& sFacename +) +{ + wxStrncpy((wxChar*)fa.szFacename, sFacename, WXSIZEOF(fa.szFacename)); + return true; +} // end of wxNativeFontInfo::SetFaceName - // - // 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 - )) +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((wxChar*)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 (bInternalPS) - ::WinReleasePS(M_FONTDATA->m_hPS); - return 0; + 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); + } } - - for(unsigned long LCNum = 0; LCNum < lNumLids; LCNum++) - if(alIds[LCNum] == flId) - ++flId; - if(flId > 254) // wow, no id available! + else { - if (bInternalPS) - ::WinReleasePS(M_FONTDATA->m_hPS); - return 0; + // unsupported encoding, replace with the default + vInfo.charset = 850; } } + fa.usCodePage = (USHORT)vInfo.charset; +} // end of wxNativeFontInfo::SetFaceName - // - // 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 */ +bool wxNativeFontInfo::FromString( const wxString& rsStr ) +{ + long lVal; + + wxStringTokenizer vTokenizer(rsStr, _T(";")); // - // Now build a facestring + // First the version // - char zFacename[128]; - strcpy(zFacename, M_FONTDATA->m_vFattrs.szFacename); + 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, + (char *)fa.szFacename); + return sStr; +} // end of wxNativeFontInfo::ToString - if(::GpiQueryFaceString( M_FONTDATA->m_hPS - ,zFacename - ,&M_FONTDATA->m_vFname - ,FACESIZE - ,M_FONTDATA->m_vFattrs.szFacename - ) == GPI_ERROR) - { - vError = ::WinGetLastError(vHabmain); - } +// ---------------------------------------------------------------------------- +// wxFont +// ---------------------------------------------------------------------------- - M_FONTDATA->m_sFaceName = zFacename; +bool wxFont::Create( const wxNativeFontInfo& rInfo, + WXHFONT hFont ) +{ + UnRef(); + m_refData = new wxFontRefData( rInfo + ,hFont + ); + RealizeResource(); + return true; +} // end of wxFont::Create - if(::GpiCreateLogFont( M_FONTDATA->m_hPS - ,NULL - ,flId - ,&M_FONTDATA->m_vFattrs - ) != GPI_ERROR) - M_FONTDATA->m_hFont = (WXHFONT)1; +wxFont::wxFont( + const wxString& rsFontdesc +) +{ + wxNativeFontInfo vInfo; + if (vInfo.FromString(rsFontdesc)) + (void)Create(vInfo); +} // end of wxFont::wxFont - if (bInternalPS) - { - if(M_FONTDATA->m_hFont) - ::GpiDeleteSetId( M_FONTDATA->m_hPS - ,flId - ); +// ---------------------------------------------------------------------------- +// 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(); - ::WinReleasePS(M_FONTDATA->m_hPS); + // + // 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(); } - else - ::GpiSetCharSet(M_FONTDATA->m_hPS, flId); // sets font for presentation space - if (!M_FONTDATA->m_hFont) + m_refData = new wxFontRefData( nPointSize + ,nFamily + ,nStyle + ,nWeight + ,bUnderlined + ,rsFaceName + ,vEncoding + ); + RealizeResource(); + return true; +} // end of wxFont::Create + +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 +// ---------------------------------------------------------------------------- + +bool wxFont::RealizeResource() +{ + if ( GetResourceHandle() ) { - 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( - bool bForce -) +bool wxFont::FreeResource( bool WXUNUSED(bForce) ) { if (GetResourceHandle()) { - M_FONTDATA->m_hFont = 0; - ::GpiDeleteSetId( M_FONTDATA->m_hPS - ,M_FONTDATA->m_nFontId - ); - return TRUE; + M_FONTDATA->Free(); + return true; } - return FALSE; + return false; } // end of wxFont::FreeResource -WXHANDLE wxFont::GetHFONT() const -{ - if (!M_FONTDATA) - return 0; - else - return (WXHANDLE)M_FONTDATA->m_hFont; -} // end of wxFont::GetHFONT - -WXHANDLE wxFont::GetResourceHandle() +WXHANDLE wxFont::GetResourceHandle() const { return GetHFONT(); } // end of wxFont::GetResourceHandle +WXHFONT wxFont::GetHFONT() const +{ + return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0; +} // end of wxFont::GetHFONT + bool wxFont::IsFree() const { - return (M_FONTDATA && (M_FONTDATA->m_hFont == 0)); + return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0); } // end of wxFont::IsFree void wxFont::Unshare() @@ -457,7 +990,7 @@ void wxFont::SetPointSize( { Unshare(); - M_FONTDATA->m_nPointSize = nPointSize; + M_FONTDATA->SetPointSize(nPointSize); RealizeResource(); } // end of wxFont::SetPointSize @@ -468,7 +1001,7 @@ void wxFont::SetFamily( { Unshare(); - M_FONTDATA->m_nFamily = nFamily; + M_FONTDATA->SetFamily(nFamily); RealizeResource(); } // end of wxFont::SetFamily @@ -479,7 +1012,7 @@ void wxFont::SetStyle( { Unshare(); - M_FONTDATA->m_nStyle = nStyle; + M_FONTDATA->SetStyle(nStyle); RealizeResource(); } // end of wxFont::SetStyle @@ -490,20 +1023,22 @@ void wxFont::SetWeight( { Unshare(); - M_FONTDATA->m_nWeight = nWeight; + M_FONTDATA->SetWeight(nWeight); RealizeResource(); } // end of wxFont::SetWeight -void wxFont::SetFaceName( +bool wxFont::SetFaceName( const wxString& rsFaceName ) { Unshare(); - M_FONTDATA->m_sFaceName = rsFaceName; + bool refdataok = M_FONTDATA->SetFaceName(rsFaceName); RealizeResource(); + + return refdataok && wxFontBase::SetFaceName(rsFaceName); } // end of wxFont::SetFaceName void wxFont::SetUnderlined( @@ -512,7 +1047,7 @@ void wxFont::SetUnderlined( { Unshare(); - M_FONTDATA->m_bUnderlined = bUnderlined; + M_FONTDATA->SetUnderlined(bUnderlined); RealizeResource(); } // end of wxFont::SetUnderlined @@ -523,33 +1058,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 @@ -557,253 +1082,74 @@ 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(), wxEmptyString, 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") ; - } + wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") ); - switch (GetWeight()) - { - default: - wxFAIL_MSG(_T("unknown font weight")); - // fall through - usWeightClass = FWEIGHT_DONT_CARE; - break; - - case wxNORMAL: - usWeightClass = FWEIGHT_NORMAL; - break; - - 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; - } - - 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; - } - } - } - - 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; + return M_FONTDATA->GetEncoding(); +} // end of wxFont::GetEncoding - 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); +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 - 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