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