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