]> git.saurik.com Git - wxWidgets.git/blob - src/motif/font.cpp
Still no such thing as gtkfeatures.h in gtk+ 1.3.1...
[wxWidgets.git] / src / motif / font.cpp
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 #ifdef __VMS
25 #pragma message disable nosimpint
26 #endif
27 #include <Xm/Xm.h>
28 #ifdef __VMS
29 #pragma message enable nosimpint
30 #endif
31
32 #include "wx/defs.h"
33 #include "wx/string.h"
34 #include "wx/font.h"
35 #include "wx/gdicmn.h"
36 #include "wx/utils.h" // for wxGetDisplay()
37 #include "wx/fontutil.h"
38
39 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
40
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
47 class wxXFont : public wxObject
48 {
49 public:
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
59 class wxFontRefData: public wxGDIRefData
60 {
61 friend class wxFont;
62
63 public:
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
83 protected:
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
114 wxXFont::wxXFont()
115 {
116 m_fontStruct = (WXFontStructPtr) 0;
117 m_fontList = (WXFontList) 0;
118 m_display = (WXDisplay*) 0;
119 m_scale = 100;
120 }
121
122 wxXFont::~wxXFont()
123 {
124 XmFontList fontList = (XmFontList) m_fontList;
125
126 XmFontListFree (fontList);
127
128 // TODO: why does freeing the font produce a segv???
129 // Note that XFreeFont wasn't called in wxWin 1.68 either.
130 // XFontStruct* fontStruct = (XFontStruct*) m_fontStruct;
131 // XFreeFont((Display*) m_display, fontStruct);
132 }
133
134 // ----------------------------------------------------------------------------
135 // wxFontRefData
136 // ----------------------------------------------------------------------------
137
138 void wxFontRefData::Init(int pointSize,
139 int family,
140 int style,
141 int weight,
142 bool underlined,
143 const wxString& faceName,
144 wxFontEncoding encoding)
145 {
146 if (family == wxDEFAULT)
147 m_family = wxSWISS;
148 else
149 m_family = family;
150
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;
170 }
171
172 wxFontRefData::~wxFontRefData()
173 {
174 wxNode* node = m_fonts.First();
175 while (node)
176 {
177 wxXFont* f = (wxXFont*) node->Data();
178 delete f;
179 node = node->Next();
180 }
181 m_fonts.Clear();
182 }
183
184 // ----------------------------------------------------------------------------
185 // wxFont
186 // ----------------------------------------------------------------------------
187
188 void wxFont::Init()
189 {
190 if ( wxTheFontList )
191 wxTheFontList->Append(this);
192 }
193
194 bool wxFont::Create(int pointSize,
195 int family,
196 int style,
197 int weight,
198 bool underlined,
199 const wxString& faceName,
200 wxFontEncoding encoding)
201 {
202 UnRef();
203 m_refData = new wxFontRefData(pointSize, family, style, weight,
204 underlined, faceName, encoding);
205
206 RealizeResource();
207
208 return TRUE;
209 }
210
211 wxFont::~wxFont()
212 {
213 if ( wxTheFontList )
214 wxTheFontList->DeleteObject(this);
215 }
216
217 // ----------------------------------------------------------------------------
218 // change the font attributes
219 // ----------------------------------------------------------------------------
220
221 void wxFont::Unshare()
222 {
223 // Don't change shared data
224 if (!m_refData)
225 {
226 m_refData = new wxFontRefData();
227 }
228 else
229 {
230 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
231 UnRef();
232 m_refData = ref;
233 }
234 }
235
236 void wxFont::SetPointSize(int pointSize)
237 {
238 Unshare();
239
240 M_FONTDATA->m_pointSize = pointSize;
241
242 RealizeResource();
243 }
244
245 void wxFont::SetFamily(int family)
246 {
247 Unshare();
248
249 M_FONTDATA->m_family = family;
250
251 RealizeResource();
252 }
253
254 void wxFont::SetStyle(int style)
255 {
256 Unshare();
257
258 M_FONTDATA->m_style = style;
259
260 RealizeResource();
261 }
262
263 void wxFont::SetWeight(int weight)
264 {
265 Unshare();
266
267 M_FONTDATA->m_weight = weight;
268
269 RealizeResource();
270 }
271
272 void wxFont::SetFaceName(const wxString& faceName)
273 {
274 Unshare();
275
276 M_FONTDATA->m_faceName = faceName;
277
278 RealizeResource();
279 }
280
281 void wxFont::SetUnderlined(bool underlined)
282 {
283 Unshare();
284
285 M_FONTDATA->m_underlined = underlined;
286
287 RealizeResource();
288 }
289
290 void wxFont::SetEncoding(wxFontEncoding encoding)
291 {
292 Unshare();
293
294 M_FONTDATA->m_encoding = encoding;
295
296 RealizeResource();
297 }
298
299 // ----------------------------------------------------------------------------
300 // query font attributes
301 // ----------------------------------------------------------------------------
302
303 int wxFont::GetPointSize() const
304 {
305 return M_FONTDATA->m_pointSize;
306 }
307
308 int wxFont::GetFamily() const
309 {
310 return M_FONTDATA->m_family;
311 }
312
313 int wxFont::GetStyle() const
314 {
315 return M_FONTDATA->m_style;
316 }
317
318 int wxFont::GetWeight() const
319 {
320 return M_FONTDATA->m_weight;
321 }
322
323 bool wxFont::GetUnderlined() const
324 {
325 return M_FONTDATA->m_underlined;
326 }
327
328 wxString wxFont::GetFaceName() const
329 {
330 wxString str;
331 if ( M_FONTDATA )
332 str = M_FONTDATA->m_faceName ;
333 return str;
334 }
335
336 wxFontEncoding wxFont::GetEncoding() const
337 {
338 return M_FONTDATA->m_encoding;
339 }
340
341 // ----------------------------------------------------------------------------
342 // real implementation
343 // ----------------------------------------------------------------------------
344
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.
348 wxXFont* wxFont::GetInternalFont(double scale, WXDisplay* display) const
349 {
350 if ( !Ok() )
351 return (wxXFont *)NULL;
352
353 long intScale = long(scale * 100.0 + 0.5); // key for wxXFont
354 int pointSize = (M_FONTDATA->m_pointSize * 10 * intScale) / 100;
355
356 // search existing fonts first
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 }
365
366 // not found, create a new one
367 XFontStruct *font = (XFontStruct *)
368 wxLoadQueryNearestFont(pointSize,
369 M_FONTDATA->m_family,
370 M_FONTDATA->m_style,
371 M_FONTDATA->m_weight,
372 M_FONTDATA->m_underlined,
373 wxT(""),
374 M_FONTDATA->m_encoding);
375
376 if ( !font )
377 {
378 wxFAIL_MSG( wxT("Could not allocate even a default font -- something is wrong.") );
379
380 return (wxXFont*) NULL;
381 }
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;
391 }
392
393 WXFontStructPtr wxFont::GetFontStruct(double scale, WXDisplay* display) const
394 {
395 wxXFont* f = GetInternalFont(scale, display);
396
397 return (f ? f->m_fontStruct : (WXFontStructPtr) 0);
398 }
399
400 WXFontList wxFont::GetFontList(double scale, WXDisplay* display) const
401 {
402 wxXFont* f = GetInternalFont(scale, display);
403
404 return (f ? f->m_fontList : (WXFontList) 0);
405 }