]> git.saurik.com Git - wxWidgets.git/blob - src/common/fontcmn.cpp
safe destruction, even if redraws might be triggered
[wxWidgets.git] / src / common / fontcmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: common/fontcmn.cpp
3 // Purpose: implementation of wxFontBase methods
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 20.09.99
7 // RCS-ID: $Id$
8 // Copyright: (c) wxWindows team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "fontbase.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/font.h"
33 #include "wx/intl.h"
34 #endif // WX_PRECOMP
35
36 #include "wx/gdicmn.h"
37
38 #if defined(__WXMSW__)
39 #include "wx/msw/private.h" // includes windows.h for LOGFONT
40 #include "wx/msw/winundef.h"
41 #endif
42
43 #include "wx/fontutil.h" // for wxNativeFontInfo
44 #include "wx/fontmap.h"
45
46 #include "wx/tokenzr.h"
47
48 // ============================================================================
49 // implementation
50 // ============================================================================
51
52 // ----------------------------------------------------------------------------
53 // wxFontBase
54 // ----------------------------------------------------------------------------
55
56 wxFontEncoding wxFontBase::ms_encodingDefault = wxFONTENCODING_SYSTEM;
57
58 /* static */
59 void wxFontBase::SetDefaultEncoding(wxFontEncoding encoding)
60 {
61 // GetDefaultEncoding() should return something != wxFONTENCODING_DEFAULT
62 // and, besides, using this value here doesn't make any sense
63 wxCHECK_RET( encoding != wxFONTENCODING_DEFAULT,
64 _T("can't set default encoding to wxFONTENCODING_DEFAULT") );
65
66 ms_encodingDefault = encoding;
67 }
68
69 wxFontBase::~wxFontBase()
70 {
71 // this destructor is required for Darwin
72 }
73
74 /* static */
75 wxFont *wxFontBase::New(int size,
76 int family,
77 int style,
78 int weight,
79 bool underlined,
80 const wxString& face,
81 wxFontEncoding encoding)
82 {
83 return new wxFont(size, family, style, weight, underlined, face, encoding);
84 }
85
86 /* static */
87 wxFont *wxFontBase::New(int pointSize,
88 wxFontFamily family,
89 int flags,
90 const wxString& face,
91 wxFontEncoding encoding)
92 {
93 return New
94 (
95 pointSize,
96 family,
97 flags & wxFONTFLAG_ITALIC
98 ? wxFONTSTYLE_ITALIC
99 : flags & wxFONTFLAG_SLANT
100 ? wxFONTSTYLE_SLANT
101 : wxFONTSTYLE_NORMAL,
102 flags & wxFONTFLAG_LIGHT
103 ? wxFONTWEIGHT_LIGHT
104 : flags & wxFONTFLAG_BOLD
105 ? wxFONTWEIGHT_BOLD
106 : wxFONTWEIGHT_NORMAL,
107 (flags & wxFONTFLAG_UNDERLINED) != 0,
108 face,
109 encoding
110 );
111 }
112
113 /* static */
114 wxFont *wxFontBase::New(const wxNativeFontInfo& info)
115 {
116 return new wxFont(info);
117 }
118
119 /* static */
120 wxFont *wxFontBase::New(const wxString& strNativeFontDesc)
121 {
122 wxNativeFontInfo fontInfo;
123 if ( !fontInfo.FromString(strNativeFontDesc) )
124 return new wxFont(*wxNORMAL_FONT);
125
126 return New(fontInfo);
127 }
128
129 bool wxFontBase::IsFixedWidth() const
130 {
131 return GetFamily() == wxFONTFAMILY_TELETYPE;
132 }
133
134 void wxFontBase::DoSetNativeFontInfo(const wxNativeFontInfo& info)
135 {
136 #ifdef wxNO_NATIVE_FONTINFO
137 SetPointSize(info.pointSize);
138 SetFamily(info.family);
139 SetStyle(info.style);
140 SetWeight(info.weight);
141 SetUnderlined(info.underlined);
142 SetFaceName(info.faceName);
143 SetEncoding(info.encoding);
144 #else
145 (void)info;
146 #endif
147 }
148
149 wxString wxFontBase::GetNativeFontInfoDesc() const
150 {
151 wxString fontDesc;
152 const wxNativeFontInfo *fontInfo = GetNativeFontInfo();
153 if ( fontInfo )
154 {
155 fontDesc = fontInfo->ToString();
156 }
157
158 return fontDesc;
159 }
160
161 wxString wxFontBase::GetNativeFontInfoUserDesc() const
162 {
163 wxString fontDesc;
164 const wxNativeFontInfo *fontInfo = GetNativeFontInfo();
165 if ( fontInfo )
166 {
167 fontDesc = fontInfo->ToUserString();
168 }
169
170 return fontDesc;
171 }
172
173 void wxFontBase::SetNativeFontInfo(const wxString& info)
174 {
175 wxNativeFontInfo fontInfo;
176 if ( !info.empty() && fontInfo.FromString(info) )
177 {
178 SetNativeFontInfo(fontInfo);
179 }
180 }
181
182 void wxFontBase::SetNativeFontInfoUserDesc(const wxString& info)
183 {
184 wxNativeFontInfo fontInfo;
185 if ( !info.empty() && fontInfo.FromUserString(info) )
186 {
187 SetNativeFontInfo(fontInfo);
188 }
189 }
190
191 wxFont& wxFont::operator=(const wxFont& font)
192 {
193 if ( this != &font )
194 Ref(font);
195
196 return (wxFont &)*this;
197 }
198
199 bool wxFontBase::operator==(const wxFont& font) const
200 {
201 // either it is the same font, i.e. they share the same common data or they
202 // have different ref datas but still describe the same font
203 return GetFontData() == font.GetFontData() ||
204 (
205 Ok() == font.Ok() &&
206 GetPointSize() == font.GetPointSize() &&
207 GetFamily() == font.GetFamily() &&
208 GetStyle() == font.GetStyle() &&
209 GetWeight() == font.GetWeight() &&
210 GetUnderlined() == font.GetUnderlined() &&
211 GetFaceName() == font.GetFaceName() &&
212 GetEncoding() == font.GetEncoding()
213 );
214 }
215
216 bool wxFontBase::operator!=(const wxFont& font) const
217 {
218 return !(*this == font);
219 }
220
221 wxString wxFontBase::GetFamilyString() const
222 {
223 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
224
225 switch ( GetFamily() )
226 {
227 case wxDECORATIVE: return wxT("wxDECORATIVE");
228 case wxROMAN: return wxT("wxROMAN");
229 case wxSCRIPT: return wxT("wxSCRIPT");
230 case wxSWISS: return wxT("wxSWISS");
231 case wxMODERN: return wxT("wxMODERN");
232 case wxTELETYPE: return wxT("wxTELETYPE");
233 default: return wxT("wxDEFAULT");
234 }
235 }
236
237 wxString wxFontBase::GetStyleString() const
238 {
239 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
240
241 switch ( GetStyle() )
242 {
243 case wxNORMAL: return wxT("wxNORMAL");
244 case wxSLANT: return wxT("wxSLANT");
245 case wxITALIC: return wxT("wxITALIC");
246 default: return wxT("wxDEFAULT");
247 }
248 }
249
250 wxString wxFontBase::GetWeightString() const
251 {
252 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
253
254 switch ( GetWeight() )
255 {
256 case wxNORMAL: return wxT("wxNORMAL");
257 case wxBOLD: return wxT("wxBOLD");
258 case wxLIGHT: return wxT("wxLIGHT");
259 default: return wxT("wxDEFAULT");
260 }
261 }
262
263 // ----------------------------------------------------------------------------
264 // wxNativeFontInfo
265 // ----------------------------------------------------------------------------
266
267 #ifdef wxNO_NATIVE_FONTINFO
268
269 // These are the generic forms of FromString()/ToString.
270 //
271 // convert to/from the string representation: format is
272 // version;pointsize;family;style;weight;underlined;facename;encoding
273
274 bool wxNativeFontInfo::FromString(const wxString& s)
275 {
276 long l;
277
278 wxStringTokenizer tokenizer(s, _T(";"));
279
280 wxString token = tokenizer.GetNextToken();
281 //
282 // Ignore the version for now
283 //
284
285 token = tokenizer.GetNextToken();
286 if ( !token.ToLong(&l) )
287 return FALSE;
288 pointSize = (int)l;
289
290 token = tokenizer.GetNextToken();
291 if ( !token.ToLong(&l) )
292 return FALSE;
293 family = (wxFontFamily)l;
294
295 token = tokenizer.GetNextToken();
296 if ( !token.ToLong(&l) )
297 return FALSE;
298 style = (wxFontStyle)l;
299
300 token = tokenizer.GetNextToken();
301 if ( !token.ToLong(&l) )
302 return FALSE;
303 weight = (wxFontWeight)l;
304
305 token = tokenizer.GetNextToken();
306 if ( !token.ToLong(&l) )
307 return FALSE;
308 underlined = l != 0;
309
310 faceName = tokenizer.GetNextToken();
311
312 #ifndef __WXMAC__
313 if( !faceName )
314 return FALSE;
315 #endif
316
317 token = tokenizer.GetNextToken();
318 if ( !token.ToLong(&l) )
319 return FALSE;
320 encoding = (wxFontEncoding)l;
321
322 return TRUE;
323 }
324
325 wxString wxNativeFontInfo::ToString() const
326 {
327 wxString s;
328
329 s.Printf(_T("%d;%d;%d;%d;%d;%d;%s;%d"),
330 0, // version
331 pointSize,
332 family,
333 (int)style,
334 (int)weight,
335 underlined,
336 faceName.GetData(),
337 (int)encoding);
338
339 return s;
340 }
341
342 void wxNativeFontInfo::Init()
343 {
344 pointSize = 0;
345 family = wxFONTFAMILY_DEFAULT;
346 style = wxFONTSTYLE_NORMAL;
347 weight = wxFONTWEIGHT_NORMAL;
348 underlined = FALSE;
349 faceName.clear();
350 encoding = wxFONTENCODING_DEFAULT;
351 }
352
353 int wxNativeFontInfo::GetPointSize() const
354 {
355 return pointSize;
356 }
357
358 wxFontStyle wxNativeFontInfo::GetStyle() const
359 {
360 return style;
361 }
362
363 wxFontWeight wxNativeFontInfo::GetWeight() const
364 {
365 return weight;
366 }
367
368 bool wxNativeFontInfo::GetUnderlined() const
369 {
370 return underlined;
371 }
372
373 wxString wxNativeFontInfo::GetFaceName() const
374 {
375 return faceName;
376 }
377
378 wxFontFamily wxNativeFontInfo::GetFamily() const
379 {
380 return family;
381 }
382
383 wxFontEncoding wxNativeFontInfo::GetEncoding() const
384 {
385 return encoding;
386 }
387
388 void wxNativeFontInfo::SetPointSize(int pointsize)
389 {
390 pointSize = pointsize;
391 }
392
393 void wxNativeFontInfo::SetStyle(wxFontStyle style_)
394 {
395 style = style_;
396 }
397
398 void wxNativeFontInfo::SetWeight(wxFontWeight weight_)
399 {
400 weight = weight_;
401 }
402
403 void wxNativeFontInfo::SetUnderlined(bool underlined_)
404 {
405 underlined = underlined_;
406 }
407
408 void wxNativeFontInfo::SetFaceName(wxString facename_)
409 {
410 faceName = facename_;
411 }
412
413 void wxNativeFontInfo::SetFamily(wxFontFamily family_)
414 {
415 family = family_;
416 }
417
418 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
419 {
420 encoding = encoding_;
421 }
422
423 #endif // generic wxNativeFontInfo implementation
424
425 // conversion to/from user-readable string: this is used in the generic
426 // versions and under MSW as well because there is no standard font description
427 // format there anyhow (but there is a well-defined standard for X11 fonts used
428 // by wxGTK and wxMotif)
429
430 #if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__)
431
432 wxString wxNativeFontInfo::ToUserString() const
433 {
434 wxString desc;
435
436 // first put the adjectives, if any - this is English-centric, of course,
437 // but what else can we do?
438 if ( GetUnderlined() )
439 {
440 desc << _("underlined ");
441 }
442
443 switch ( GetWeight() )
444 {
445 default:
446 wxFAIL_MSG( _T("unknown font weight") );
447 // fall through
448
449 case wxFONTWEIGHT_NORMAL:
450 break;
451
452 case wxFONTWEIGHT_LIGHT:
453 desc << _("light ");
454 break;
455
456 case wxFONTWEIGHT_BOLD:
457 desc << _("bold ");
458 break;
459 }
460
461 switch ( GetStyle() )
462 {
463 default:
464 wxFAIL_MSG( _T("unknown font style") );
465 // fall through
466
467 case wxFONTSTYLE_NORMAL:
468 break;
469
470 // we don't distinguish between the two for now anyhow...
471 case wxFONTSTYLE_ITALIC:
472 case wxFONTSTYLE_SLANT:
473 desc << _("italic");
474 break;
475 }
476
477 wxString face = GetFaceName();
478 if ( !face.empty() )
479 {
480 desc << _T(' ') << face;
481 }
482
483 int size = GetPointSize();
484 if ( size != wxNORMAL_FONT->GetPointSize() )
485 {
486 desc << _T(' ') << size;
487 }
488
489 #if wxUSE_FONTMAP
490 wxFontEncoding enc = GetEncoding();
491 if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM )
492 {
493 desc << _T(' ') << wxFontMapper::Get()->GetEncodingName(enc);
494 }
495 #endif // wxUSE_FONTMAP
496
497 return desc;
498 }
499
500 bool wxNativeFontInfo::FromUserString(const wxString& s)
501 {
502 // reset to the default state
503 Init();
504
505 // parse a more or less free form string
506 //
507 // TODO: we should handle at least the quoted facenames
508 wxStringTokenizer tokenizer(s, _T(";, "), wxTOKEN_STRTOK);
509
510 wxString face;
511 unsigned long size;
512
513 #if wxUSE_FONTMAP
514 wxFontEncoding encoding;
515 #endif // wxUSE_FONTMAP
516
517 while ( tokenizer.HasMoreTokens() )
518 {
519 wxString token = tokenizer.GetNextToken();
520
521 // normalize it
522 token.Trim(TRUE).Trim(FALSE).MakeLower();
523
524 // look for the known tokens
525 if ( token == _T("underlined") || token == _("underlined") )
526 {
527 SetUnderlined(TRUE);
528 }
529 else if ( token == _T("light") || token == _("light") )
530 {
531 SetWeight(wxFONTWEIGHT_LIGHT);
532 }
533 else if ( token == _T("bold") || token == _("bold") )
534 {
535 SetWeight(wxFONTWEIGHT_BOLD);
536 }
537 else if ( token == _T("italic") || token == _("italic") )
538 {
539 SetStyle(wxFONTSTYLE_ITALIC);
540 }
541 else if ( token.ToULong(&size) )
542 {
543 SetPointSize(size);
544 }
545 #if wxUSE_FONTMAP
546 else if ( (encoding = wxFontMapper::Get()->CharsetToEncoding(token, FALSE))
547 != wxFONTENCODING_DEFAULT )
548 {
549 SetEncoding(encoding);
550 }
551 #endif // wxUSE_FONTMAP
552 else // assume it is the face name
553 {
554 if ( !face.empty() )
555 {
556 face += _T(' ');
557 }
558
559 face += token;
560
561 // skip the code which resets face below
562 continue;
563 }
564
565 // if we had had the facename, we shouldn't continue appending tokens
566 // to it (i.e. "foo bold bar" shouldn't result in the facename "foo
567 // bar")
568 if ( !face.empty() )
569 {
570 SetFaceName(face);
571 face.clear();
572 }
573 }
574
575 // we might not have flushed it inside the loop
576 if ( !face.empty() )
577 {
578 SetFaceName(face);
579 }
580
581 return TRUE;
582 }
583
584 #endif // generic or wxMSW or wxOS2
585