dolphin/Externals/wxWidgets/src/common/fontmgrcmn.cpp

349 lines
8.6 KiB
C++
Raw Normal View History

/////////////////////////////////////////////////////////////////////////////
// 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 54757 2008-07-21 17:34:48Z VZ $
// 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,
wxFontBundleHashBase);
// in STL build, hash class is typedef to a template, so it can't be forward
// declared, as we do; solve it by having a dummy class:
class wxFontBundleHash : public wxFontBundleHashBase
{
};
// ============================================================================
// 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!") );
for ( wxFontInstanceList::const_iterator i = m_instances->begin();
i != m_instances->end(); ++i )
{
if ( (*i)->GetPointSize() == ptSize && (*i)->IsAntiAliased() == aa )
return *i;
}
wxFontInstance *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();
}
}