This keyword is not expanded by Git which means it's not replaced with the correct revision value in the releases made using git-based scripts and it's confusing to have lines with unexpanded "$Id$" in the released files. As expanding them with Git is not that simple (it could be done with git archive and export-subst attribute) and there are not many benefits in having them in the first place, just remove all these lines. If nothing else, this will make an eventual transition to Git simpler. Closes #14487. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
1146 lines
31 KiB
C++
1146 lines
31 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/os2/font.cpp
|
|
// Purpose: wxFont class
|
|
// Author: David Webster
|
|
// Modified by:
|
|
// Created: 10/06/99
|
|
// Copyright: (c) David Webster
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
// ============================================================================
|
|
// declarations
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// headers
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#include "wx/font.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include <stdio.h>
|
|
#include "wx/list.h"
|
|
#include "wx/utils.h"
|
|
#include "wx/app.h"
|
|
#include "wx/log.h"
|
|
#endif // WX_PRECOMP
|
|
|
|
#include "wx/os2/private.h"
|
|
|
|
#include "wx/fontutil.h"
|
|
#include "wx/fontmap.h"
|
|
#include "wx/encinfo.h"
|
|
|
|
#include "wx/tokenzr.h"
|
|
|
|
#include <malloc.h>
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxFontRefData - the internal description of the font
|
|
// ----------------------------------------------------------------------------
|
|
|
|
class WXDLLEXPORT wxFontRefData: public wxGDIRefData
|
|
{
|
|
public:
|
|
wxFontRefData()
|
|
{
|
|
Init(-1, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false,
|
|
wxEmptyString, wxFONTENCODING_DEFAULT);
|
|
}
|
|
|
|
wxFontRefData( int nSize
|
|
,wxFontFamily nFamily
|
|
,wxFontStyle nStyle
|
|
,wxFontWeight nWeight
|
|
,bool bUnderlined
|
|
,const wxString& sFaceName
|
|
,wxFontEncoding 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 wxFontFamily GetFamily(void) const
|
|
{
|
|
return m_nFamily;
|
|
}
|
|
|
|
inline wxFontStyle GetStyle(void) const
|
|
{
|
|
return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetStyle()
|
|
: m_nStyle;
|
|
}
|
|
|
|
inline wxFontWeight GetWeight(void) const
|
|
{
|
|
return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetWeight()
|
|
: m_nWeight;
|
|
}
|
|
|
|
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(wxFontFamily nFamily)
|
|
{
|
|
m_nFamily = nFamily;
|
|
}
|
|
|
|
inline void SetStyle(wxFontStyle nStyle)
|
|
{
|
|
if (m_bNativeFontInfoOk)
|
|
m_vNativeFontInfo.SetStyle(nStyle);
|
|
else
|
|
m_nStyle = nStyle;
|
|
}
|
|
|
|
inline void SetWeight(wxFontWeight nWeight)
|
|
{
|
|
if (m_bNativeFontInfoOk)
|
|
m_vNativeFontInfo.SetWeight(nWeight);
|
|
else
|
|
m_nWeight = nWeight;
|
|
}
|
|
|
|
inline bool SetFaceName(const wxString& sFaceName)
|
|
{
|
|
if (m_bNativeFontInfoOk)
|
|
return m_vNativeFontInfo.SetFaceName(sFaceName);
|
|
else
|
|
m_sFaceName = sFaceName;
|
|
return true;
|
|
}
|
|
|
|
inline void SetUnderlined(bool bUnderlined)
|
|
{
|
|
if (m_bNativeFontInfoOk)
|
|
m_vNativeFontInfo.SetUnderlined(bUnderlined);
|
|
else
|
|
m_bUnderlined = bUnderlined;
|
|
}
|
|
|
|
inline void SetEncoding(wxFontEncoding vEncoding)
|
|
{
|
|
if (m_bNativeFontInfoOk)
|
|
m_vNativeFontInfo.SetEncoding(vEncoding);
|
|
else
|
|
m_vEncoding = vEncoding;
|
|
}
|
|
|
|
inline void SetPS(HPS hPS)
|
|
{
|
|
m_hPS = hPS;
|
|
}
|
|
|
|
inline void SetFM(PFONTMETRICS pFM)
|
|
{
|
|
m_pFM = pFM;
|
|
}
|
|
|
|
inline void SetNumFonts(int nNumFonts)
|
|
{
|
|
m_nNumFonts = nNumFonts;
|
|
}
|
|
|
|
//
|
|
// Native font info tests
|
|
//
|
|
bool HasNativeFontInfo() const { return m_bNativeFontInfoOk; }
|
|
|
|
const wxNativeFontInfo& GetNativeFontInfo() const
|
|
{ return m_vNativeFontInfo; }
|
|
|
|
protected:
|
|
//
|
|
// Common part of all ctors
|
|
//
|
|
void Init( int nSize
|
|
,wxFontFamily nFamily
|
|
,wxFontStyle nStyle
|
|
,wxFontWeight nWeight
|
|
,bool bUnderlined
|
|
,const wxString& rsFaceName
|
|
,wxFontEncoding vEncoding
|
|
);
|
|
|
|
void Init( const wxNativeFontInfo& rInfo
|
|
,WXHFONT hFont = 0
|
|
,WXHANDLE hPS = 0
|
|
);
|
|
//
|
|
// If true, the pointer to the actual font is temporary and SHOULD NOT BE
|
|
// DELETED by destructor
|
|
//
|
|
bool m_bTemporary;
|
|
int m_nFontId;
|
|
|
|
//
|
|
// Font characterstics
|
|
//
|
|
int m_nPointSize;
|
|
wxFontFamily m_nFamily;
|
|
wxFontStyle m_nStyle;
|
|
wxFontWeight m_nWeight;
|
|
bool m_bUnderlined;
|
|
wxString m_sFaceName;
|
|
wxFontEncoding m_vEncoding;
|
|
WXHFONT m_hFont;
|
|
|
|
//
|
|
// Native font info
|
|
//
|
|
wxNativeFontInfo m_vNativeFontInfo;
|
|
bool m_bNativeFontInfoOk;
|
|
|
|
//
|
|
// Some PM specific stuff
|
|
//
|
|
PFONTMETRICS m_pFM; // array of FONTMETRICS structs
|
|
int m_nNumFonts; // number of fonts in array
|
|
HPS m_hPS; // PS handle this font belongs to
|
|
FATTRS m_vFattrs; // Current fattrs struct
|
|
FACENAMEDESC m_vFname; // Current facename struct
|
|
bool m_bInternalPS; // Internally generated PS?
|
|
}; // end of CLASS wxFontRefData
|
|
|
|
#define M_FONTDATA ((wxFontRefData*)m_refData)
|
|
|
|
// ============================================================================
|
|
// implementation
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxFontRefData
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void wxFontRefData::Init(
|
|
int nPointSize
|
|
, wxFontFamily nFamily
|
|
, wxFontStyle nStyle
|
|
, wxFontWeight nWeight
|
|
, bool bUnderlined
|
|
, const wxString& rsFaceName
|
|
, wxFontEncoding vEncoding
|
|
)
|
|
{
|
|
m_nStyle = nStyle;
|
|
m_nPointSize = nPointSize;
|
|
m_nFamily = nFamily;
|
|
m_nStyle = nStyle;
|
|
m_nWeight = nWeight;
|
|
m_bUnderlined = bUnderlined;
|
|
m_sFaceName = rsFaceName;
|
|
m_vEncoding = vEncoding;
|
|
m_hFont = 0;
|
|
|
|
m_bNativeFontInfoOk = false;
|
|
|
|
m_nFontId = 0;
|
|
m_bTemporary = false;
|
|
m_pFM = (PFONTMETRICS)NULL;
|
|
m_hPS = NULLHANDLE;
|
|
m_nNumFonts = 0;
|
|
} // end of wxFontRefData::Init
|
|
|
|
void wxFontRefData::Init(
|
|
const wxNativeFontInfo& rInfo
|
|
, WXHFONT hFont //this is the FontId -- functions as the hFont for OS/2
|
|
, WXHANDLE hPS // Presentation Space we are using
|
|
)
|
|
{
|
|
//
|
|
// 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(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 = wxFONTFAMILY_ROMAN;
|
|
else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman MT 30") == 0)
|
|
m_nFamily = wxFONTFAMILY_ROMAN;
|
|
else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "@Times New Roman MT 30") == 0)
|
|
m_nFamily = wxFONTFAMILY_ROMAN;
|
|
else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Tms Rmn") == 0)
|
|
m_nFamily = wxFONTFAMILY_ROMAN;
|
|
else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "WarpSans") == 0)
|
|
m_nFamily = wxFONTFAMILY_DECORATIVE;
|
|
else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helvetica") == 0)
|
|
m_nFamily = wxFONTFAMILY_SWISS;
|
|
else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helv") == 0)
|
|
m_nFamily = wxFONTFAMILY_SWISS;
|
|
else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Script") == 0)
|
|
m_nFamily = wxFONTFAMILY_SCRIPT;
|
|
else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier New") == 0)
|
|
m_nFamily = wxFONTFAMILY_TELETYPE;
|
|
else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier") == 0)
|
|
m_nFamily = wxFONTFAMILY_TELETYPE;
|
|
else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Monospaced") == 0)
|
|
m_nFamily = wxFONTFAMILY_TELETYPE;
|
|
else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System VIO") == 0)
|
|
m_nFamily = wxFONTFAMILY_MODERN;
|
|
else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Proportional") == 0)
|
|
m_nFamily = wxFONTFAMILY_MODERN;
|
|
else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Arial") == 0)
|
|
m_nFamily = wxFONTFAMILY_SWISS;
|
|
else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Swiss") == 0)
|
|
m_nFamily = wxFONTFAMILY_SWISS;
|
|
else
|
|
m_nFamily = wxFONTFAMILY_SWISS;
|
|
|
|
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 = (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
|
|
);
|
|
|
|
::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 (wxChar*)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 = wxFONTFAMILY_ROMAN;
|
|
else if (strcmp(fm.szFamilyname, "Times New Roman MT 30") == 0)
|
|
nFamily = wxFONTFAMILY_ROMAN;
|
|
else if (strcmp(fm.szFamilyname, "@Times New Roman MT 30") == 0)
|
|
nFamily = wxFONTFAMILY_ROMAN;
|
|
else if (strcmp(fm.szFamilyname, "Tms Rmn") == 0)
|
|
nFamily = wxFONTFAMILY_ROMAN;
|
|
else if (strcmp(fm.szFamilyname, "WarpSans") == 0)
|
|
nFamily = wxFONTFAMILY_DECORATIVE;
|
|
else if (strcmp(fm.szFamilyname, "Helvetica") == 0)
|
|
nFamily = wxFONTFAMILY_SWISS;
|
|
else if (strcmp(fm.szFamilyname, "Helv") == 0)
|
|
nFamily = wxFONTFAMILY_SWISS;
|
|
else if (strcmp(fm.szFamilyname, "Script") == 0)
|
|
nFamily = wxFONTFAMILY_SCRIPT;
|
|
else if (strcmp(fm.szFamilyname, "Courier New") == 0)
|
|
nFamily = wxFONTFAMILY_TELETYPE;
|
|
else if (strcmp(fm.szFamilyname, "Courier") == 0)
|
|
nFamily = wxFONTFAMILY_TELETYPE;
|
|
else if (strcmp(fm.szFamilyname, "System Monospaced") == 0)
|
|
nFamily = wxFONTFAMILY_TELETYPE;
|
|
else if (strcmp(fm.szFamilyname, "System VIO") == 0)
|
|
nFamily = wxFONTFAMILY_MODERN;
|
|
else if (strcmp(fm.szFamilyname, "System Proportional") == 0)
|
|
nFamily = wxFONTFAMILY_MODERN;
|
|
else if (strcmp(fm.szFamilyname, "Arial") == 0)
|
|
nFamily = wxFONTFAMILY_SWISS;
|
|
else if (strcmp(fm.szFamilyname, "Swiss") == 0)
|
|
nFamily = wxFONTFAMILY_SWISS;
|
|
else
|
|
nFamily = wxFONTFAMILY_SWISS;
|
|
return (wxFontFamily)nFamily;
|
|
} // end of wxNativeFontInfo::GetFamily
|
|
|
|
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( wxT("unknown font style") );
|
|
// fall through
|
|
|
|
case wxFONTSTYLE_NORMAL:
|
|
break;
|
|
|
|
case wxFONTSTYLE_ITALIC:
|
|
case wxFONTSTYLE_SLANT:
|
|
fa.fsSelection |= FATTR_SEL_ITALIC;
|
|
break;
|
|
}
|
|
} // end of wxNativeFontInfo::SetStyle
|
|
|
|
void wxNativeFontInfo::SetWeight(
|
|
wxFontWeight eWeight
|
|
)
|
|
{
|
|
switch (eWeight)
|
|
{
|
|
default:
|
|
wxFAIL_MSG( wxT("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
|
|
|
|
bool wxNativeFontInfo::SetFaceName(
|
|
const wxString& sFacename
|
|
)
|
|
{
|
|
wxStrlcpy((wxChar*)fa.szFacename, sFacename, WXSIZEOF(fa.szFacename));
|
|
return true;
|
|
} // end of wxNativeFontInfo::SetFaceName
|
|
|
|
void wxNativeFontInfo::SetFamily(
|
|
wxFontFamily eFamily
|
|
)
|
|
{
|
|
wxString sFacename;
|
|
|
|
switch (eFamily)
|
|
{
|
|
case wxFONTFAMILY_SCRIPT:
|
|
sFacename = wxT("Tms Rmn");
|
|
break;
|
|
|
|
case wxFONTFAMILY_DECORATIVE:
|
|
sFacename = wxT("WarpSans");
|
|
break;
|
|
|
|
case wxFONTFAMILY_ROMAN:
|
|
sFacename = wxT("Tms Rmn");
|
|
break;
|
|
|
|
case wxFONTFAMILY_TELETYPE:
|
|
sFacename = wxT("Courier") ;
|
|
break;
|
|
|
|
case wxFONTFAMILY_MODERN:
|
|
sFacename = wxT("System VIO") ;
|
|
break;
|
|
|
|
case wxFONTFAMILY_SWISS:
|
|
sFacename = wxT("Helv") ;
|
|
break;
|
|
|
|
case wxFONTFAMILY_DEFAULT:
|
|
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 (!vInfo.facename.empty())
|
|
{
|
|
//
|
|
// If we have this encoding only in some particular facename, use
|
|
// the facename - it is better to show the correct characters in a
|
|
// wrong facename than unreadable text in a correct one
|
|
//
|
|
SetFaceName(vInfo.facename);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// unsupported encoding, replace with the default
|
|
vInfo.charset = 850;
|
|
}
|
|
}
|
|
fa.usCodePage = (USHORT)vInfo.charset;
|
|
} // end of wxNativeFontInfo::SetFaceName
|
|
|
|
bool wxNativeFontInfo::FromString( const wxString& rsStr )
|
|
{
|
|
long lVal;
|
|
|
|
wxStringTokenizer vTokenizer(rsStr, wxT(";"));
|
|
|
|
//
|
|
// First the version
|
|
//
|
|
wxString sToken = vTokenizer.GetNextToken();
|
|
|
|
if (sToken != wxT('0'))
|
|
return false;
|
|
|
|
sToken = vTokenizer.GetNextToken();
|
|
if (!sToken.ToLong(&lVal))
|
|
return false;
|
|
fm.lEmHeight = lVal;
|
|
|
|
sToken = vTokenizer.GetNextToken();
|
|
if (!sToken.ToLong(&lVal))
|
|
return false;
|
|
fa.lAveCharWidth = lVal;
|
|
|
|
sToken = vTokenizer.GetNextToken();
|
|
if (!sToken.ToLong(&lVal))
|
|
return false;
|
|
fa.fsSelection = (USHORT)lVal;
|
|
|
|
sToken = vTokenizer.GetNextToken();
|
|
if (!sToken.ToLong(&lVal))
|
|
return false;
|
|
fa.fsType = (USHORT)lVal;
|
|
|
|
sToken = vTokenizer.GetNextToken();
|
|
if (!sToken.ToLong(&lVal))
|
|
return false;
|
|
fa.fsFontUse = (USHORT)lVal;
|
|
|
|
sToken = vTokenizer.GetNextToken();
|
|
if (!sToken.ToLong(&lVal))
|
|
return false;
|
|
fa.idRegistry = (USHORT)lVal;
|
|
|
|
sToken = vTokenizer.GetNextToken();
|
|
if (!sToken.ToLong(&lVal))
|
|
return false;
|
|
fa.usCodePage = (USHORT)lVal;
|
|
|
|
sToken = vTokenizer.GetNextToken();
|
|
if (!sToken.ToLong(&lVal))
|
|
return false;
|
|
fa.lMatch = lVal;
|
|
|
|
sToken = vTokenizer.GetNextToken();
|
|
if (!sToken.ToLong(&lVal))
|
|
return false;
|
|
fn.usWeightClass = (USHORT)lVal;
|
|
|
|
sToken = vTokenizer.GetNextToken();
|
|
if(!sToken)
|
|
return false;
|
|
wxStrcpy((wxChar*)fa.szFacename, sToken.c_str());
|
|
return true;
|
|
} // end of wxNativeFontInfo::FromString
|
|
|
|
wxString wxNativeFontInfo::ToString() const
|
|
{
|
|
wxString sStr;
|
|
|
|
sStr.Printf(wxT("%d;%ld;%ld;%ld;%d;%d;%d;%d;%d;%ld;%d;%s"),
|
|
0, // version, in case we want to change the format later
|
|
fm.lEmHeight,
|
|
fa.lAveCharWidth,
|
|
fa.lMaxBaselineExt,
|
|
fa.fsSelection,
|
|
fa.fsType,
|
|
fa.fsFontUse,
|
|
fa.idRegistry,
|
|
fa.usCodePage,
|
|
fa.lMatch,
|
|
fn.usWeightClass,
|
|
(char *)fa.szFacename);
|
|
return sStr;
|
|
} // end of wxNativeFontInfo::ToString
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxFont
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool wxFont::Create( const wxNativeFontInfo& rInfo,
|
|
WXHFONT hFont )
|
|
{
|
|
UnRef();
|
|
m_refData = new wxFontRefData( rInfo
|
|
,hFont
|
|
);
|
|
RealizeResource();
|
|
return true;
|
|
} // end of wxFont::Create
|
|
|
|
wxFont::wxFont(
|
|
const wxString& rsFontdesc
|
|
)
|
|
{
|
|
wxNativeFontInfo vInfo;
|
|
|
|
if (vInfo.FromString(rsFontdesc))
|
|
(void)Create(vInfo);
|
|
} // end of wxFont::wxFont
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Constructor for a font. Note that the real construction is done
|
|
// in wxDC::SetFont, when information is available about scaling etc.
|
|
// ----------------------------------------------------------------------------
|
|
bool wxFont::Create( int nPointSize,
|
|
wxFontFamily nFamily,
|
|
wxFontStyle nStyle,
|
|
wxFontWeight nWeight,
|
|
bool bUnderlined,
|
|
const wxString& rsFaceName,
|
|
wxFontEncoding vEncoding )
|
|
{
|
|
UnRef();
|
|
|
|
//
|
|
// 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
|
|
,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 cannot create the font
|
|
// here, but we may check that font definition is true
|
|
// ----------------------------------------------------------------------------
|
|
|
|
wxGDIRefData *wxFont::CreateGDIRefData() const
|
|
{
|
|
return new wxFontRefData();
|
|
}
|
|
|
|
wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
|
|
{
|
|
return new wxFontRefData(*static_cast<const wxFontRefData *>(data));
|
|
}
|
|
|
|
bool wxFont::RealizeResource()
|
|
{
|
|
if ( GetResourceHandle() )
|
|
{
|
|
return true;
|
|
}
|
|
return M_FONTDATA->Alloc(this);
|
|
} // end of wxFont::RealizeResource
|
|
|
|
bool wxFont::FreeResource( bool WXUNUSED(bForce) )
|
|
{
|
|
if (GetResourceHandle())
|
|
{
|
|
M_FONTDATA->Free();
|
|
return true;
|
|
}
|
|
return false;
|
|
} // end of wxFont::FreeResource
|
|
|
|
WXHANDLE wxFont::GetResourceHandle() const
|
|
{
|
|
return GetHFONT();
|
|
} // end of wxFont::GetResourceHandle
|
|
|
|
WXHFONT wxFont::GetHFONT() const
|
|
{
|
|
return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
|
|
} // end of wxFont::GetHFONT
|
|
|
|
bool wxFont::IsFree() const
|
|
{
|
|
return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0);
|
|
} // end of wxFont::IsFree
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// change font attribute: we recreate font when doing it
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void wxFont::SetPointSize(
|
|
int nPointSize
|
|
)
|
|
{
|
|
AllocExclusive();
|
|
|
|
M_FONTDATA->SetPointSize(nPointSize);
|
|
|
|
RealizeResource();
|
|
} // end of wxFont::SetPointSize
|
|
|
|
void wxFont::SetFamily(
|
|
wxFontFamily nFamily
|
|
)
|
|
{
|
|
AllocExclusive();
|
|
|
|
M_FONTDATA->SetFamily(nFamily);
|
|
|
|
RealizeResource();
|
|
} // end of wxFont::SetFamily
|
|
|
|
void wxFont::SetStyle(
|
|
wxFontStyle nStyle
|
|
)
|
|
{
|
|
AllocExclusive();
|
|
|
|
M_FONTDATA->SetStyle(nStyle);
|
|
|
|
RealizeResource();
|
|
} // end of wxFont::SetStyle
|
|
|
|
void wxFont::SetWeight(
|
|
wxFontWeight nWeight
|
|
)
|
|
{
|
|
AllocExclusive();
|
|
|
|
M_FONTDATA->SetWeight(nWeight);
|
|
|
|
RealizeResource();
|
|
} // end of wxFont::SetWeight
|
|
|
|
bool wxFont::SetFaceName(
|
|
const wxString& rsFaceName
|
|
)
|
|
{
|
|
AllocExclusive();
|
|
|
|
bool refdataok = M_FONTDATA->SetFaceName(rsFaceName);
|
|
|
|
RealizeResource();
|
|
|
|
return refdataok && wxFontBase::SetFaceName(rsFaceName);
|
|
} // end of wxFont::SetFaceName
|
|
|
|
void wxFont::SetUnderlined(
|
|
bool bUnderlined
|
|
)
|
|
{
|
|
AllocExclusive();
|
|
|
|
M_FONTDATA->SetUnderlined(bUnderlined);
|
|
|
|
RealizeResource();
|
|
} // end of wxFont::SetUnderlined
|
|
|
|
void wxFont::SetEncoding(
|
|
wxFontEncoding vEncoding
|
|
)
|
|
{
|
|
AllocExclusive();
|
|
|
|
M_FONTDATA->SetEncoding(vEncoding);
|
|
|
|
RealizeResource();
|
|
} // end of wxFont::SetEncoding
|
|
|
|
void wxFont::DoSetNativeFontInfo(
|
|
const wxNativeFontInfo& rInfo
|
|
)
|
|
{
|
|
AllocExclusive();
|
|
|
|
FreeResource();
|
|
|
|
*M_FONTDATA = wxFontRefData(rInfo);
|
|
|
|
RealizeResource();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// accessors
|
|
// ----------------------------------------------------------------------------
|
|
|
|
int wxFont::GetPointSize() const
|
|
{
|
|
wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
|
|
|
|
return M_FONTDATA->GetPointSize();
|
|
} // end of wxFont::GetPointSize
|
|
|
|
wxFontFamily wxFont::DoGetFamily() const
|
|
{
|
|
return M_FONTDATA->GetFamily();
|
|
} // end of wxFont::DoGetFamily
|
|
|
|
wxFontStyle wxFont::GetStyle() const
|
|
{
|
|
wxCHECK_MSG( IsOk(), wxFONTSTYLE_MAX, wxT("invalid font") );
|
|
|
|
return M_FONTDATA->GetStyle();
|
|
} // end of wxFont::GetStyle
|
|
|
|
wxFontWeight wxFont::GetWeight() const
|
|
{
|
|
wxCHECK_MSG( IsOk(), wxFONTWEIGHT_MAX, wxT("invalid font") );
|
|
|
|
return M_FONTDATA->GetWeight();
|
|
}
|
|
|
|
bool wxFont::GetUnderlined() const
|
|
{
|
|
wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
|
|
|
|
return M_FONTDATA->GetUnderlined();
|
|
} // end of wxFont::GetUnderlined
|
|
|
|
wxString wxFont::GetFaceName() const
|
|
{
|
|
wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
|
|
|
|
return M_FONTDATA->GetFaceName();
|
|
} // end of wxFont::GetFaceName
|
|
|
|
wxFontEncoding wxFont::GetEncoding() const
|
|
{
|
|
wxCHECK_MSG( IsOk(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
|
|
|
|
return M_FONTDATA->GetEncoding();
|
|
} // end of wxFont::GetEncoding
|
|
|
|
const wxNativeFontInfo* wxFont::GetNativeFontInfo() const
|
|
{
|
|
return M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
|
|
: NULL;
|
|
} // end of wxFont::GetNativeFontInfo
|
|
|
|
//
|
|
// Internal use only method to set the FONTMETRICS array
|
|
//
|
|
void wxFont::SetFM( PFONTMETRICS pFM, int nNumFonts )
|
|
{
|
|
M_FONTDATA->SetFM(pFM);
|
|
M_FONTDATA->SetNumFonts(nNumFonts);
|
|
} // end of wxFont::SetFM
|
|
|
|
|
|
void wxFont::SetPS( HPS hPS )
|
|
{
|
|
AllocExclusive();
|
|
|
|
M_FONTDATA->SetPS(hPS);
|
|
|
|
RealizeResource();
|
|
} // end of wxFont::SetPS
|