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