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