]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/motif/font.cpp
some wxArtProv docs
[wxWidgets.git] / src / motif / font.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/motif/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#include "wx/vms_x_fix.h"
27#endif
28#include <Xm/Xm.h>
29#ifdef __VMS
30#pragma message enable nosimpint
31#endif
32
33#include "wx/defs.h"
34#include "wx/string.h"
35#include "wx/font.h"
36#include "wx/gdicmn.h"
37#include "wx/utils.h" // for wxGetDisplay()
38#include "wx/fontutil.h" // for wxNativeFontInfo
39#include "wx/tokenzr.h"
40#include "wx/settings.h"
41
42IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
43
44// ----------------------------------------------------------------------------
45// private classes
46// ----------------------------------------------------------------------------
47
48// For every wxFont, there must be a font for each display and scale requested.
49// So these objects are stored in wxFontRefData::m_fonts
50class wxXFont : public wxObject
51{
52public:
53 wxXFont();
54 ~wxXFont();
55
56 WXFontStructPtr m_fontStruct; // XFontStruct
57 WXFontList m_fontList; // Motif XmFontList
58 WXDisplay* m_display; // XDisplay
59 int m_scale; // Scale * 100
60};
61
62class wxFontRefData: public wxGDIRefData
63{
64friend class wxFont;
65
66public:
67 wxFontRefData(int size = wxDEFAULT,
68 int family = wxDEFAULT,
69 int style = wxDEFAULT,
70 int weight = wxDEFAULT,
71 bool underlined = FALSE,
72 const wxString& faceName = wxEmptyString,
73 wxFontEncoding encoding = wxFONTENCODING_DEFAULT)
74 {
75 Init(size, family, style, weight, underlined, faceName, encoding);
76 }
77
78 wxFontRefData(const wxFontRefData& data)
79 {
80 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
81 data.m_underlined, data.m_faceName, data.m_encoding);
82 }
83
84 ~wxFontRefData();
85
86protected:
87 // common part of all ctors
88 void Init(int size,
89 int family,
90 int style,
91 int weight,
92 bool underlined,
93 const wxString& faceName,
94 wxFontEncoding encoding);
95
96 // font attributes
97 int m_pointSize;
98 int m_family;
99 int m_style;
100 int m_weight;
101 bool m_underlined;
102 wxString m_faceName;
103 wxFontEncoding m_encoding;
104
105 wxNativeFontInfo m_nativeFontInfo;
106
107 // A list of wxXFonts
108 wxList m_fonts;
109};
110
111// ============================================================================
112// implementation
113// ============================================================================
114
115// ----------------------------------------------------------------------------
116// wxXFont
117// ----------------------------------------------------------------------------
118
119wxXFont::wxXFont()
120{
121 m_fontStruct = (WXFontStructPtr) 0;
122 m_fontList = (WXFontList) 0;
123 m_display = (WXDisplay*) 0;
124 m_scale = 100;
125}
126
127wxXFont::~wxXFont()
128{
129 XmFontList fontList = (XmFontList) m_fontList;
130
131 XmFontListFree (fontList);
132
133 // TODO: why does freeing the font produce a segv???
134 // Note that XFreeFont wasn't called in wxWin 1.68 either.
135 // XFontStruct* fontStruct = (XFontStruct*) m_fontStruct;
136 // XFreeFont((Display*) m_display, fontStruct);
137}
138
139// ----------------------------------------------------------------------------
140// wxFontRefData
141// ----------------------------------------------------------------------------
142
143void wxFontRefData::Init(int pointSize,
144 int family,
145 int style,
146 int weight,
147 bool underlined,
148 const wxString& faceName,
149 wxFontEncoding encoding)
150{
151 if (family == wxDEFAULT)
152 m_family = wxSWISS;
153 else
154 m_family = family;
155
156 m_faceName = faceName;
157
158 if (style == wxDEFAULT)
159 m_style = wxNORMAL;
160 else
161 m_style = style;
162
163 if (weight == wxDEFAULT)
164 m_weight = wxNORMAL;
165 else
166 m_weight = weight;
167
168 if (pointSize == wxDEFAULT)
169 m_pointSize = 12;
170 else
171 m_pointSize = pointSize;
172
173 m_underlined = underlined;
174 m_encoding = encoding;
175}
176
177wxFontRefData::~wxFontRefData()
178{
179 wxNode* node = m_fonts.First();
180 while (node)
181 {
182 wxXFont* f = (wxXFont*) node->Data();
183 delete f;
184 node = node->Next();
185 }
186 m_fonts.Clear();
187}
188
189// ----------------------------------------------------------------------------
190// wxFont
191// ----------------------------------------------------------------------------
192
193wxFont::wxFont(const wxNativeFontInfo& info)
194{
195 Init();
196
197 (void)Create(info.GetXFontName());
198}
199
200void wxFont::Init()
201{
202}
203
204bool wxFont::Create(int pointSize,
205 int family,
206 int style,
207 int weight,
208 bool underlined,
209 const wxString& faceName,
210 wxFontEncoding encoding)
211{
212 UnRef();
213 m_refData = new wxFontRefData(pointSize, family, style, weight,
214 underlined, faceName, encoding);
215
216 RealizeResource();
217
218 return TRUE;
219}
220
221bool wxFont::Create(const wxString& fontname, wxFontEncoding enc)
222{
223 if( !fontname )
224 {
225 *this = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT);
226 return TRUE;
227 }
228
229 m_refData = new wxFontRefData();
230
231 M_FONTDATA->m_nativeFontInfo.SetXFontName(fontname); // X font name
232
233 wxString tmp;
234
235 wxStringTokenizer tn( fontname, wxT("-") );
236
237 tn.GetNextToken(); // skip initial empty token
238 tn.GetNextToken(); // foundry
239
240
241 M_FONTDATA->m_faceName = tn.GetNextToken(); // family
242
243 tmp = tn.GetNextToken().MakeUpper(); // weight
244 if (tmp == wxT("BOLD")) M_FONTDATA->m_weight = wxBOLD;
245 if (tmp == wxT("BLACK")) M_FONTDATA->m_weight = wxBOLD;
246 if (tmp == wxT("EXTRABOLD")) M_FONTDATA->m_weight = wxBOLD;
247 if (tmp == wxT("DEMIBOLD")) M_FONTDATA->m_weight = wxBOLD;
248 if (tmp == wxT("ULTRABOLD")) M_FONTDATA->m_weight = wxBOLD;
249
250 if (tmp == wxT("LIGHT")) M_FONTDATA->m_weight = wxLIGHT;
251 if (tmp == wxT("THIN")) M_FONTDATA->m_weight = wxLIGHT;
252
253 tmp = tn.GetNextToken().MakeUpper(); // slant
254 if (tmp == wxT("I")) M_FONTDATA->m_style = wxITALIC;
255 if (tmp == wxT("O")) M_FONTDATA->m_style = wxITALIC;
256
257 tn.GetNextToken(); // set width
258 tn.GetNextToken(); // add. style
259 tn.GetNextToken(); // pixel size
260
261 tmp = tn.GetNextToken(); // pointsize
262 if (tmp != wxT("*"))
263 {
264 long num = wxStrtol (tmp.c_str(), (wxChar **) NULL, 10);
265 M_FONTDATA->m_pointSize = (int)(num / 10);
266 }
267
268 tn.GetNextToken(); // x-res
269 tn.GetNextToken(); // y-res
270
271 tmp = tn.GetNextToken().MakeUpper(); // spacing
272
273 if (tmp == wxT("M"))
274 M_FONTDATA->m_family = wxMODERN;
275 else if (M_FONTDATA->m_faceName == wxT("TIMES"))
276 M_FONTDATA->m_family = wxROMAN;
277 else if (M_FONTDATA->m_faceName == wxT("HELVETICA"))
278 M_FONTDATA->m_family = wxSWISS;
279 else if (M_FONTDATA->m_faceName == wxT("LUCIDATYPEWRITER"))
280 M_FONTDATA->m_family = wxTELETYPE;
281 else if (M_FONTDATA->m_faceName == wxT("LUCIDA"))
282 M_FONTDATA->m_family = wxDECORATIVE;
283 else if (M_FONTDATA->m_faceName == wxT("UTOPIA"))
284 M_FONTDATA->m_family = wxSCRIPT;
285
286 tn.GetNextToken(); // avg width
287
288 // deal with font encoding
289 M_FONTDATA->m_encoding = enc;
290 if ( M_FONTDATA->m_encoding == wxFONTENCODING_SYSTEM )
291 {
292 wxString registry = tn.GetNextToken().MakeUpper(),
293 encoding = tn.GetNextToken().MakeUpper();
294
295 if ( registry == _T("ISO8859") )
296 {
297 int cp;
298 if ( wxSscanf(encoding, wxT("%d"), &cp) == 1 )
299 {
300 M_FONTDATA->m_encoding =
301 (wxFontEncoding)(wxFONTENCODING_ISO8859_1 + cp - 1);
302 }
303 }
304 else if ( registry == _T("MICROSOFT") )
305 {
306 int cp;
307 if ( wxSscanf(encoding, wxT("cp125%d"), &cp) == 1 )
308 {
309 M_FONTDATA->m_encoding =
310 (wxFontEncoding)(wxFONTENCODING_CP1250 + cp);
311 }
312 }
313 else if ( registry == _T("KOI8") )
314 {
315 M_FONTDATA->m_encoding = wxFONTENCODING_KOI8;
316 }
317 //else: unknown encoding - may be give a warning here?
318 else
319 return FALSE;
320 }
321 return TRUE;
322}
323
324wxFont::~wxFont()
325{
326}
327
328// ----------------------------------------------------------------------------
329// change the font attributes
330// ----------------------------------------------------------------------------
331
332void wxFont::Unshare()
333{
334 // Don't change shared data
335 if (!m_refData)
336 {
337 m_refData = new wxFontRefData();
338 }
339 else
340 {
341 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
342 UnRef();
343 m_refData = ref;
344 }
345}
346
347void wxFont::SetPointSize(int pointSize)
348{
349 Unshare();
350
351 M_FONTDATA->m_pointSize = pointSize;
352 M_FONTDATA->m_nativeFontInfo.GetXFontName().Clear(); // invalid now
353
354 RealizeResource();
355}
356
357void wxFont::SetFamily(int family)
358{
359 Unshare();
360
361 M_FONTDATA->m_family = family;
362 M_FONTDATA->m_nativeFontInfo.GetXFontName().Clear(); // invalid now
363
364 RealizeResource();
365}
366
367void wxFont::SetStyle(int style)
368{
369 Unshare();
370
371 M_FONTDATA->m_style = style;
372 M_FONTDATA->m_nativeFontInfo.GetXFontName().Clear(); // invalid now
373
374 RealizeResource();
375}
376
377void wxFont::SetWeight(int weight)
378{
379 Unshare();
380
381 M_FONTDATA->m_weight = weight;
382 M_FONTDATA->m_nativeFontInfo.GetXFontName().Clear(); // invalid now
383
384 RealizeResource();
385}
386
387void wxFont::SetFaceName(const wxString& faceName)
388{
389 Unshare();
390
391 M_FONTDATA->m_faceName = faceName;
392 M_FONTDATA->m_nativeFontInfo.GetXFontName().Clear(); // invalid now
393
394 RealizeResource();
395}
396
397void wxFont::SetUnderlined(bool underlined)
398{
399 Unshare();
400
401 M_FONTDATA->m_underlined = underlined;
402
403 RealizeResource();
404}
405
406void wxFont::SetEncoding(wxFontEncoding encoding)
407{
408 Unshare();
409
410 M_FONTDATA->m_encoding = encoding;
411 M_FONTDATA->m_nativeFontInfo.GetXFontName().Clear(); // invalid now
412
413 RealizeResource();
414}
415
416void wxFont::SetNativeFontInfo(const wxNativeFontInfo& info)
417{
418 Unshare();
419
420 M_FONTDATA->m_nativeFontInfo = info;
421}
422
423// ----------------------------------------------------------------------------
424// query font attributes
425// ----------------------------------------------------------------------------
426
427int wxFont::GetPointSize() const
428{
429 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
430
431 return M_FONTDATA->m_pointSize;
432}
433
434wxString wxFont::GetFaceName() const
435{
436 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
437
438 return M_FONTDATA->m_faceName ;
439}
440
441int wxFont::GetFamily() const
442{
443 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
444
445 return M_FONTDATA->m_family;
446}
447
448int wxFont::GetStyle() const
449{
450 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
451
452 return M_FONTDATA->m_style;
453}
454
455int wxFont::GetWeight() const
456{
457 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
458
459 return M_FONTDATA->m_weight;
460}
461
462bool wxFont::GetUnderlined() const
463{
464 wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") );
465
466 return M_FONTDATA->m_underlined;
467}
468
469wxFontEncoding wxFont::GetEncoding() const
470{
471 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
472
473 return M_FONTDATA->m_encoding;
474}
475
476wxNativeFontInfo *wxFont::GetNativeFontInfo() const
477{
478 wxCHECK_MSG( Ok(), (wxNativeFontInfo *)NULL, wxT("invalid font") );
479
480 if(M_FONTDATA->m_nativeFontInfo.GetXFontName().IsEmpty())
481 GetInternalFont();
482
483 return new wxNativeFontInfo(M_FONTDATA->m_nativeFontInfo);
484}
485
486// ----------------------------------------------------------------------------
487// real implementation
488// ----------------------------------------------------------------------------
489
490// Find an existing, or create a new, XFontStruct
491// based on this wxFont and the given scale. Append the
492// font to list in the private data for future reference.
493wxXFont* wxFont::GetInternalFont(double scale, WXDisplay* display) const
494{
495 if ( !Ok() )
496 return (wxXFont *)NULL;
497
498 long intScale = long(scale * 100.0 + 0.5); // key for wxXFont
499 int pointSize = (M_FONTDATA->m_pointSize * 10 * intScale) / 100;
500
501 // search existing fonts first
502 wxNode* node = M_FONTDATA->m_fonts.First();
503 while (node)
504 {
505 wxXFont* f = (wxXFont*) node->Data();
506 if ((!display || (f->m_display == display)) && (f->m_scale == intScale))
507 return f;
508 node = node->Next();
509 }
510
511 // not found, create a new one
512 XFontStruct *font = (XFontStruct *)
513 wxLoadQueryNearestFont(pointSize,
514 M_FONTDATA->m_family,
515 M_FONTDATA->m_style,
516 M_FONTDATA->m_weight,
517 M_FONTDATA->m_underlined,
518 wxT(""),
519 M_FONTDATA->m_encoding);
520
521 if ( !font )
522 {
523 wxFAIL_MSG( wxT("Could not allocate even a default font -- something is wrong.") );
524
525 return (wxXFont*) NULL;
526 }
527
528 wxXFont* f = new wxXFont;
529 f->m_fontStruct = (WXFontStructPtr)font;
530 f->m_display = ( display ? display : wxGetDisplay() );
531 f->m_scale = intScale;
532 f->m_fontList = XmFontListCreate ((XFontStruct*) font, XmSTRING_DEFAULT_CHARSET);
533 M_FONTDATA->m_fonts.Append(f);
534
535 return f;
536}
537
538WXFontStructPtr wxFont::GetFontStruct(double scale, WXDisplay* display) const
539{
540 wxXFont* f = GetInternalFont(scale, display);
541
542 return (f ? f->m_fontStruct : (WXFontStructPtr) 0);
543}
544
545WXFontList wxFont::GetFontList(double scale, WXDisplay* display) const
546{
547 wxXFont* f = GetInternalFont(scale, display);
548
549 return (f ? f->m_fontList : (WXFontList) 0);
550}
551