changed wxUSE_DRAGIMAG to wxUSE_DRAGIMAGE and use it everywhere now
[wxWidgets.git] / src / motif / font.cpp
CommitLineData
4bb6408c
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: 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
dfe1eee3 9// Licence: wxWindows licence
4bb6408c
JS
10/////////////////////////////////////////////////////////////////////////////
11
93ccaed8
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
4bb6408c 20#ifdef __GNUG__
93ccaed8 21 #pragma implementation "font.h"
4bb6408c
JS
22#endif
23
338dd992
JJ
24#ifdef __VMS
25#pragma message disable nosimpint
4dff3400 26#include "wx/vms_x_fix.h"
338dd992 27#endif
79e4b627 28#include <Xm/Xm.h>
338dd992
JJ
29#ifdef __VMS
30#pragma message enable nosimpint
31#endif
79e4b627 32
4bb6408c
JS
33#include "wx/defs.h"
34#include "wx/string.h"
35#include "wx/font.h"
36#include "wx/gdicmn.h"
79e4b627 37#include "wx/utils.h" // for wxGetDisplay()
98c9fc2d 38#include "wx/fontutil.h" // for wxNativeFontInfo
4bb6408c 39
98c9fc2d 40IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
4bb6408c 41
93ccaed8
VZ
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
79e4b627 48class wxXFont : public wxObject
93ccaed8
VZ
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
f97c9854
JS
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{
f97c9854 125 XmFontList fontList = (XmFontList) m_fontList;
dfe1eee3 126
f97c9854 127 XmFontListFree (fontList);
dfe1eee3 128
2d120f83 129 // TODO: why does freeing the font produce a segv???
f97c9854 130 // Note that XFreeFont wasn't called in wxWin 1.68 either.
dfe1eee3 131 // XFontStruct* fontStruct = (XFontStruct*) m_fontStruct;
2d120f83 132 // XFreeFont((Display*) m_display, fontStruct);
f97c9854
JS
133}
134
93ccaed8
VZ
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)
4bb6408c 146{
93ccaed8
VZ
147 if (family == wxDEFAULT)
148 m_family = wxSWISS;
149 else
150 m_family = family;
4bb6408c 151
93ccaed8
VZ
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;
4bb6408c
JS
171}
172
173wxFontRefData::~wxFontRefData()
174{
f97c9854 175 wxNode* node = m_fonts.First();
dfc54541
JS
176 while (node)
177 {
f97c9854
JS
178 wxXFont* f = (wxXFont*) node->Data();
179 delete f;
dfc54541
JS
180 node = node->Next();
181 }
f97c9854 182 m_fonts.Clear();
4bb6408c
JS
183}
184
93ccaed8
VZ
185// ----------------------------------------------------------------------------
186// wxFont
187// ----------------------------------------------------------------------------
4bb6408c 188
ef4e8ebd 189wxFont::wxFont(const wxNativeFontInfo& info)
98c9fc2d
VZ
190{
191 Init();
192
193 (void)Create(info.pointSize, info.family, info.style, info.weight,
194 info.underlined, info.faceName, info.encoding);
195}
196
93ccaed8 197void wxFont::Init()
4bb6408c 198{
4bb6408c
JS
199 if ( wxTheFontList )
200 wxTheFontList->Append(this);
201}
202
93ccaed8
VZ
203bool wxFont::Create(int pointSize,
204 int family,
205 int style,
206 int weight,
207 bool underlined,
208 const wxString& faceName,
209 wxFontEncoding encoding)
4bb6408c
JS
210{
211 UnRef();
93ccaed8
VZ
212 m_refData = new wxFontRefData(pointSize, family, style, weight,
213 underlined, faceName, encoding);
dfe1eee3 214
4bb6408c 215 RealizeResource();
dfe1eee3 216
4bb6408c
JS
217 return TRUE;
218}
219
220wxFont::~wxFont()
221{
93ccaed8 222 if ( wxTheFontList )
4bb6408c
JS
223 wxTheFontList->DeleteObject(this);
224}
225
93ccaed8
VZ
226// ----------------------------------------------------------------------------
227// change the font attributes
228// ----------------------------------------------------------------------------
4bb6408c
JS
229
230void wxFont::Unshare()
231{
2d120f83
JS
232 // Don't change shared data
233 if (!m_refData)
4bb6408c 234 {
2d120f83
JS
235 m_refData = new wxFontRefData();
236 }
4bb6408c
JS
237 else
238 {
2d120f83
JS
239 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
240 UnRef();
241 m_refData = ref;
242 }
4bb6408c
JS
243}
244
245void wxFont::SetPointSize(int pointSize)
246{
247 Unshare();
dfe1eee3 248
4bb6408c 249 M_FONTDATA->m_pointSize = pointSize;
dfe1eee3 250
4bb6408c
JS
251 RealizeResource();
252}
253
254void wxFont::SetFamily(int family)
255{
256 Unshare();
dfe1eee3 257
4bb6408c 258 M_FONTDATA->m_family = family;
dfe1eee3 259
4bb6408c
JS
260 RealizeResource();
261}
262
263void wxFont::SetStyle(int style)
264{
265 Unshare();
dfe1eee3 266
4bb6408c 267 M_FONTDATA->m_style = style;
dfe1eee3 268
4bb6408c
JS
269 RealizeResource();
270}
271
272void wxFont::SetWeight(int weight)
273{
274 Unshare();
dfe1eee3 275
4bb6408c 276 M_FONTDATA->m_weight = weight;
dfe1eee3 277
4bb6408c
JS
278 RealizeResource();
279}
280
281void wxFont::SetFaceName(const wxString& faceName)
282{
283 Unshare();
dfe1eee3 284
4bb6408c 285 M_FONTDATA->m_faceName = faceName;
dfe1eee3 286
4bb6408c
JS
287 RealizeResource();
288}
289
290void wxFont::SetUnderlined(bool underlined)
291{
292 Unshare();
dfe1eee3 293
4bb6408c 294 M_FONTDATA->m_underlined = underlined;
dfe1eee3 295
4bb6408c
JS
296 RealizeResource();
297}
298
93ccaed8 299void wxFont::SetEncoding(wxFontEncoding encoding)
4bb6408c 300{
93ccaed8
VZ
301 Unshare();
302
303 M_FONTDATA->m_encoding = encoding;
304
305 RealizeResource();
306}
307
308// ----------------------------------------------------------------------------
309// query font attributes
310// ----------------------------------------------------------------------------
311
312int wxFont::GetPointSize() const
313{
314 return M_FONTDATA->m_pointSize;
315}
316
317int wxFont::GetFamily() const
318{
319 return M_FONTDATA->m_family;
320}
321
322int wxFont::GetStyle() const
323{
324 return M_FONTDATA->m_style;
325}
326
327int wxFont::GetWeight() const
328{
329 return M_FONTDATA->m_weight;
330}
331
332bool wxFont::GetUnderlined() const
333{
334 return M_FONTDATA->m_underlined;
4bb6408c
JS
335}
336
4bb6408c
JS
337wxString wxFont::GetFaceName() const
338{
93ccaed8
VZ
339 wxString str;
340 if ( M_FONTDATA )
2d120f83 341 str = M_FONTDATA->m_faceName ;
4bb6408c
JS
342 return str;
343}
344
93ccaed8 345wxFontEncoding wxFont::GetEncoding() const
4bb6408c 346{
93ccaed8 347 return M_FONTDATA->m_encoding;
4bb6408c
JS
348}
349
93ccaed8
VZ
350// ----------------------------------------------------------------------------
351// real implementation
352// ----------------------------------------------------------------------------
4bb6408c 353
dfc54541
JS
354// Find an existing, or create a new, XFontStruct
355// based on this wxFont and the given scale. Append the
356// font to list in the private data for future reference.
f97c9854 357wxXFont* wxFont::GetInternalFont(double scale, WXDisplay* display) const
dfc54541 358{
93ccaed8
VZ
359 if ( !Ok() )
360 return (wxXFont *)NULL;
dfe1eee3 361
2d120f83
JS
362 long intScale = long(scale * 100.0 + 0.5); // key for wxXFont
363 int pointSize = (M_FONTDATA->m_pointSize * 10 * intScale) / 100;
dfe1eee3 364
93ccaed8 365 // search existing fonts first
2d120f83
JS
366 wxNode* node = M_FONTDATA->m_fonts.First();
367 while (node)
368 {
369 wxXFont* f = (wxXFont*) node->Data();
370 if ((!display || (f->m_display == display)) && (f->m_scale == intScale))
371 return f;
372 node = node->Next();
373 }
dfe1eee3 374
93ccaed8 375 // not found, create a new one
0d083705
VZ
376 XFontStruct *font = (XFontStruct *)
377 wxLoadQueryNearestFont(pointSize,
93ccaed8
VZ
378 M_FONTDATA->m_family,
379 M_FONTDATA->m_style,
380 M_FONTDATA->m_weight,
381 M_FONTDATA->m_underlined,
223d09f6 382 wxT(""),
93ccaed8 383 M_FONTDATA->m_encoding);
dfe1eee3 384
93ccaed8 385 if ( !font )
2d120f83 386 {
223d09f6 387 wxFAIL_MSG( wxT("Could not allocate even a default font -- something is wrong.") );
93ccaed8
VZ
388
389 return (wxXFont*) NULL;
2d120f83 390 }
93ccaed8
VZ
391
392 wxXFont* f = new wxXFont;
393 f->m_fontStruct = (WXFontStructPtr)font;
394 f->m_display = ( display ? display : wxGetDisplay() );
395 f->m_scale = intScale;
396 f->m_fontList = XmFontListCreate ((XFontStruct*) font, XmSTRING_DEFAULT_CHARSET);
397 M_FONTDATA->m_fonts.Append(f);
398
399 return f;
dfc54541
JS
400}
401
93ccaed8 402WXFontStructPtr wxFont::GetFontStruct(double scale, WXDisplay* display) const
dfc54541 403{
93ccaed8 404 wxXFont* f = GetInternalFont(scale, display);
dfe1eee3 405
93ccaed8
VZ
406 return (f ? f->m_fontStruct : (WXFontStructPtr) 0);
407}
dfe1eee3 408
93ccaed8
VZ
409WXFontList wxFont::GetFontList(double scale, WXDisplay* display) const
410{
411 wxXFont* f = GetInternalFont(scale, display);
dfe1eee3 412
93ccaed8 413 return (f ? f->m_fontList : (WXFontList) 0);
dfc54541 414}