]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/motif/font.cpp
wxDC::SetFont can now handle invalid font and doesn't assert anymore (other ports...
[wxWidgets.git] / src / motif / font.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/motif/font.cpp
3// Purpose: wxFont class
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#ifdef __GNUG__
21 #pragma implementation "font.h"
22#endif
23
24#ifdef __VMS
25#pragma message disable nosimpint
26#include "wx/vms_x_fix.h"
27#endif
28#include <Xm/Xm.h>
29#ifdef __VMS
30#pragma message enable nosimpint
31#endif
32
33#include "wx/defs.h"
34#include "wx/string.h"
35#include "wx/font.h"
36#include "wx/gdicmn.h"
37#include "wx/utils.h" // for wxGetDisplay()
38#include "wx/fontutil.h" // for wxNativeFontInfo
39
40IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
41
42// ----------------------------------------------------------------------------
43// private classes
44// ----------------------------------------------------------------------------
45
46// For every wxFont, there must be a font for each display and scale requested.
47// So these objects are stored in wxFontRefData::m_fonts
48class wxXFont : public wxObject
49{
50public:
51 wxXFont();
52 ~wxXFont();
53
54 WXFontStructPtr m_fontStruct; // XFontStruct
55 WXFontList m_fontList; // Motif XmFontList
56 WXDisplay* m_display; // XDisplay
57 int m_scale; // Scale * 100
58};
59
60class wxFontRefData: public wxGDIRefData
61{
62friend class wxFont;
63
64public:
65 wxFontRefData(int size = wxDEFAULT,
66 int family = wxDEFAULT,
67 int style = wxDEFAULT,
68 int weight = wxDEFAULT,
69 bool underlined = FALSE,
70 const wxString& faceName = wxEmptyString,
71 wxFontEncoding encoding = wxFONTENCODING_DEFAULT)
72 {
73 Init(size, family, style, weight, underlined, faceName, encoding);
74 }
75
76 wxFontRefData(const wxFontRefData& data)
77 {
78 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
79 data.m_underlined, data.m_faceName, data.m_encoding);
80 }
81
82 ~wxFontRefData();
83
84protected:
85 // common part of all ctors
86 void Init(int size,
87 int family,
88 int style,
89 int weight,
90 bool underlined,
91 const wxString& faceName,
92 wxFontEncoding encoding);
93
94 // font attributes
95 int m_pointSize;
96 int m_family;
97 int m_style;
98 int m_weight;
99 bool m_underlined;
100 wxString m_faceName;
101 wxFontEncoding m_encoding;
102
103 // A list of wxXFonts
104 wxList m_fonts;
105};
106
107// ============================================================================
108// implementation
109// ============================================================================
110
111// ----------------------------------------------------------------------------
112// wxXFont
113// ----------------------------------------------------------------------------
114
115wxXFont::wxXFont()
116{
117 m_fontStruct = (WXFontStructPtr) 0;
118 m_fontList = (WXFontList) 0;
119 m_display = (WXDisplay*) 0;
120 m_scale = 100;
121}
122
123wxXFont::~wxXFont()
124{
125 XmFontList fontList = (XmFontList) m_fontList;
126
127 XmFontListFree (fontList);
128
129 // TODO: why does freeing the font produce a segv???
130 // Note that XFreeFont wasn't called in wxWin 1.68 either.
131 // XFontStruct* fontStruct = (XFontStruct*) m_fontStruct;
132 // XFreeFont((Display*) m_display, fontStruct);
133}
134
135// ----------------------------------------------------------------------------
136// wxFontRefData
137// ----------------------------------------------------------------------------
138
139void wxFontRefData::Init(int pointSize,
140 int family,
141 int style,
142 int weight,
143 bool underlined,
144 const wxString& faceName,
145 wxFontEncoding encoding)
146{
147 if (family == wxDEFAULT)
148 m_family = wxSWISS;
149 else
150 m_family = family;
151
152 m_faceName = faceName;
153
154 if (style == wxDEFAULT)
155 m_style = wxNORMAL;
156 else
157 m_style = style;
158
159 if (weight == wxDEFAULT)
160 m_weight = wxNORMAL;
161 else
162 m_weight = weight;
163
164 if (pointSize == wxDEFAULT)
165 m_pointSize = 12;
166 else
167 m_pointSize = pointSize;
168
169 m_underlined = underlined;
170 m_encoding = encoding;
171}
172
173wxFontRefData::~wxFontRefData()
174{
175 wxNode* node = m_fonts.First();
176 while (node)
177 {
178 wxXFont* f = (wxXFont*) node->Data();
179 delete f;
180 node = node->Next();
181 }
182 m_fonts.Clear();
183}
184
185// ----------------------------------------------------------------------------
186// wxFont
187// ----------------------------------------------------------------------------
188
189wxFont::wxFont(const wxNativeFontInfo& info)
190{
191 Init();
192
193 (void)Create(info.pointSize, info.family, info.style, info.weight,
194 info.underlined, info.faceName, info.encoding);
195}
196
197void wxFont::Init()
198{
199}
200
201bool wxFont::Create(int pointSize,
202 int family,
203 int style,
204 int weight,
205 bool underlined,
206 const wxString& faceName,
207 wxFontEncoding encoding)
208{
209 UnRef();
210 m_refData = new wxFontRefData(pointSize, family, style, weight,
211 underlined, faceName, encoding);
212
213 RealizeResource();
214
215 return TRUE;
216}
217
218wxFont::~wxFont()
219{
220}
221
222// ----------------------------------------------------------------------------
223// change the font attributes
224// ----------------------------------------------------------------------------
225
226void wxFont::Unshare()
227{
228 // Don't change shared data
229 if (!m_refData)
230 {
231 m_refData = new wxFontRefData();
232 }
233 else
234 {
235 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
236 UnRef();
237 m_refData = ref;
238 }
239}
240
241void wxFont::SetPointSize(int pointSize)
242{
243 Unshare();
244
245 M_FONTDATA->m_pointSize = pointSize;
246
247 RealizeResource();
248}
249
250void wxFont::SetFamily(int family)
251{
252 Unshare();
253
254 M_FONTDATA->m_family = family;
255
256 RealizeResource();
257}
258
259void wxFont::SetStyle(int style)
260{
261 Unshare();
262
263 M_FONTDATA->m_style = style;
264
265 RealizeResource();
266}
267
268void wxFont::SetWeight(int weight)
269{
270 Unshare();
271
272 M_FONTDATA->m_weight = weight;
273
274 RealizeResource();
275}
276
277void wxFont::SetFaceName(const wxString& faceName)
278{
279 Unshare();
280
281 M_FONTDATA->m_faceName = faceName;
282
283 RealizeResource();
284}
285
286void wxFont::SetUnderlined(bool underlined)
287{
288 Unshare();
289
290 M_FONTDATA->m_underlined = underlined;
291
292 RealizeResource();
293}
294
295void wxFont::SetEncoding(wxFontEncoding encoding)
296{
297 Unshare();
298
299 M_FONTDATA->m_encoding = encoding;
300
301 RealizeResource();
302}
303
304// ----------------------------------------------------------------------------
305// query font attributes
306// ----------------------------------------------------------------------------
307
308int wxFont::GetPointSize() const
309{
310 return M_FONTDATA->m_pointSize;
311}
312
313int wxFont::GetFamily() const
314{
315 return M_FONTDATA->m_family;
316}
317
318int wxFont::GetStyle() const
319{
320 return M_FONTDATA->m_style;
321}
322
323int wxFont::GetWeight() const
324{
325 return M_FONTDATA->m_weight;
326}
327
328bool wxFont::GetUnderlined() const
329{
330 return M_FONTDATA->m_underlined;
331}
332
333wxString wxFont::GetFaceName() const
334{
335 wxString str;
336 if ( M_FONTDATA )
337 str = M_FONTDATA->m_faceName ;
338 return str;
339}
340
341wxFontEncoding wxFont::GetEncoding() const
342{
343 return M_FONTDATA->m_encoding;
344}
345
346// ----------------------------------------------------------------------------
347// real implementation
348// ----------------------------------------------------------------------------
349
350// Find an existing, or create a new, XFontStruct
351// based on this wxFont and the given scale. Append the
352// font to list in the private data for future reference.
353wxXFont* wxFont::GetInternalFont(double scale, WXDisplay* display) const
354{
355 if ( !Ok() )
356 return (wxXFont *)NULL;
357
358 long intScale = long(scale * 100.0 + 0.5); // key for wxXFont
359 int pointSize = (M_FONTDATA->m_pointSize * 10 * intScale) / 100;
360
361 // search existing fonts first
362 wxNode* node = M_FONTDATA->m_fonts.First();
363 while (node)
364 {
365 wxXFont* f = (wxXFont*) node->Data();
366 if ((!display || (f->m_display == display)) && (f->m_scale == intScale))
367 return f;
368 node = node->Next();
369 }
370
371 // not found, create a new one
372 XFontStruct *font = (XFontStruct *)
373 wxLoadQueryNearestFont(pointSize,
374 M_FONTDATA->m_family,
375 M_FONTDATA->m_style,
376 M_FONTDATA->m_weight,
377 M_FONTDATA->m_underlined,
378 wxT(""),
379 M_FONTDATA->m_encoding);
380
381 if ( !font )
382 {
383 wxFAIL_MSG( wxT("Could not allocate even a default font -- something is wrong.") );
384
385 return (wxXFont*) NULL;
386 }
387
388 wxXFont* f = new wxXFont;
389 f->m_fontStruct = (WXFontStructPtr)font;
390 f->m_display = ( display ? display : wxGetDisplay() );
391 f->m_scale = intScale;
392 f->m_fontList = XmFontListCreate ((XFontStruct*) font, XmSTRING_DEFAULT_CHARSET);
393 M_FONTDATA->m_fonts.Append(f);
394
395 return f;
396}
397
398WXFontStructPtr wxFont::GetFontStruct(double scale, WXDisplay* display) const
399{
400 wxXFont* f = GetInternalFont(scale, display);
401
402 return (f ? f->m_fontStruct : (WXFontStructPtr) 0);
403}
404
405WXFontList wxFont::GetFontList(double scale, WXDisplay* display) const
406{
407 wxXFont* f = GetInternalFont(scale, display);
408
409 return (f ? f->m_fontList : (WXFontList) 0);
410}
411