]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/motif/font.cpp
some conflicts resolved
[wxWidgets.git] / src / motif / font.cpp
... / ...
CommitLineData
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
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#ifdef __GNUG__
21 #pragma implementation "font.h"
22#endif
23
24#include "wx/defs.h"
25#include "wx/string.h"
26#include "wx/font.h"
27#include "wx/gdicmn.h"
28#include "wx/utils.h"
29
30#include <Xm/Xm.h>
31
32#if !USE_SHARED_LIBRARIES
33 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
34#endif
35
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
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{
119 XmFontList fontList = (XmFontList) m_fontList;
120
121 XmFontListFree (fontList);
122
123 // TODO: why does freeing the font produce a segv???
124 // Note that XFreeFont wasn't called in wxWin 1.68 either.
125 // XFontStruct* fontStruct = (XFontStruct*) m_fontStruct;
126 // XFreeFont((Display*) m_display, fontStruct);
127}
128
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)
140{
141 if (family == wxDEFAULT)
142 m_family = wxSWISS;
143 else
144 m_family = family;
145
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;
165}
166
167wxFontRefData::~wxFontRefData()
168{
169 wxNode* node = m_fonts.First();
170 while (node)
171 {
172 wxXFont* f = (wxXFont*) node->Data();
173 delete f;
174 node = node->Next();
175 }
176 m_fonts.Clear();
177}
178
179// ----------------------------------------------------------------------------
180// wxFont
181// ----------------------------------------------------------------------------
182
183void wxFont::Init()
184{
185 if ( wxTheFontList )
186 wxTheFontList->Append(this);
187}
188
189bool wxFont::Create(int pointSize,
190 int family,
191 int style,
192 int weight,
193 bool underlined,
194 const wxString& faceName,
195 wxFontEncoding encoding)
196{
197 UnRef();
198 m_refData = new wxFontRefData(pointSize, family, style, weight,
199 underlined, faceName, encoding);
200
201 RealizeResource();
202
203 return TRUE;
204}
205
206wxFont::~wxFont()
207{
208 if ( wxTheFontList )
209 wxTheFontList->DeleteObject(this);
210}
211
212// ----------------------------------------------------------------------------
213// change the font attributes
214// ----------------------------------------------------------------------------
215
216void wxFont::Unshare()
217{
218 // Don't change shared data
219 if (!m_refData)
220 {
221 m_refData = new wxFontRefData();
222 }
223 else
224 {
225 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
226 UnRef();
227 m_refData = ref;
228 }
229}
230
231void wxFont::SetPointSize(int pointSize)
232{
233 Unshare();
234
235 M_FONTDATA->m_pointSize = pointSize;
236
237 RealizeResource();
238}
239
240void wxFont::SetFamily(int family)
241{
242 Unshare();
243
244 M_FONTDATA->m_family = family;
245
246 RealizeResource();
247}
248
249void wxFont::SetStyle(int style)
250{
251 Unshare();
252
253 M_FONTDATA->m_style = style;
254
255 RealizeResource();
256}
257
258void wxFont::SetWeight(int weight)
259{
260 Unshare();
261
262 M_FONTDATA->m_weight = weight;
263
264 RealizeResource();
265}
266
267void wxFont::SetFaceName(const wxString& faceName)
268{
269 Unshare();
270
271 M_FONTDATA->m_faceName = faceName;
272
273 RealizeResource();
274}
275
276void wxFont::SetUnderlined(bool underlined)
277{
278 Unshare();
279
280 M_FONTDATA->m_underlined = underlined;
281
282 RealizeResource();
283}
284
285void wxFont::SetEncoding(wxFontEncoding encoding)
286{
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;
321}
322
323wxString wxFont::GetFaceName() const
324{
325 wxString str;
326 if ( M_FONTDATA )
327 str = M_FONTDATA->m_faceName ;
328 return str;
329}
330
331wxFontEncoding wxFont::GetEncoding() const
332{
333 return M_FONTDATA->m_encoding;
334}
335
336// ----------------------------------------------------------------------------
337// real implementation
338// ----------------------------------------------------------------------------
339
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.
343wxXFont* wxFont::GetInternalFont(double scale, WXDisplay* display) const
344{
345 if ( !Ok() )
346 return (wxXFont *)NULL;
347
348 long intScale = long(scale * 100.0 + 0.5); // key for wxXFont
349 int pointSize = (M_FONTDATA->m_pointSize * 10 * intScale) / 100;
350
351 // search existing fonts first
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 }
360
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,
367 wxT(""),
368 M_FONTDATA->m_encoding);
369
370 if ( !font )
371 {
372 wxFAIL_MSG( wxT("Could not allocate even a default font -- something is wrong.") );
373
374 return (wxXFont*) NULL;
375 }
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;
385}
386
387WXFontStructPtr wxFont::GetFontStruct(double scale, WXDisplay* display) const
388{
389 wxXFont* f = GetInternalFont(scale, display);
390
391 return (f ? f->m_fontStruct : (WXFontStructPtr) 0);
392}
393
394WXFontList wxFont::GetFontList(double scale, WXDisplay* display) const
395{
396 wxXFont* f = GetInternalFont(scale, display);
397
398 return (f ? f->m_fontList : (WXFontList) 0);
399}