]> git.saurik.com Git - wxWidgets.git/blame - src/common/fontmgrcmn.cpp
use wx/crt.h as the 'official' header for wxCRT wrappers instead of wxchar.h; add...
[wxWidgets.git] / src / common / fontmgrcmn.cpp
CommitLineData
d7ae4a62
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/common/fontmgrcmn.cpp
3// Purpose: font management for ports that don't have their own
4// Author: Vaclav Slavik
5// Created: 2006-11-18
6// RCS-ID: $Id$
7// Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com)
8// (c) 2006 REA Elektronik GmbH
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16 #pragma hdrstop
17#endif
18
19#include "wx/private/fontmgr.h"
20
21#include "wx/listimpl.cpp"
22#include "wx/hashmap.h"
23
24WX_DECLARE_LIST(wxFontInstance, wxFontInstanceList);
25WX_DEFINE_LIST(wxFontInstanceList)
26WX_DEFINE_LIST(wxFontBundleList)
27WX_DECLARE_HASH_MAP(wxString, wxFontBundle*,
28 wxStringHash, wxStringEqual,
29 wxFontBundleHash);
30
31// ============================================================================
32// implementation
33// ============================================================================
34
35// ----------------------------------------------------------------------------
36// wxFontFaceBase
37// ----------------------------------------------------------------------------
38
39wxFontFaceBase::wxFontFaceBase()
40 : m_refCnt(0)
41{
42 m_instances = new wxFontInstanceList;
43 m_instances->DeleteContents(true);
44}
45
46wxFontFaceBase::~wxFontFaceBase()
47{
48 delete m_instances;
49}
50
51void wxFontFaceBase::Acquire()
52{
53 m_refCnt++;
54}
55
56void wxFontFaceBase::Release()
57{
58 if ( --m_refCnt == 0 )
59 {
60 m_instances->Clear();
61 }
62}
63
64wxFontInstance *wxFontFaceBase::GetFontInstance(float ptSize, bool aa)
65{
66 wxASSERT_MSG( m_refCnt > 0, _T("font library not loaded!") );
67
68 wxFontInstance *i;
69 wxFontInstanceList::Node *node;
70
71 for ( node = m_instances->GetFirst(); node; node = node->GetNext() )
72 {
73 i = node->GetData();
74 if ( i->GetPointSize() == ptSize && i->IsAntiAliased() == aa )
75 return i;
76 }
77
78 i = CreateFontInstance(ptSize, aa);
79 m_instances->Append(i);
80 return i;
81}
82
83// ----------------------------------------------------------------------------
84// wxFontBundleBase
85// ----------------------------------------------------------------------------
86
87wxFontBundleBase::wxFontBundleBase()
88{
89 for (int i = 0; i < FaceType_Max; i++)
90 m_faces[i] = NULL;
91}
92
93wxFontBundleBase::~wxFontBundleBase()
94{
95 for (int i = 0; i < FaceType_Max; i++)
96 delete m_faces[i];
97}
98
99wxFontFace *wxFontBundleBase::GetFace(FaceType type) const
100{
101 wxFontFace *f = m_faces[type];
102
103 wxCHECK_MSG( f, NULL, _T("no such face in font bundle") );
104
105 f->Acquire();
106
107 return f;
108}
109
110wxFontFace *
111wxFontBundleBase::GetFaceForFont(const wxFontMgrFontRefData& font) const
112{
dff1625b
VS
113 wxASSERT_MSG( font.GetFaceName().empty() ||
114 GetName().CmpNoCase(font.GetFaceName()) == 0,
d7ae4a62
VS
115 _T("calling GetFaceForFont for incompatible font") );
116
117 int type = FaceType_Regular;
118
119 if ( font.GetWeight() == wxBOLD )
120 type |= FaceType_Bold;
121
122 // FIXME -- this should read "if ( font->GetStyle() == wxITALIC )",
123 // but since MGL neither DFB supports slant, we try to display it with
124 // italic face (better than nothing...)
125 if ( font.GetStyle() == wxITALIC || font.GetStyle() == wxSLANT )
126 {
127 if ( HasFace((FaceType)(type | FaceType_Italic)) )
128 type |= FaceType_Italic;
129 }
130
131 if ( !HasFace((FaceType)type) )
132 {
209ce629
VS
133 // if we can't get the exact font requested, substitute it with
134 // some other variant:
d7ae4a62
VS
135 for (int i = 0; i < FaceType_Max; i++)
136 {
137 if ( HasFace((FaceType)i) )
138 return GetFace((FaceType)i);
139 }
140
141 wxFAIL_MSG( _T("no face") );
142 return NULL;
143 }
144
145 return GetFace((FaceType)type);
146}
147
148// ----------------------------------------------------------------------------
149// wxFontsManagerBase
150// ----------------------------------------------------------------------------
151
152wxFontsManager *wxFontsManagerBase::ms_instance = NULL;
153
154wxFontsManagerBase::wxFontsManagerBase()
155{
156 m_hash = new wxFontBundleHash();
157 m_list = new wxFontBundleList;
158 m_list->DeleteContents(true);
159}
160
161wxFontsManagerBase::~wxFontsManagerBase()
162{
163 delete m_hash;
164 delete m_list;
165}
166
167/* static */
168wxFontsManager *wxFontsManagerBase::Get()
169{
170 if ( !ms_instance )
171 ms_instance = new wxFontsManager();
172 return ms_instance;
173}
174
175/* static */
176void wxFontsManagerBase::CleanUp()
177{
178 wxDELETE(ms_instance);
179}
180
181wxFontBundle *wxFontsManagerBase::GetBundle(const wxString& name) const
182{
183 return (*m_hash)[name.Lower()];
184}
185
186wxFontBundle *
187wxFontsManagerBase::GetBundleForFont(const wxFontMgrFontRefData& font) const
188{
189 wxFontBundle *bundle = NULL;
190
191 wxString facename = font.GetFaceName();
192 if ( !facename.empty() )
193 bundle = GetBundle(facename);
194
195 if ( !bundle )
196 {
197 facename = GetDefaultFacename((wxFontFamily)font.GetFamily());
198 if ( !facename.empty() )
199 bundle = GetBundle(facename);
200 }
201
202 if ( !bundle )
203 {
204 if ( m_list->GetFirst() )
205 bundle = m_list->GetFirst()->GetData();
206 else
207 wxFAIL_MSG(wxT("Fatal error, no fonts available!"));
208 }
209
210 return bundle;
211}
212
213void wxFontsManagerBase::AddBundle(wxFontBundle *bundle)
214{
215 (*m_hash)[bundle->GetName().Lower()] = bundle;
216 m_list->Append(bundle);
217}
218
219
220// ----------------------------------------------------------------------------
221// wxFontMgrFontRefData
222// ----------------------------------------------------------------------------
223
224wxFontMgrFontRefData::wxFontMgrFontRefData(int size,
225 int family,
226 int style,
227 int weight,
228 bool underlined,
229 const wxString& faceName,
230 wxFontEncoding encoding)
231{
232 if ( family == wxDEFAULT )
233 family = wxSWISS;
234 if ( style == wxDEFAULT )
235 style = wxNORMAL;
236 if ( weight == wxDEFAULT )
237 weight = wxNORMAL;
238 if ( size == wxDEFAULT )
239 size = 12;
240
241 m_info.family = (wxFontFamily)family;
242 m_info.faceName = faceName;
243 m_info.style = (wxFontStyle)style;
244 m_info.weight = (wxFontWeight)weight;
245 m_info.pointSize = size;
246 m_info.underlined = underlined;
247 m_info.encoding = encoding;
248
249 m_noAA = false;
250
251 m_fontFace = NULL;
252 m_fontBundle = NULL;
253 m_fontValid = false;
254}
255
256wxFontMgrFontRefData::wxFontMgrFontRefData(const wxFontMgrFontRefData& data)
257{
258 m_info = data.m_info;
259 m_noAA = data.m_noAA;
260
261 m_fontFace = data.m_fontFace;
262 m_fontBundle = data.m_fontBundle;
263 m_fontValid = data.m_fontValid;
264 if ( m_fontFace )
265 m_fontFace->Acquire();
266}
267
268wxFontMgrFontRefData::~wxFontMgrFontRefData()
269{
270 if ( m_fontFace )
271 m_fontFace->Release();
272}
273
274wxFontBundle *wxFontMgrFontRefData::GetFontBundle() const
275{
276 wxConstCast(this, wxFontMgrFontRefData)->EnsureValidFont();
277 return m_fontBundle;
278}
279
280wxFontInstance *
281wxFontMgrFontRefData::GetFontInstance(float scale, bool antialiased) const
282{
283 wxConstCast(this, wxFontMgrFontRefData)->EnsureValidFont();
284 return m_fontFace->GetFontInstance(m_info.pointSize * scale,
285 antialiased && !m_noAA);
286}
287
288void wxFontMgrFontRefData::SetPointSize(int pointSize)
289{
290 m_info.pointSize = pointSize;
291 m_fontValid = false;
292}
293
294void wxFontMgrFontRefData::SetFamily(int family)
295{
296 m_info.family = (wxFontFamily)family;
297 m_fontValid = false;
298}
299
300void wxFontMgrFontRefData::SetStyle(int style)
301{
302 m_info.style = (wxFontStyle)style;
303 m_fontValid = false;
304}
305
306void wxFontMgrFontRefData::SetWeight(int weight)
307{
308 m_info.weight = (wxFontWeight)weight;
309 m_fontValid = false;
310}
311
312void wxFontMgrFontRefData::SetFaceName(const wxString& faceName)
313{
314 m_info.faceName = faceName;
315 m_fontValid = false;
316}
317
318void wxFontMgrFontRefData::SetUnderlined(bool underlined)
319{
320 m_info.underlined = underlined;
321 m_fontValid = false;
322}
323
324void wxFontMgrFontRefData::SetEncoding(wxFontEncoding encoding)
325{
326 m_info.encoding = encoding;
327 m_fontValid = false;
328}
329
330void wxFontMgrFontRefData::SetNoAntiAliasing(bool no)
331{
332 m_noAA = no;
333}
334
335
336void wxFontMgrFontRefData::EnsureValidFont()
337{
338 if ( !m_fontValid )
339 {
340 wxFontFace *old = m_fontFace;
341
342 m_fontBundle = wxFontsManager::Get()->GetBundleForFont(*this);
343 m_fontFace = m_fontBundle->GetFaceForFont(*this);
344
345 if ( old )
346 old->Release();
347 }
348}