2008-12-08 05:17:03 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Name: src/common/fontmgrcmn.cpp
|
|
|
|
// Purpose: font management for ports that don't have their own
|
|
|
|
// Author: Vaclav Slavik
|
|
|
|
// Created: 2006-11-18
|
|
|
|
// RCS-ID: $Id: fontmgrcmn.cpp 43550 2006-11-20 20:45:57Z VS $
|
|
|
|
// Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com)
|
|
|
|
// (c) 2006 REA Elektronik GmbH
|
|
|
|
// Licence: wxWindows licence
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
|
|
#include "wx/wxprec.h"
|
|
|
|
|
|
|
|
#ifdef __BORLANDC__
|
|
|
|
#pragma hdrstop
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "wx/private/fontmgr.h"
|
|
|
|
|
|
|
|
#include "wx/listimpl.cpp"
|
|
|
|
#include "wx/hashmap.h"
|
|
|
|
|
|
|
|
WX_DECLARE_LIST(wxFontInstance, wxFontInstanceList);
|
|
|
|
WX_DEFINE_LIST(wxFontInstanceList)
|
|
|
|
WX_DEFINE_LIST(wxFontBundleList)
|
|
|
|
WX_DECLARE_HASH_MAP(wxString, wxFontBundle*,
|
|
|
|
wxStringHash, wxStringEqual,
|
|
|
|
wxFontBundleHash);
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
// implementation
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// wxFontFaceBase
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
wxFontFaceBase::wxFontFaceBase()
|
|
|
|
: m_refCnt(0)
|
|
|
|
{
|
|
|
|
m_instances = new wxFontInstanceList;
|
|
|
|
m_instances->DeleteContents(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
wxFontFaceBase::~wxFontFaceBase()
|
|
|
|
{
|
|
|
|
delete m_instances;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxFontFaceBase::Acquire()
|
|
|
|
{
|
|
|
|
m_refCnt++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxFontFaceBase::Release()
|
|
|
|
{
|
|
|
|
if ( --m_refCnt == 0 )
|
|
|
|
{
|
|
|
|
m_instances->Clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
wxFontInstance *wxFontFaceBase::GetFontInstance(float ptSize, bool aa)
|
|
|
|
{
|
|
|
|
wxASSERT_MSG( m_refCnt > 0, _T("font library not loaded!") );
|
|
|
|
|
|
|
|
wxFontInstance *i;
|
|
|
|
wxFontInstanceList::Node *node;
|
|
|
|
|
|
|
|
for ( node = m_instances->GetFirst(); node; node = node->GetNext() )
|
|
|
|
{
|
|
|
|
i = node->GetData();
|
|
|
|
if ( i->GetPointSize() == ptSize && i->IsAntiAliased() == aa )
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
i = CreateFontInstance(ptSize, aa);
|
|
|
|
m_instances->Append(i);
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// wxFontBundleBase
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
wxFontBundleBase::wxFontBundleBase()
|
|
|
|
{
|
|
|
|
for (int i = 0; i < FaceType_Max; i++)
|
|
|
|
m_faces[i] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxFontBundleBase::~wxFontBundleBase()
|
|
|
|
{
|
|
|
|
for (int i = 0; i < FaceType_Max; i++)
|
|
|
|
delete m_faces[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
wxFontFace *wxFontBundleBase::GetFace(FaceType type) const
|
|
|
|
{
|
|
|
|
wxFontFace *f = m_faces[type];
|
|
|
|
|
|
|
|
wxCHECK_MSG( f, NULL, _T("no such face in font bundle") );
|
|
|
|
|
|
|
|
f->Acquire();
|
|
|
|
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxFontFace *
|
|
|
|
wxFontBundleBase::GetFaceForFont(const wxFontMgrFontRefData& font) const
|
|
|
|
{
|
|
|
|
wxASSERT_MSG( font.GetFaceName().empty() || font.GetFaceName() == GetName(),
|
|
|
|
_T("calling GetFaceForFont for incompatible font") );
|
|
|
|
|
|
|
|
int type = FaceType_Regular;
|
|
|
|
|
|
|
|
if ( font.GetWeight() == wxBOLD )
|
|
|
|
type |= FaceType_Bold;
|
|
|
|
|
|
|
|
// FIXME -- this should read "if ( font->GetStyle() == wxITALIC )",
|
|
|
|
// but since MGL neither DFB supports slant, we try to display it with
|
|
|
|
// italic face (better than nothing...)
|
|
|
|
if ( font.GetStyle() == wxITALIC || font.GetStyle() == wxSLANT )
|
|
|
|
{
|
|
|
|
if ( HasFace((FaceType)(type | FaceType_Italic)) )
|
|
|
|
type |= FaceType_Italic;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !HasFace((FaceType)type) )
|
|
|
|
{
|
|
|
|
for (int i = 0; i < FaceType_Max; i++)
|
|
|
|
{
|
|
|
|
if ( HasFace((FaceType)i) )
|
|
|
|
return GetFace((FaceType)i);
|
|
|
|
}
|
|
|
|
|
|
|
|
wxFAIL_MSG( _T("no face") );
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return GetFace((FaceType)type);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// wxFontsManagerBase
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
wxFontsManager *wxFontsManagerBase::ms_instance = NULL;
|
|
|
|
|
|
|
|
wxFontsManagerBase::wxFontsManagerBase()
|
|
|
|
{
|
|
|
|
m_hash = new wxFontBundleHash();
|
|
|
|
m_list = new wxFontBundleList;
|
|
|
|
m_list->DeleteContents(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
wxFontsManagerBase::~wxFontsManagerBase()
|
|
|
|
{
|
|
|
|
delete m_hash;
|
|
|
|
delete m_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */
|
|
|
|
wxFontsManager *wxFontsManagerBase::Get()
|
|
|
|
{
|
|
|
|
if ( !ms_instance )
|
|
|
|
ms_instance = new wxFontsManager();
|
|
|
|
return ms_instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */
|
|
|
|
void wxFontsManagerBase::CleanUp()
|
|
|
|
{
|
|
|
|
wxDELETE(ms_instance);
|
|
|
|
}
|
|
|
|
|
|
|
|
wxFontBundle *wxFontsManagerBase::GetBundle(const wxString& name) const
|
|
|
|
{
|
|
|
|
return (*m_hash)[name.Lower()];
|
|
|
|
}
|
|
|
|
|
|
|
|
wxFontBundle *
|
|
|
|
wxFontsManagerBase::GetBundleForFont(const wxFontMgrFontRefData& font) const
|
|
|
|
{
|
|
|
|
wxFontBundle *bundle = NULL;
|
|
|
|
|
|
|
|
wxString facename = font.GetFaceName();
|
|
|
|
if ( !facename.empty() )
|
|
|
|
bundle = GetBundle(facename);
|
|
|
|
|
|
|
|
if ( !bundle )
|
|
|
|
{
|
|
|
|
facename = GetDefaultFacename((wxFontFamily)font.GetFamily());
|
|
|
|
if ( !facename.empty() )
|
|
|
|
bundle = GetBundle(facename);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !bundle )
|
|
|
|
{
|
|
|
|
if ( m_list->GetFirst() )
|
|
|
|
bundle = m_list->GetFirst()->GetData();
|
|
|
|
else
|
|
|
|
wxFAIL_MSG(wxT("Fatal error, no fonts available!"));
|
|
|
|
}
|
|
|
|
|
|
|
|
return bundle;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxFontsManagerBase::AddBundle(wxFontBundle *bundle)
|
|
|
|
{
|
|
|
|
(*m_hash)[bundle->GetName().Lower()] = bundle;
|
|
|
|
m_list->Append(bundle);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// wxFontMgrFontRefData
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
wxFontMgrFontRefData::wxFontMgrFontRefData(int size,
|
|
|
|
int family,
|
|
|
|
int style,
|
|
|
|
int weight,
|
|
|
|
bool underlined,
|
|
|
|
const wxString& faceName,
|
|
|
|
wxFontEncoding encoding)
|
|
|
|
{
|
|
|
|
if ( family == wxDEFAULT )
|
|
|
|
family = wxSWISS;
|
|
|
|
if ( style == wxDEFAULT )
|
|
|
|
style = wxNORMAL;
|
|
|
|
if ( weight == wxDEFAULT )
|
|
|
|
weight = wxNORMAL;
|
|
|
|
if ( size == wxDEFAULT )
|
|
|
|
size = 12;
|
|
|
|
|
|
|
|
m_info.family = (wxFontFamily)family;
|
|
|
|
m_info.faceName = faceName;
|
|
|
|
m_info.style = (wxFontStyle)style;
|
|
|
|
m_info.weight = (wxFontWeight)weight;
|
|
|
|
m_info.pointSize = size;
|
|
|
|
m_info.underlined = underlined;
|
|
|
|
m_info.encoding = encoding;
|
|
|
|
|
|
|
|
m_noAA = false;
|
|
|
|
|
|
|
|
m_fontFace = NULL;
|
|
|
|
m_fontBundle = NULL;
|
|
|
|
m_fontValid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxFontMgrFontRefData::wxFontMgrFontRefData(const wxFontMgrFontRefData& data)
|
|
|
|
{
|
|
|
|
m_info = data.m_info;
|
|
|
|
m_noAA = data.m_noAA;
|
|
|
|
|
|
|
|
m_fontFace = data.m_fontFace;
|
|
|
|
m_fontBundle = data.m_fontBundle;
|
|
|
|
m_fontValid = data.m_fontValid;
|
|
|
|
if ( m_fontFace )
|
|
|
|
m_fontFace->Acquire();
|
|
|
|
}
|
|
|
|
|
|
|
|
wxFontMgrFontRefData::~wxFontMgrFontRefData()
|
|
|
|
{
|
|
|
|
if ( m_fontFace )
|
|
|
|
m_fontFace->Release();
|
|
|
|
}
|
|
|
|
|
|
|
|
wxFontBundle *wxFontMgrFontRefData::GetFontBundle() const
|
|
|
|
{
|
|
|
|
wxConstCast(this, wxFontMgrFontRefData)->EnsureValidFont();
|
|
|
|
return m_fontBundle;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxFontInstance *
|
|
|
|
wxFontMgrFontRefData::GetFontInstance(float scale, bool antialiased) const
|
|
|
|
{
|
|
|
|
wxConstCast(this, wxFontMgrFontRefData)->EnsureValidFont();
|
|
|
|
return m_fontFace->GetFontInstance(m_info.pointSize * scale,
|
|
|
|
antialiased && !m_noAA);
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxFontMgrFontRefData::SetPointSize(int pointSize)
|
|
|
|
{
|
|
|
|
m_info.pointSize = pointSize;
|
|
|
|
m_fontValid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxFontMgrFontRefData::SetFamily(int family)
|
|
|
|
{
|
|
|
|
m_info.family = (wxFontFamily)family;
|
|
|
|
m_fontValid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxFontMgrFontRefData::SetStyle(int style)
|
|
|
|
{
|
|
|
|
m_info.style = (wxFontStyle)style;
|
|
|
|
m_fontValid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxFontMgrFontRefData::SetWeight(int weight)
|
|
|
|
{
|
|
|
|
m_info.weight = (wxFontWeight)weight;
|
|
|
|
m_fontValid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxFontMgrFontRefData::SetFaceName(const wxString& faceName)
|
|
|
|
{
|
|
|
|
m_info.faceName = faceName;
|
|
|
|
m_fontValid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxFontMgrFontRefData::SetUnderlined(bool underlined)
|
|
|
|
{
|
|
|
|
m_info.underlined = underlined;
|
|
|
|
m_fontValid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxFontMgrFontRefData::SetEncoding(wxFontEncoding encoding)
|
|
|
|
{
|
|
|
|
m_info.encoding = encoding;
|
|
|
|
m_fontValid = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wxFontMgrFontRefData::SetNoAntiAliasing(bool no)
|
|
|
|
{
|
|
|
|
m_noAA = no;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void wxFontMgrFontRefData::EnsureValidFont()
|
|
|
|
{
|
|
|
|
if ( !m_fontValid )
|
|
|
|
{
|
|
|
|
wxFontFace *old = m_fontFace;
|
|
|
|
|
|
|
|
m_fontBundle = wxFontsManager::Get()->GetBundleForFont(*this);
|
|
|
|
m_fontFace = m_fontBundle->GetFaceForFont(*this);
|
|
|
|
|
|
|
|
if ( old )
|
|
|
|
old->Release();
|
|
|
|
}
|
|
|
|
}
|