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