1/////////////////////////////////////////////////////////////////////////////
2// Name:        src/mac/classic/font.cpp
3// Purpose:     wxFont class
4// Author:      Stefan Csomor
5// Modified by:
6// Created:     1998-01-01
7// RCS-ID:      $Id: font.cpp 43545 2006-11-20 16:21:08Z VS $
8// Copyright:   (c) Stefan Csomor
9// Licence:     wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15    #pragma hdrstop
16#endif
17
18#include "wx/font.h"
19
20#ifndef WX_PRECOMP
21    #include "wx/string.h"
22    #include "wx/utils.h"
23    #include "wx/gdicmn.h"
24#endif
25
26#include "wx/fontutil.h"
27
28#include "wx/fontutil.h"
29
30#include "wx/mac/private.h"
31#include <ATSUnicode.h>
32
33IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
34
35class WXDLLEXPORT wxFontRefData: public wxGDIRefData
36{
37    friend class WXDLLEXPORT wxFont;
38public:
39    wxFontRefData()
40        : m_fontId(0)
41        , m_pointSize(10)
42        , m_family(wxDEFAULT)
43        , m_style(wxNORMAL)
44        , m_weight(wxNORMAL)
45        , m_underlined(false)
46        , m_faceName(wxT("Geneva"))
47        , m_encoding(wxFONTENCODING_DEFAULT)
48        , m_macFontNum(0)
49        , m_macFontSize(0)
50        , m_macFontStyle(0)
51        , m_macATSUFontID()
52    {
53        Init(10, wxDEFAULT, wxNORMAL, wxNORMAL, false,
54             wxT("Geneva"), wxFONTENCODING_DEFAULT);
55    }
56
57    wxFontRefData(const wxFontRefData& data)
58        : wxGDIRefData()
59        , m_fontId(data.m_fontId)
60        , m_pointSize(data.m_pointSize)
61        , m_family(data.m_family)
62        , m_style(data.m_style)
63        , m_weight(data.m_weight)
64        , m_underlined(data.m_underlined)
65        , m_faceName(data.m_faceName)
66        , m_encoding(data.m_encoding)
67        , m_macFontNum(data.m_macFontNum)
68        , m_macFontSize(data.m_macFontSize)
69        , m_macFontStyle(data.m_macFontStyle)
70        , m_macATSUFontID(data.m_macATSUFontID)
71    {
72        Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
73             data.m_underlined, data.m_faceName, data.m_encoding);
74    }
75
76    wxFontRefData(int size,
77                  int family,
78                  int style,
79                  int weight,
80                  bool underlined,
81                  const wxString& faceName,
82                  wxFontEncoding encoding)
83        : m_fontId(0)
84        , m_pointSize(size)
85        , m_family(family)
86        , m_style(style)
87        , m_weight(weight)
88        , m_underlined(underlined)
89        , m_faceName(faceName)
90        , m_encoding(encoding)
91        , m_macFontNum(0)
92        , m_macFontSize(0)
93        , m_macFontStyle(0)
94        , m_macATSUFontID(0)
95    {
96        Init(size, family, style, weight, underlined, faceName, encoding);
97    }
98
99    virtual ~wxFontRefData();
100    void SetNoAntiAliasing( bool no = true ) { m_noAA = no; }
101    bool GetNoAntiAliasing() const { return m_noAA; }
102
103protected:
104    // common part of all ctors
105    void Init(int size,
106              int family,
107              int style,
108              int weight,
109              bool underlined,
110              const wxString& faceName,
111              wxFontEncoding encoding);
112
113    // font characterstics
114    int            m_fontId;
115    int            m_pointSize;
116    int            m_family;
117    int            m_style;
118    int            m_weight;
119    bool           m_underlined;
120    wxString       m_faceName;
121    wxFontEncoding m_encoding;
122    bool           m_noAA;      // No anti-aliasing
123
124public:
125    short       m_macFontNum;
126    short       m_macFontSize;
127    unsigned char  m_macFontStyle;
128    wxUint32       m_macATSUFontID;
129
130    wxNativeFontInfo  m_info;
131
132public:
133    void        MacFindFont() ;
134};
135
136#define M_FONTDATA ((wxFontRefData*)m_refData)
137
138// ============================================================================
139// implementation
140// ============================================================================
141
142// ----------------------------------------------------------------------------
143// wxFontRefData
144// ----------------------------------------------------------------------------
145
146void wxFontRefData::Init(int pointSize,
147                         int family,
148                         int style,
149                         int weight,
150                         bool underlined,
151                         const wxString& faceName,
152                         wxFontEncoding encoding)
153{
154    m_style = style;
155    m_pointSize = pointSize;
156    m_family = family;
157    m_style = style;
158    m_weight = weight;
159    m_underlined = underlined;
160    m_faceName = faceName;
161    m_encoding = encoding;
162
163    m_macFontNum = 0 ;
164    m_macFontSize = 0;
165    m_macFontStyle = 0;
166    m_fontId = 0;
167    m_noAA = false;
168}
169
170wxFontRefData::~wxFontRefData()
171{
172}
173
174void wxFontRefData::MacFindFont()
175{
176    if( m_faceName.empty() )
177    {
178        switch( m_family )
179        {
180            case wxDEFAULT :
181                m_macFontNum = ::GetAppFont() ;
182                break ;
183            case wxDECORATIVE :
184                ::GetFNum( "\pTimes" , &m_macFontNum) ;
185                break ;
186            case wxROMAN :
187                ::GetFNum( "\pTimes" , &m_macFontNum) ;
188                break ;
189            case wxSCRIPT :
190                ::GetFNum( "\pTimes" , &m_macFontNum) ;
191                break ;
192            case wxSWISS :
193                ::GetFNum( "\pGeneva" , &m_macFontNum) ;
194                break ;
195            case wxMODERN :
196                ::GetFNum( "\pMonaco" , &m_macFontNum) ;
197                break ;
198        }
199        Str255 name ;
200        GetFontName( m_macFontNum , name ) ;
201        m_faceName = wxMacMakeStringFromPascal( name ) ;
202    }
203    else
204    {
205        if ( m_faceName == wxT("systemfont") )
206            m_macFontNum = ::GetSysFont() ;
207        else if ( m_faceName == wxT("applicationfont") )
208            m_macFontNum = ::GetAppFont() ;
209        else
210        {
211            Str255 fontname ;
212            wxMacStringToPascal( m_faceName , fontname ) ;
213            ::GetFNum( fontname, &m_macFontNum);
214        }
215    }
216
217    m_macFontStyle = 0;
218    if (m_weight == wxBOLD)
219         m_macFontStyle |= bold;
220    if (m_style == wxITALIC || m_style == wxSLANT)
221        m_macFontStyle |= italic;
222    if (m_underlined)
223        m_macFontStyle |= underline;
224    m_macFontSize = m_pointSize ;
225
226    //TODO:if we supply the style as an additional parameter we must make a testing
227    //sequence in order to degrade gracefully while trying to maintain most of the style
228    //information, meanwhile we just take the normal font and apply the features after
229#ifdef __WXDEBUG__
230    OSStatus status =
231#endif // __WXDEBUG__
232        ::ATSUFONDtoFontID(m_macFontNum, normal /*qdStyle*/, (UInt32*)&m_macATSUFontID);
233    /*
234    status = ATSUFindFontFromName ( (Ptr) m_faceName , strlen( m_faceName ) ,
235        kFontFullName,    kFontMacintoshPlatform, kFontRomanScript , kFontNoLanguage  ,  (UInt32*)&m_macATSUFontID ) ;
236    */
237    wxASSERT_MSG( status == noErr , wxT("couldn't retrieve font identifier") ) ;
238}
239
240// ----------------------------------------------------------------------------
241// wxFont
242// ----------------------------------------------------------------------------
243}
244
245bool wxFont::Create(const wxNativeFontInfo& info)
246{
247    return Create(info.pointSize, info.family, info.style, info.weight,
248                  info.underlined, info.faceName, info.encoding);
249}
250
251wxFont::wxFont(const wxString& fontdesc)
252{
253    wxNativeFontInfo info;
254    if ( info.FromString(fontdesc) )
255        (void)Create(info);
256}
257
258bool wxFont::Create(int pointSize,
259                    int family,
260                    int style,
261                    int weight,
262                    bool underlined,
263                    const wxString& faceName,
264                    wxFontEncoding encoding)
265{
266    UnRef();
267    m_refData = new wxFontRefData(pointSize, family, style, weight,
268                                  underlined, faceName, encoding);
269
270    RealizeResource();
271
272    return true;
273}
274
275wxFont::~wxFont()
276{
277}
278
279bool wxFont::RealizeResource()
280{
281    M_FONTDATA->MacFindFont() ;
282    return true;
283}
284
285void wxFont::SetEncoding(wxFontEncoding encoding)
286{
287    Unshare();
288
289    M_FONTDATA->m_encoding = encoding;
290
291    RealizeResource();
292}
293
294void wxFont::Unshare()
295{
296    // Don't change shared data
297    if (!m_refData)
298    {
299        m_refData = new wxFontRefData();
300    }
301    else
302    {
303        wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
304        UnRef();
305        m_refData = ref;
306    }
307}
308
309void wxFont::SetPointSize(int pointSize)
310{
311    Unshare();
312
313    M_FONTDATA->m_pointSize = pointSize;
314
315    RealizeResource();
316}
317
318void wxFont::SetFamily(int family)
319{
320    Unshare();
321
322    M_FONTDATA->m_family = family;
323
324    RealizeResource();
325}
326
327void wxFont::SetStyle(int style)
328{
329    Unshare();
330
331    M_FONTDATA->m_style = style;
332
333    RealizeResource();
334}
335
336void wxFont::SetWeight(int weight)
337{
338    Unshare();
339
340    M_FONTDATA->m_weight = weight;
341
342    RealizeResource();
343}
344
345bool wxFont::SetFaceName(const wxString& faceName)
346{
347    Unshare();
348
349    M_FONTDATA->m_faceName = faceName;
350
351    RealizeResource();
352
353    return wxFontBase::SetFaceName(faceName);
354}
355
356void wxFont::SetUnderlined(bool underlined)
357{
358    Unshare();
359
360    M_FONTDATA->m_underlined = underlined;
361
362    RealizeResource();
363}
364
365void wxFont::SetNoAntiAliasing( bool no )
366{
367    Unshare();
368
369    M_FONTDATA->SetNoAntiAliasing( no );
370
371    RealizeResource();
372}
373
374// ----------------------------------------------------------------------------
375// accessors
376// ----------------------------------------------------------------------------
377
378// TODO: insert checks everywhere for M_FONTDATA == NULL!
379
380int wxFont::GetPointSize() const
381{
382    return M_FONTDATA->m_pointSize;
383}
384
385int wxFont::GetFamily() const
386{
387    return M_FONTDATA->m_family;
388}
389
390int wxFont::GetStyle() const
391{
392    return M_FONTDATA->m_style;
393}
394
395int wxFont::GetWeight() const
396{
397    return M_FONTDATA->m_weight;
398}
399
400bool wxFont::GetUnderlined() const
401{
402    return M_FONTDATA->m_underlined;
403}
404
405wxString wxFont::GetFaceName() const
406{
407    wxString str;
408    if ( M_FONTDATA )
409        str = M_FONTDATA->m_faceName ;
410    return str;
411}
412
413wxFontEncoding wxFont::GetEncoding() const
414{
415    return M_FONTDATA->m_encoding;
416}
417
418bool wxFont::GetNoAntiAliasing() const
419{
420    return M_FONTDATA->m_noAA;
421}
422
423short wxFont::GetMacFontNum() const
424{
425    return M_FONTDATA->m_macFontNum;
426}
427
428short wxFont::GetMacFontSize() const
429{
430    return M_FONTDATA->m_macFontSize;
431}
432
433wxByte wxFont::GetMacFontStyle() const
434{
435    return M_FONTDATA->m_macFontStyle;
436}
437
438wxUint32 wxFont::GetMacATSUFontID() const
439{
440    return M_FONTDATA->m_macATSUFontID;
441}
442
443const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
444{
445    wxCHECK_MSG( Ok(), NULL, wxT("invalid font") );
446
447    M_FONTDATA->m_info.InitFromFont(*this);
448
449    return &(M_FONTDATA->m_info);
450}
451