1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxFont class
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "font.h"
27 #include "wx/string.h"
29 #include "wx/gdicmn.h"
30 #include "wx/utils.h" // for wxGetDisplay()
31 #include "wx/fontutil.h"
33 #if !USE_SHARED_LIBRARIES
34 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
37 // ----------------------------------------------------------------------------
39 // ----------------------------------------------------------------------------
41 // For every wxFont, there must be a font for each display and scale requested.
42 // So these objects are stored in wxFontRefData::m_fonts
43 class wxXFont
: public wxObject
49 WXFontStructPtr m_fontStruct
; // XFontStruct
50 WXFontList m_fontList
; // Motif XmFontList
51 WXDisplay
* m_display
; // XDisplay
52 int m_scale
; // Scale * 100
55 class wxFontRefData
: public wxGDIRefData
60 wxFontRefData(int size
= wxDEFAULT
,
61 int family
= wxDEFAULT
,
62 int style
= wxDEFAULT
,
63 int weight
= wxDEFAULT
,
64 bool underlined
= FALSE
,
65 const wxString
& faceName
= wxEmptyString
,
66 wxFontEncoding encoding
= wxFONTENCODING_DEFAULT
)
68 Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
);
71 wxFontRefData(const wxFontRefData
& data
)
73 Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
,
74 data
.m_underlined
, data
.m_faceName
, data
.m_encoding
);
80 // common part of all ctors
86 const wxString
& faceName
,
87 wxFontEncoding encoding
);
96 wxFontEncoding m_encoding
;
102 // ============================================================================
104 // ============================================================================
106 // ----------------------------------------------------------------------------
108 // ----------------------------------------------------------------------------
112 m_fontStruct
= (WXFontStructPtr
) 0;
113 m_fontList
= (WXFontList
) 0;
114 m_display
= (WXDisplay
*) 0;
120 XmFontList fontList
= (XmFontList
) m_fontList
;
122 XmFontListFree (fontList
);
124 // TODO: why does freeing the font produce a segv???
125 // Note that XFreeFont wasn't called in wxWin 1.68 either.
126 // XFontStruct* fontStruct = (XFontStruct*) m_fontStruct;
127 // XFreeFont((Display*) m_display, fontStruct);
130 // ----------------------------------------------------------------------------
132 // ----------------------------------------------------------------------------
134 void wxFontRefData::Init(int pointSize
,
139 const wxString
& faceName
,
140 wxFontEncoding encoding
)
142 if (family
== wxDEFAULT
)
147 m_faceName
= faceName
;
149 if (style
== wxDEFAULT
)
154 if (weight
== wxDEFAULT
)
159 if (pointSize
== wxDEFAULT
)
162 m_pointSize
= pointSize
;
164 m_underlined
= underlined
;
165 m_encoding
= encoding
;
168 wxFontRefData::~wxFontRefData()
170 wxNode
* node
= m_fonts
.First();
173 wxXFont
* f
= (wxXFont
*) node
->Data();
180 // ----------------------------------------------------------------------------
182 // ----------------------------------------------------------------------------
187 wxTheFontList
->Append(this);
190 bool wxFont::Create(int pointSize
,
195 const wxString
& faceName
,
196 wxFontEncoding encoding
)
199 m_refData
= new wxFontRefData(pointSize
, family
, style
, weight
,
200 underlined
, faceName
, encoding
);
210 wxTheFontList
->DeleteObject(this);
213 // ----------------------------------------------------------------------------
214 // change the font attributes
215 // ----------------------------------------------------------------------------
217 void wxFont::Unshare()
219 // Don't change shared data
222 m_refData
= new wxFontRefData();
226 wxFontRefData
* ref
= new wxFontRefData(*(wxFontRefData
*)m_refData
);
232 void wxFont::SetPointSize(int pointSize
)
236 M_FONTDATA
->m_pointSize
= pointSize
;
241 void wxFont::SetFamily(int family
)
245 M_FONTDATA
->m_family
= family
;
250 void wxFont::SetStyle(int style
)
254 M_FONTDATA
->m_style
= style
;
259 void wxFont::SetWeight(int weight
)
263 M_FONTDATA
->m_weight
= weight
;
268 void wxFont::SetFaceName(const wxString
& faceName
)
272 M_FONTDATA
->m_faceName
= faceName
;
277 void wxFont::SetUnderlined(bool underlined
)
281 M_FONTDATA
->m_underlined
= underlined
;
286 void wxFont::SetEncoding(wxFontEncoding encoding
)
290 M_FONTDATA
->m_encoding
= encoding
;
295 // ----------------------------------------------------------------------------
296 // query font attributes
297 // ----------------------------------------------------------------------------
299 int wxFont::GetPointSize() const
301 return M_FONTDATA
->m_pointSize
;
304 int wxFont::GetFamily() const
306 return M_FONTDATA
->m_family
;
309 int wxFont::GetStyle() const
311 return M_FONTDATA
->m_style
;
314 int wxFont::GetWeight() const
316 return M_FONTDATA
->m_weight
;
319 bool wxFont::GetUnderlined() const
321 return M_FONTDATA
->m_underlined
;
324 wxString
wxFont::GetFaceName() const
328 str
= M_FONTDATA
->m_faceName
;
332 wxFontEncoding
wxFont::GetEncoding() const
334 return M_FONTDATA
->m_encoding
;
337 // ----------------------------------------------------------------------------
338 // real implementation
339 // ----------------------------------------------------------------------------
341 // Find an existing, or create a new, XFontStruct
342 // based on this wxFont and the given scale. Append the
343 // font to list in the private data for future reference.
344 wxXFont
* wxFont::GetInternalFont(double scale
, WXDisplay
* display
) const
347 return (wxXFont
*)NULL
;
349 long intScale
= long(scale
* 100.0 + 0.5); // key for wxXFont
350 int pointSize
= (M_FONTDATA
->m_pointSize
* 10 * intScale
) / 100;
352 // search existing fonts first
353 wxNode
* node
= M_FONTDATA
->m_fonts
.First();
356 wxXFont
* f
= (wxXFont
*) node
->Data();
357 if ((!display
|| (f
->m_display
== display
)) && (f
->m_scale
== intScale
))
362 // not found, create a new one
363 XFontStruct
*font
= wxLoadQueryNearestFont(pointSize
,
364 M_FONTDATA
->m_family
,
366 M_FONTDATA
->m_weight
,
367 M_FONTDATA
->m_underlined
,
369 M_FONTDATA
->m_encoding
);
373 wxFAIL_MSG( wxT("Could not allocate even a default font -- something is wrong.") );
375 return (wxXFont
*) NULL
;
378 wxXFont
* f
= new wxXFont
;
379 f
->m_fontStruct
= (WXFontStructPtr
)font
;
380 f
->m_display
= ( display
? display
: wxGetDisplay() );
381 f
->m_scale
= intScale
;
382 f
->m_fontList
= XmFontListCreate ((XFontStruct
*) font
, XmSTRING_DEFAULT_CHARSET
);
383 M_FONTDATA
->m_fonts
.Append(f
);
388 WXFontStructPtr
wxFont::GetFontStruct(double scale
, WXDisplay
* display
) const
390 wxXFont
* f
= GetInternalFont(scale
, display
);
392 return (f
? f
->m_fontStruct
: (WXFontStructPtr
) 0);
395 WXFontList
wxFont::GetFontList(double scale
, WXDisplay
* display
) const
397 wxXFont
* f
= GetInternalFont(scale
, display
);
399 return (f
? f
->m_fontList
: (WXFontList
) 0);