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