]> git.saurik.com Git - wxWidgets.git/blame - src/common/fontcmn.cpp
Applied [ 821234 ] Fix: erroneous assertion failed wxListBox::SetSelection
[wxWidgets.git] / src / common / fontcmn.cpp
CommitLineData
0c5d3e1c
VZ
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
55d99c7a 9// Licence: wxWindows licence
0c5d3e1c
VZ
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
14f355c2 20#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
01610529 21#pragma implementation "fontbase.h"
1b68e0b5
RR
22#endif
23
0c5d3e1c
VZ
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
01610529 28#pragma hdrstop
0c5d3e1c
VZ
29#endif
30
31#ifndef WX_PRECOMP
01610529
RL
32#include "wx/font.h"
33#include "wx/intl.h"
0c5d3e1c
VZ
34#endif // WX_PRECOMP
35
09fcd889 36#include "wx/gdicmn.h"
1c193821
JS
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
76e23cdb 43#include "wx/fontutil.h" // for wxNativeFontInfo
ab5fe833 44#include "wx/fontmap.h"
76e23cdb 45
30764ab5
VZ
46#include "wx/tokenzr.h"
47
0c5d3e1c
VZ
48// ============================================================================
49// implementation
50// ============================================================================
51
52// ----------------------------------------------------------------------------
53// wxFontBase
54// ----------------------------------------------------------------------------
55
56wxFontEncoding wxFontBase::ms_encodingDefault = wxFONTENCODING_SYSTEM;
57
cafbf6fb
VZ
58/* static */
59void 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
799ea011
GD
69wxFontBase::~wxFontBase()
70{
71 // this destructor is required for Darwin
72}
73
7beba2fc 74/* static */
0c5d3e1c
VZ
75wxFont *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
01cb1c26
VZ
86/* static */
87wxFont *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
30764ab5
VZ
113/* static */
114wxFont *wxFontBase::New(const wxNativeFontInfo& info)
115{
116 return new wxFont(info);
117}
118
7826e2dd
VZ
119/* static */
120wxFont *wxFontBase::New(const wxString& strNativeFontDesc)
30764ab5 121{
30764ab5 122 wxNativeFontInfo fontInfo;
7826e2dd 123 if ( !fontInfo.FromString(strNativeFontDesc) )
09fcd889 124 return new wxFont(*wxNORMAL_FONT);
7826e2dd
VZ
125
126 return New(fontInfo);
127}
128
53f6aab7
VZ
129bool wxFontBase::IsFixedWidth() const
130{
131 return GetFamily() == wxFONTFAMILY_TELETYPE;
132}
133
9045ad9d 134void wxFontBase::DoSetNativeFontInfo(const wxNativeFontInfo& info)
30764ab5 135{
ab5fe833 136#ifdef wxNO_NATIVE_FONTINFO
30764ab5
VZ
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);
33ac7e6f 144#else
1e6feb95 145 (void)info;
30764ab5
VZ
146#endif
147}
148
7826e2dd
VZ
149wxString wxFontBase::GetNativeFontInfoDesc() const
150{
151 wxString fontDesc;
3bf5a59b 152 const wxNativeFontInfo *fontInfo = GetNativeFontInfo();
7826e2dd
VZ
153 if ( fontInfo )
154 {
155 fontDesc = fontInfo->ToString();
7826e2dd
VZ
156 }
157
158 return fontDesc;
159}
160
ab5fe833
VZ
161wxString wxFontBase::GetNativeFontInfoUserDesc() const
162{
163 wxString fontDesc;
3bf5a59b 164 const wxNativeFontInfo *fontInfo = GetNativeFontInfo();
ab5fe833
VZ
165 if ( fontInfo )
166 {
167 fontDesc = fontInfo->ToUserString();
ab5fe833
VZ
168 }
169
170 return fontDesc;
171}
172
31d1b66e
VZ
173void wxFontBase::SetNativeFontInfo(const wxString& info)
174{
175 wxNativeFontInfo fontInfo;
176 if ( !info.empty() && fontInfo.FromString(info) )
177 {
178 SetNativeFontInfo(fontInfo);
179 }
180}
181
ab5fe833
VZ
182void wxFontBase::SetNativeFontInfoUserDesc(const wxString& info)
183{
184 wxNativeFontInfo fontInfo;
185 if ( !info.empty() && fontInfo.FromUserString(info) )
186 {
187 SetNativeFontInfo(fontInfo);
188 }
189}
190
0c5d3e1c
VZ
191wxFont& wxFont::operator=(const wxFont& font)
192{
193 if ( this != &font )
194 Ref(font);
195
196 return (wxFont &)*this;
197}
198
0c5d3e1c
VZ
199bool wxFontBase::operator==(const wxFont& font) const
200{
8bf30fe9
VZ
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() &&
e6adf058 209 GetWeight() == font.GetWeight() &&
8bf30fe9
VZ
210 GetUnderlined() == font.GetUnderlined() &&
211 GetFaceName() == font.GetFaceName() &&
212 GetEncoding() == font.GetEncoding()
213 );
0c5d3e1c
VZ
214}
215
216bool wxFontBase::operator!=(const wxFont& font) const
217{
8bf30fe9 218 return !(*this == font);
0c5d3e1c
VZ
219}
220
221wxString wxFontBase::GetFamilyString() const
222{
223d09f6 223 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
0c5d3e1c
VZ
224
225 switch ( GetFamily() )
226 {
223d09f6
KB
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");
0c5d3e1c
VZ
234 }
235}
236
237wxString wxFontBase::GetStyleString() const
238{
223d09f6 239 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
0c5d3e1c
VZ
240
241 switch ( GetStyle() )
242 {
223d09f6
KB
243 case wxNORMAL: return wxT("wxNORMAL");
244 case wxSLANT: return wxT("wxSLANT");
245 case wxITALIC: return wxT("wxITALIC");
246 default: return wxT("wxDEFAULT");
0c5d3e1c
VZ
247 }
248}
249
250wxString wxFontBase::GetWeightString() const
251{
223d09f6 252 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
0c5d3e1c
VZ
253
254 switch ( GetWeight() )
255 {
223d09f6
KB
256 case wxNORMAL: return wxT("wxNORMAL");
257 case wxBOLD: return wxT("wxBOLD");
258 case wxLIGHT: return wxT("wxLIGHT");
259 default: return wxT("wxDEFAULT");
0c5d3e1c
VZ
260 }
261}
262
30764ab5
VZ
263// ----------------------------------------------------------------------------
264// wxNativeFontInfo
265// ----------------------------------------------------------------------------
266
ab5fe833
VZ
267#ifdef wxNO_NATIVE_FONTINFO
268
30764ab5
VZ
269// These are the generic forms of FromString()/ToString.
270//
271// convert to/from the string representation: format is
09fcd889 272// version;pointsize;family;style;weight;underlined;facename;encoding
30764ab5
VZ
273
274bool wxNativeFontInfo::FromString(const wxString& s)
275{
276 long l;
277
278 wxStringTokenizer tokenizer(s, _T(";"));
279
280 wxString token = tokenizer.GetNextToken();
09fcd889
VZ
281 //
282 // Ignore the version for now
283 //
33ac7e6f 284
09fcd889 285 token = tokenizer.GetNextToken();
30764ab5
VZ
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;
f7b301fa 293 family = (wxFontFamily)l;
30764ab5
VZ
294
295 token = tokenizer.GetNextToken();
296 if ( !token.ToLong(&l) )
297 return FALSE;
ab5fe833 298 style = (wxFontStyle)l;
30764ab5
VZ
299
300 token = tokenizer.GetNextToken();
301 if ( !token.ToLong(&l) )
302 return FALSE;
ab5fe833 303 weight = (wxFontWeight)l;
30764ab5
VZ
304
305 token = tokenizer.GetNextToken();
306 if ( !token.ToLong(&l) )
307 return FALSE;
189e08b4 308 underlined = l != 0;
30764ab5
VZ
309
310 faceName = tokenizer.GetNextToken();
0a9f0ef7
JS
311
312#ifndef __WXMAC__
30764ab5
VZ
313 if( !faceName )
314 return FALSE;
0a9f0ef7 315#endif
30764ab5
VZ
316
317 token = tokenizer.GetNextToken();
318 if ( !token.ToLong(&l) )
319 return FALSE;
320 encoding = (wxFontEncoding)l;
321
322 return TRUE;
323}
324
325wxString wxNativeFontInfo::ToString() const
326{
327 wxString s;
328
09fcd889
VZ
329 s.Printf(_T("%d;%d;%d;%d;%d;%d;%s;%d"),
330 0, // version
30764ab5
VZ
331 pointSize,
332 family,
ab5fe833
VZ
333 (int)style,
334 (int)weight,
30764ab5
VZ
335 underlined,
336 faceName.GetData(),
337 (int)encoding);
338
339 return s;
340}
341
ab5fe833
VZ
342void wxNativeFontInfo::Init()
343{
3bf5a59b 344 pointSize = 0;
ab5fe833
VZ
345 family = wxFONTFAMILY_DEFAULT;
346 style = wxFONTSTYLE_NORMAL;
347 weight = wxFONTWEIGHT_NORMAL;
348 underlined = FALSE;
349 faceName.clear();
350 encoding = wxFONTENCODING_DEFAULT;
351}
352
353int wxNativeFontInfo::GetPointSize() const
354{
355 return pointSize;
356}
357
358wxFontStyle wxNativeFontInfo::GetStyle() const
359{
360 return style;
361}
362
363wxFontWeight wxNativeFontInfo::GetWeight() const
364{
365 return weight;
366}
367
368bool wxNativeFontInfo::GetUnderlined() const
369{
370 return underlined;
371}
372
373wxString wxNativeFontInfo::GetFaceName() const
374{
375 return faceName;
376}
377
7936354d
VZ
378wxFontFamily wxNativeFontInfo::GetFamily() const
379{
380 return family;
381}
382
ab5fe833
VZ
383wxFontEncoding wxNativeFontInfo::GetEncoding() const
384{
385 return encoding;
386}
387
388void wxNativeFontInfo::SetPointSize(int pointsize)
389{
390 pointSize = pointsize;
391}
392
393void wxNativeFontInfo::SetStyle(wxFontStyle style_)
394{
395 style = style_;
396}
397
398void wxNativeFontInfo::SetWeight(wxFontWeight weight_)
399{
400 weight = weight_;
401}
402
403void wxNativeFontInfo::SetUnderlined(bool underlined_)
404{
405 underlined = underlined_;
406}
407
408void wxNativeFontInfo::SetFaceName(wxString facename_)
409{
f7b301fa 410 faceName = facename_;
ab5fe833
VZ
411}
412
3f1d1373 413void wxNativeFontInfo::SetFamily(wxFontFamily family_)
7936354d
VZ
414{
415 family = family_;
416}
417
ab5fe833
VZ
418void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
419{
420 encoding = encoding_;
421}
422
7826e2dd 423#endif // generic wxNativeFontInfo implementation
30764ab5 424
ab5fe833
VZ
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
0eb529d9 430#if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__)
ab5fe833
VZ
431
432wxString 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:
a9249b2e 473 desc << _("italic");
ab5fe833
VZ
474 break;
475 }
476
a9249b2e
VZ
477 wxString face = GetFaceName();
478 if ( !face.empty() )
ab5fe833 479 {
a9249b2e 480 desc << _T(' ') << face;
ab5fe833
VZ
481 }
482
a9249b2e
VZ
483 int size = GetPointSize();
484 if ( size != wxNORMAL_FONT->GetPointSize() )
ab5fe833 485 {
a9249b2e 486 desc << _T(' ') << size;
ab5fe833 487 }
a9249b2e 488
e7e52b6d 489#if wxUSE_FONTMAP
a9249b2e
VZ
490 wxFontEncoding enc = GetEncoding();
491 if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM )
492 {
142b3bc2 493 desc << _T(' ') << wxFontMapper::Get()->GetEncodingName(enc);
a9249b2e 494 }
e7e52b6d 495#endif // wxUSE_FONTMAP
a9249b2e
VZ
496
497 return desc;
ab5fe833
VZ
498}
499
500bool 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;
e7e52b6d
VZ
512
513#if wxUSE_FONTMAP
ab5fe833 514 wxFontEncoding encoding;
e7e52b6d 515#endif // wxUSE_FONTMAP
ab5fe833
VZ
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 {
a9249b2e 543 SetPointSize(size);
ab5fe833 544 }
e7e52b6d 545#if wxUSE_FONTMAP
142b3bc2 546 else if ( (encoding = wxFontMapper::Get()->CharsetToEncoding(token, FALSE))
ab5fe833
VZ
547 != wxFONTENCODING_DEFAULT )
548 {
549 SetEncoding(encoding);
550 }
e7e52b6d 551#endif // wxUSE_FONTMAP
ab5fe833
VZ
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
0eb529d9 584#endif // generic or wxMSW or wxOS2
ab5fe833 585