]> git.saurik.com Git - wxWidgets.git/blame - src/common/fontcmn.cpp
revised wxString docs: don't use old style grouping of functions at the beginning...
[wxWidgets.git] / src / common / fontcmn.cpp
CommitLineData
8f7fa6f8 1/////////////////////////////////////////////////////////////////////////////
da80ae71 2// Name: src/common/fontcmn.cpp
0c5d3e1c
VZ
3// Purpose: implementation of wxFontBase methods
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 20.09.99
7// RCS-ID: $Id$
77ffb593 8// Copyright: (c) wxWidgets team
65571936 9// Licence: wxWindows licence
0c5d3e1c
VZ
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
da80ae71 24 #pragma hdrstop
0c5d3e1c
VZ
25#endif
26
da80ae71
WS
27#include "wx/font.h"
28
0c5d3e1c 29#ifndef WX_PRECOMP
452aa069 30 #include "wx/dc.h"
9342fdbe
VZ
31 #include "wx/intl.h"
32 #include "wx/dcscreen.h"
8d3ba63b 33 #include "wx/log.h"
dd05139a 34 #include "wx/gdicmn.h"
0c5d3e1c
VZ
35#endif // WX_PRECOMP
36
82ef81ed 37#if defined(__WXMSW__)
7bd236e6
WS
38 #include "wx/msw/private.h" // includes windows.h for LOGFONT
39 #include "wx/msw/winundef.h"
1c193821
JS
40#endif
41
76e23cdb 42#include "wx/fontutil.h" // for wxNativeFontInfo
ab5fe833 43#include "wx/fontmap.h"
85ab460e 44#include "wx/fontenum.h"
76e23cdb 45
30764ab5
VZ
46#include "wx/tokenzr.h"
47
0c5d3e1c
VZ
48// ============================================================================
49// implementation
50// ============================================================================
51
544229d1
VZ
52// ----------------------------------------------------------------------------
53// helper functions
54// ----------------------------------------------------------------------------
55
b5791cc7 56static inline int flags2Style(int flags)
544229d1 57{
b5791cc7
FM
58 return flags & wxFONTFLAG_ITALIC
59 ? wxFONTSTYLE_ITALIC
60 : flags & wxFONTFLAG_SLANT
61 ? wxFONTSTYLE_SLANT
62 : wxFONTSTYLE_NORMAL;
63}
544229d1 64
b5791cc7
FM
65static inline int flags2Weight(int flags)
66{
67 return flags & wxFONTFLAG_LIGHT
68 ? wxFONTWEIGHT_LIGHT
69 : flags & wxFONTFLAG_BOLD
70 ? wxFONTWEIGHT_BOLD
71 : wxFONTWEIGHT_NORMAL;
72}
544229d1 73
b5791cc7
FM
74static inline bool flags2Underlined(int flags)
75{
76 return (flags & wxFONTFLAG_UNDERLINED) != 0;
544229d1
VZ
77}
78
0c5d3e1c
VZ
79// ----------------------------------------------------------------------------
80// wxFontBase
81// ----------------------------------------------------------------------------
82
83wxFontEncoding wxFontBase::ms_encodingDefault = wxFONTENCODING_SYSTEM;
84
cafbf6fb
VZ
85/* static */
86void wxFontBase::SetDefaultEncoding(wxFontEncoding encoding)
87{
88 // GetDefaultEncoding() should return something != wxFONTENCODING_DEFAULT
89 // and, besides, using this value here doesn't make any sense
90 wxCHECK_RET( encoding != wxFONTENCODING_DEFAULT,
91 _T("can't set default encoding to wxFONTENCODING_DEFAULT") );
92
93 ms_encodingDefault = encoding;
94}
95
799ea011
GD
96wxFontBase::~wxFontBase()
97{
98 // this destructor is required for Darwin
99}
100
7beba2fc 101/* static */
0c5d3e1c 102wxFont *wxFontBase::New(int size,
0c14b6c3
FM
103 wxFontFamily family,
104 wxFontStyle style,
105 wxFontWeight weight,
0c5d3e1c
VZ
106 bool underlined,
107 const wxString& face,
108 wxFontEncoding encoding)
109{
110 return new wxFont(size, family, style, weight, underlined, face, encoding);
111}
112
b5791cc7
FM
113/* static */
114wxFont *wxFontBase::New(const wxSize& pixelSize,
115 wxFontFamily family,
116 wxFontStyle style,
117 wxFontWeight weight,
118 bool underlined,
119 const wxString& face,
120 wxFontEncoding encoding)
544229d1 121{
b5791cc7
FM
122 return new wxFont(pixelSize, family, style, weight, underlined,
123 face, encoding);
544229d1
VZ
124}
125
126/* static */
127wxFont *wxFontBase::New(int pointSize,
128 wxFontFamily family,
129 int flags,
130 const wxString& face,
131 wxFontEncoding encoding)
132{
133 return New(pointSize, family, flags2Style(flags), flags2Weight(flags),
134 flags2Underlined(flags), face, encoding);
135}
136
137/* static */
138wxFont *wxFontBase::New(const wxSize& pixelSize,
0c14b6c3 139 wxFontFamily family,
b5791cc7 140 int flags,
544229d1
VZ
141 const wxString& face,
142 wxFontEncoding encoding)
143{
b5791cc7
FM
144 return New(pixelSize, family, flags2Style(flags), flags2Weight(flags),
145 flags2Underlined(flags), face, encoding);
544229d1
VZ
146}
147
148/* static */
b5791cc7 149wxFont *wxFontBase::New(const wxNativeFontInfo& info)
544229d1 150{
b5791cc7
FM
151 return new wxFont(info);
152}
153
154/* static */
155wxFont *wxFontBase::New(const wxString& strNativeFontDesc)
156{
157 wxNativeFontInfo fontInfo;
158 if ( !fontInfo.FromString(strNativeFontDesc) )
159 return new wxFont(*wxNORMAL_FONT);
160
161 return New(fontInfo);
162}
163
164bool wxFontBase::IsFixedWidth() const
165{
166 return GetFamily() == wxFONTFAMILY_TELETYPE;
544229d1
VZ
167}
168
169wxSize wxFontBase::GetPixelSize() const
170{
171 wxScreenDC dc;
172 dc.SetFont(*(wxFont *)this);
173 return wxSize(dc.GetCharWidth(), dc.GetCharHeight());
174}
175
176bool wxFontBase::IsUsingSizeInPixels() const
177{
178 return false;
179}
180
181void wxFontBase::SetPixelSize( const wxSize& pixelSize )
182{
b5791cc7
FM
183 wxCHECK_RET( pixelSize.GetWidth() >= 0 && pixelSize.GetHeight() > 0,
184 "Negative values for the pixel size or zero pixel height are not allowed" );
185
544229d1 186 wxScreenDC dc;
01cb1c26 187
b5791cc7
FM
188 // NOTE: this algorithm for adjusting the font size is used by all
189 // implementations of wxFont except under wxMSW and wxGTK where
190 // native support to font creation using pixel-size is provided.
191
192 int largestGood = 0;
193 int smallestBad = 0;
30764ab5 194
b5791cc7
FM
195 bool initialGoodFound = false;
196 bool initialBadFound = false;
7826e2dd 197
b5791cc7
FM
198 // NB: this assignment was separated from the variable definition
199 // in order to fix a gcc v3.3.3 compiler crash
200 int currentSize = GetPointSize();
201 while (currentSize > 0)
202 {
203 dc.SetFont(*static_cast<wxFont*>(this));
7826e2dd 204
b5791cc7
FM
205 // if currentSize (in points) results in a font that is smaller
206 // than required by pixelSize it is considered a good size
207 // NOTE: the pixel size width may be zero
208 if (dc.GetCharHeight() <= pixelSize.GetHeight() &&
209 (pixelSize.GetWidth() == 0 ||
210 dc.GetCharWidth() <= pixelSize.GetWidth()))
211 {
212 largestGood = currentSize;
213 initialGoodFound = true;
214 }
215 else
216 {
217 smallestBad = currentSize;
218 initialBadFound = true;
219 }
220 if (!initialGoodFound)
221 {
222 currentSize /= 2;
223 }
224 else if (!initialBadFound)
225 {
226 currentSize *= 2;
227 }
228 else
229 {
230 int distance = smallestBad - largestGood;
231 if (distance == 1)
232 break;
233
234 currentSize = largestGood + distance / 2;
235 }
236
237 SetPointSize(currentSize);
238 }
239
240 if (currentSize != largestGood)
241 SetPointSize(largestGood);
53f6aab7
VZ
242}
243
9045ad9d 244void wxFontBase::DoSetNativeFontInfo(const wxNativeFontInfo& info)
30764ab5 245{
ab5fe833 246#ifdef wxNO_NATIVE_FONTINFO
30764ab5
VZ
247 SetPointSize(info.pointSize);
248 SetFamily(info.family);
249 SetStyle(info.style);
250 SetWeight(info.weight);
251 SetUnderlined(info.underlined);
252 SetFaceName(info.faceName);
253 SetEncoding(info.encoding);
33ac7e6f 254#else
1e6feb95 255 (void)info;
30764ab5
VZ
256#endif
257}
258
7826e2dd
VZ
259wxString wxFontBase::GetNativeFontInfoDesc() const
260{
261 wxString fontDesc;
3bf5a59b 262 const wxNativeFontInfo *fontInfo = GetNativeFontInfo();
7826e2dd
VZ
263 if ( fontInfo )
264 {
265 fontDesc = fontInfo->ToString();
dd05139a 266 wxASSERT_MSG(!fontDesc.empty(), wxT("This should be a non-empty string!"));
85ab460e
VZ
267 }
268 else
269 {
7bd236e6 270 wxFAIL_MSG(wxT("Derived class should have created the wxNativeFontInfo!"));
7826e2dd
VZ
271 }
272
273 return fontDesc;
274}
275
ab5fe833
VZ
276wxString wxFontBase::GetNativeFontInfoUserDesc() const
277{
278 wxString fontDesc;
3bf5a59b 279 const wxNativeFontInfo *fontInfo = GetNativeFontInfo();
ab5fe833
VZ
280 if ( fontInfo )
281 {
282 fontDesc = fontInfo->ToUserString();
dd05139a 283 wxASSERT_MSG(!fontDesc.empty(), wxT("This should be a non-empty string!"));
85ab460e
VZ
284 }
285 else
286 {
7456f382 287 wxFAIL_MSG(wxT("Derived class should have created the wxNativeFontInfo!"));
ab5fe833
VZ
288 }
289
290 return fontDesc;
291}
292
85ab460e 293bool wxFontBase::SetNativeFontInfo(const wxString& info)
31d1b66e
VZ
294{
295 wxNativeFontInfo fontInfo;
296 if ( !info.empty() && fontInfo.FromString(info) )
297 {
298 SetNativeFontInfo(fontInfo);
85ab460e 299 return true;
31d1b66e 300 }
85ab460e 301
85ab460e 302 return false;
31d1b66e
VZ
303}
304
85ab460e 305bool wxFontBase::SetNativeFontInfoUserDesc(const wxString& info)
ab5fe833
VZ
306{
307 wxNativeFontInfo fontInfo;
308 if ( !info.empty() && fontInfo.FromUserString(info) )
309 {
310 SetNativeFontInfo(fontInfo);
85ab460e 311 return true;
ab5fe833 312 }
85ab460e 313
85ab460e 314 return false;
ab5fe833
VZ
315}
316
0c5d3e1c
VZ
317bool wxFontBase::operator==(const wxFont& font) const
318{
8bf30fe9
VZ
319 // either it is the same font, i.e. they share the same common data or they
320 // have different ref datas but still describe the same font
a38cd629 321 return IsSameAs(font) ||
8bf30fe9 322 (
70f70818 323 IsOk() == font.IsOk() &&
8bf30fe9 324 GetPointSize() == font.GetPointSize() &&
82d0e7fe
VZ
325 // in wxGTK1 GetPixelSize() calls GetInternalFont() which uses
326 // operator==() resulting in infinite recursion so we can't use it
327 // in that port
328#if !defined(__WXGTK__) || defined(__WXGTK20__)
cc3de8a3 329 GetPixelSize() == font.GetPixelSize() &&
82d0e7fe 330#endif
8bf30fe9
VZ
331 GetFamily() == font.GetFamily() &&
332 GetStyle() == font.GetStyle() &&
e6adf058 333 GetWeight() == font.GetWeight() &&
8bf30fe9 334 GetUnderlined() == font.GetUnderlined() &&
85ab460e 335 GetFaceName().IsSameAs(font.GetFaceName(), false) &&
8bf30fe9
VZ
336 GetEncoding() == font.GetEncoding()
337 );
0c5d3e1c
VZ
338}
339
0c5d3e1c
VZ
340wxString wxFontBase::GetFamilyString() const
341{
70f70818 342 wxCHECK_MSG( IsOk(), "wxFONTFAMILY_DEFAULT", "invalid font" );
0c5d3e1c
VZ
343
344 switch ( GetFamily() )
345 {
70f70818
FM
346 case wxFONTFAMILY_DECORATIVE: return "wxFONTFAMILY_DECORATIVE";
347 case wxFONTFAMILY_ROMAN: return "wxFONTFAMILY_ROMAN";
348 case wxFONTFAMILY_SCRIPT: return "wxFONTFAMILY_SCRIPT";
349 case wxFONTFAMILY_SWISS: return "wxFONTFAMILY_SWISS";
350 case wxFONTFAMILY_MODERN: return "wxFONTFAMILY_MODERN";
351 case wxFONTFAMILY_TELETYPE: return "wxFONTFAMILY_TELETYPE";
352 default: return "wxFONTFAMILY_DEFAULT";
0c5d3e1c
VZ
353 }
354}
355
356wxString wxFontBase::GetStyleString() const
357{
70f70818 358 wxCHECK_MSG( IsOk(), "wxFONTSTYLE_DEFAULT", "invalid font" );
0c5d3e1c
VZ
359
360 switch ( GetStyle() )
361 {
70f70818
FM
362 case wxFONTSTYLE_NORMAL: return "wxFONTSTYLE_NORMAL";
363 case wxFONTSTYLE_SLANT: return "wxFONTSTYLE_SLANT";
364 case wxFONTSTYLE_ITALIC: return "wxFONTSTYLE_ITALIC";
365 default: return "wxFONTSTYLE_DEFAULT";
0c5d3e1c
VZ
366 }
367}
368
369wxString wxFontBase::GetWeightString() const
370{
70f70818 371 wxCHECK_MSG( IsOk(), "wxFONTWEIGHT_DEFAULT", "invalid font" );
0c5d3e1c
VZ
372
373 switch ( GetWeight() )
374 {
70f70818
FM
375 case wxFONTWEIGHT_NORMAL: return "wxFONTWEIGHT_NORMAL";
376 case wxFONTWEIGHT_BOLD: return "wxFONTWEIGHT_BOLD";
377 case wxFONTWEIGHT_LIGHT: return "wxFONTWEIGHT_LIGHT";
378 default: return "wxFONTWEIGHT_DEFAULT";
0c5d3e1c
VZ
379 }
380}
381
ff427585 382bool wxFontBase::SetFaceName(const wxString& facename)
85ab460e 383{
ff427585 384#if wxUSE_FONTENUM
85ab460e
VZ
385 if (!wxFontEnumerator::IsValidFacename(facename))
386 {
70f70818 387 UnRef(); // make IsOk() return false
85ab460e
VZ
388 return false;
389 }
ff427585
VZ
390#else // !wxUSE_FONTENUM
391 wxUnusedVar(facename);
392#endif // wxUSE_FONTENUM/!wxUSE_FONTENUM
85ab460e
VZ
393
394 return true;
395}
396
397
30764ab5
VZ
398// ----------------------------------------------------------------------------
399// wxNativeFontInfo
400// ----------------------------------------------------------------------------
401
85ab460e 402// Up to now, there are no native implementations of this function:
ff427585 403void wxNativeFontInfo::SetFaceName(const wxArrayString& facenames)
85ab460e 404{
ff427585 405#if wxUSE_FONTENUM
85ab460e
VZ
406 for (size_t i=0; i < facenames.GetCount(); i++)
407 {
408 if (wxFontEnumerator::IsValidFacename(facenames[i]))
409 {
410 SetFaceName(facenames[i]);
411 return;
412 }
413 }
414
415 // set the first valid facename we can find on this system
416 wxString validfacename = wxFontEnumerator::GetFacenames().Item(0);
417 wxLogTrace(wxT("font"), wxT("Falling back to '%s'"), validfacename.c_str());
418 SetFaceName(validfacename);
ff427585
VZ
419#else // !wxUSE_FONTENUM
420 SetFaceName(facenames[0]);
421#endif // wxUSE_FONTENUM/!wxUSE_FONTENUM
85ab460e
VZ
422}
423
424
ab5fe833
VZ
425#ifdef wxNO_NATIVE_FONTINFO
426
30764ab5
VZ
427// These are the generic forms of FromString()/ToString.
428//
429// convert to/from the string representation: format is
09fcd889 430// version;pointsize;family;style;weight;underlined;facename;encoding
30764ab5
VZ
431
432bool wxNativeFontInfo::FromString(const wxString& s)
433{
434 long l;
435
436 wxStringTokenizer tokenizer(s, _T(";"));
437
438 wxString token = tokenizer.GetNextToken();
09fcd889
VZ
439 //
440 // Ignore the version for now
441 //
33ac7e6f 442
09fcd889 443 token = tokenizer.GetNextToken();
30764ab5 444 if ( !token.ToLong(&l) )
a62848fd 445 return false;
30764ab5
VZ
446 pointSize = (int)l;
447
448 token = tokenizer.GetNextToken();
449 if ( !token.ToLong(&l) )
a62848fd 450 return false;
f7b301fa 451 family = (wxFontFamily)l;
30764ab5
VZ
452
453 token = tokenizer.GetNextToken();
454 if ( !token.ToLong(&l) )
a62848fd 455 return false;
ab5fe833 456 style = (wxFontStyle)l;
30764ab5
VZ
457
458 token = tokenizer.GetNextToken();
459 if ( !token.ToLong(&l) )
a62848fd 460 return false;
ab5fe833 461 weight = (wxFontWeight)l;
30764ab5
VZ
462
463 token = tokenizer.GetNextToken();
464 if ( !token.ToLong(&l) )
a62848fd 465 return false;
189e08b4 466 underlined = l != 0;
30764ab5
VZ
467
468 faceName = tokenizer.GetNextToken();
0a9f0ef7
JS
469
470#ifndef __WXMAC__
30764ab5 471 if( !faceName )
a62848fd 472 return false;
0a9f0ef7 473#endif
30764ab5
VZ
474
475 token = tokenizer.GetNextToken();
476 if ( !token.ToLong(&l) )
a62848fd 477 return false;
30764ab5
VZ
478 encoding = (wxFontEncoding)l;
479
a62848fd 480 return true;
30764ab5
VZ
481}
482
483wxString wxNativeFontInfo::ToString() const
484{
485 wxString s;
486
09fcd889
VZ
487 s.Printf(_T("%d;%d;%d;%d;%d;%d;%s;%d"),
488 0, // version
30764ab5
VZ
489 pointSize,
490 family,
ab5fe833
VZ
491 (int)style,
492 (int)weight,
30764ab5
VZ
493 underlined,
494 faceName.GetData(),
495 (int)encoding);
496
497 return s;
498}
499
ab5fe833
VZ
500void wxNativeFontInfo::Init()
501{
3bf5a59b 502 pointSize = 0;
ab5fe833
VZ
503 family = wxFONTFAMILY_DEFAULT;
504 style = wxFONTSTYLE_NORMAL;
505 weight = wxFONTWEIGHT_NORMAL;
a62848fd 506 underlined = false;
ab5fe833
VZ
507 faceName.clear();
508 encoding = wxFONTENCODING_DEFAULT;
509}
510
511int wxNativeFontInfo::GetPointSize() const
512{
513 return pointSize;
514}
515
516wxFontStyle wxNativeFontInfo::GetStyle() const
517{
518 return style;
519}
520
521wxFontWeight wxNativeFontInfo::GetWeight() const
522{
523 return weight;
524}
525
526bool wxNativeFontInfo::GetUnderlined() const
527{
528 return underlined;
529}
530
531wxString wxNativeFontInfo::GetFaceName() const
532{
533 return faceName;
534}
535
7936354d
VZ
536wxFontFamily wxNativeFontInfo::GetFamily() const
537{
538 return family;
539}
540
ab5fe833
VZ
541wxFontEncoding wxNativeFontInfo::GetEncoding() const
542{
543 return encoding;
544}
545
546void wxNativeFontInfo::SetPointSize(int pointsize)
547{
548 pointSize = pointsize;
549}
550
551void wxNativeFontInfo::SetStyle(wxFontStyle style_)
552{
553 style = style_;
554}
555
556void wxNativeFontInfo::SetWeight(wxFontWeight weight_)
557{
558 weight = weight_;
559}
560
561void wxNativeFontInfo::SetUnderlined(bool underlined_)
562{
563 underlined = underlined_;
564}
565
85ab460e 566bool wxNativeFontInfo::SetFaceName(const wxString& facename_)
ab5fe833 567{
f7b301fa 568 faceName = facename_;
85ab460e 569 return true;
ab5fe833
VZ
570}
571
3f1d1373 572void wxNativeFontInfo::SetFamily(wxFontFamily family_)
7936354d
VZ
573{
574 family = family_;
575}
576
ab5fe833
VZ
577void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
578{
579 encoding = encoding_;
580}
581
7826e2dd 582#endif // generic wxNativeFontInfo implementation
30764ab5 583
ab5fe833
VZ
584// conversion to/from user-readable string: this is used in the generic
585// versions and under MSW as well because there is no standard font description
586// format there anyhow (but there is a well-defined standard for X11 fonts used
587// by wxGTK and wxMotif)
588
0eb529d9 589#if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__)
ab5fe833
VZ
590
591wxString wxNativeFontInfo::ToUserString() const
592{
593 wxString desc;
594
595 // first put the adjectives, if any - this is English-centric, of course,
596 // but what else can we do?
597 if ( GetUnderlined() )
598 {
85ab460e 599 desc << _("underlined");
ab5fe833
VZ
600 }
601
602 switch ( GetWeight() )
603 {
604 default:
605 wxFAIL_MSG( _T("unknown font weight") );
606 // fall through
607
608 case wxFONTWEIGHT_NORMAL:
609 break;
610
611 case wxFONTWEIGHT_LIGHT:
85ab460e 612 desc << _(" light");
ab5fe833
VZ
613 break;
614
615 case wxFONTWEIGHT_BOLD:
85ab460e 616 desc << _(" bold");
ab5fe833
VZ
617 break;
618 }
619
620 switch ( GetStyle() )
621 {
622 default:
623 wxFAIL_MSG( _T("unknown font style") );
624 // fall through
625
626 case wxFONTSTYLE_NORMAL:
627 break;
628
629 // we don't distinguish between the two for now anyhow...
630 case wxFONTSTYLE_ITALIC:
631 case wxFONTSTYLE_SLANT:
85ab460e 632 desc << _(" italic");
ab5fe833
VZ
633 break;
634 }
635
a9249b2e
VZ
636 wxString face = GetFaceName();
637 if ( !face.empty() )
ab5fe833 638 {
a9249b2e 639 desc << _T(' ') << face;
ab5fe833
VZ
640 }
641
a9249b2e
VZ
642 int size = GetPointSize();
643 if ( size != wxNORMAL_FONT->GetPointSize() )
ab5fe833 644 {
a9249b2e 645 desc << _T(' ') << size;
ab5fe833 646 }
a9249b2e 647
e7e52b6d 648#if wxUSE_FONTMAP
a9249b2e
VZ
649 wxFontEncoding enc = GetEncoding();
650 if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM )
651 {
2a1f999f 652 desc << _T(' ') << wxFontMapper::GetEncodingName(enc);
a9249b2e 653 }
e7e52b6d 654#endif // wxUSE_FONTMAP
a9249b2e 655
85ab460e 656 return desc.Strip(wxString::both).MakeLower();
ab5fe833
VZ
657}
658
659bool wxNativeFontInfo::FromUserString(const wxString& s)
660{
661 // reset to the default state
662 Init();
663
664 // parse a more or less free form string
665 //
666 // TODO: we should handle at least the quoted facenames
667 wxStringTokenizer tokenizer(s, _T(";, "), wxTOKEN_STRTOK);
668
669 wxString face;
670 unsigned long size;
77f15ffe
VS
671 bool weightfound = false, pointsizefound = false;
672#if wxUSE_FONTMAP
673 bool encodingfound = false;
674#endif
ab5fe833
VZ
675
676 while ( tokenizer.HasMoreTokens() )
677 {
678 wxString token = tokenizer.GetNextToken();
679
680 // normalize it
a62848fd 681 token.Trim(true).Trim(false).MakeLower();
ab5fe833
VZ
682
683 // look for the known tokens
684 if ( token == _T("underlined") || token == _("underlined") )
685 {
a62848fd 686 SetUnderlined(true);
ab5fe833
VZ
687 }
688 else if ( token == _T("light") || token == _("light") )
689 {
690 SetWeight(wxFONTWEIGHT_LIGHT);
85ab460e 691 weightfound = true;
ab5fe833
VZ
692 }
693 else if ( token == _T("bold") || token == _("bold") )
694 {
695 SetWeight(wxFONTWEIGHT_BOLD);
85ab460e 696 weightfound = true;
ab5fe833
VZ
697 }
698 else if ( token == _T("italic") || token == _("italic") )
699 {
700 SetStyle(wxFONTSTYLE_ITALIC);
701 }
702 else if ( token.ToULong(&size) )
703 {
a9249b2e 704 SetPointSize(size);
85ab460e 705 pointsizefound = true;
ab5fe833 706 }
85ab460e
VZ
707 else
708 {
e7e52b6d 709#if wxUSE_FONTMAP
85ab460e
VZ
710 // try to interpret this as an encoding
711 wxFontEncoding encoding = wxFontMapper::Get()->CharsetToEncoding(token, false);
712 if ( encoding != wxFONTENCODING_DEFAULT &&
713 encoding != wxFONTENCODING_SYSTEM ) // returned when the recognition failed
ab5fe833
VZ
714 {
715 SetEncoding(encoding);
85ab460e 716 encodingfound = true;
ab5fe833 717 }
85ab460e 718 else
ab5fe833 719 {
85ab460e
VZ
720#endif // wxUSE_FONTMAP
721
722 // assume it is the face name
ab5fe833
VZ
723 if ( !face.empty() )
724 {
725 face += _T(' ');
726 }
727
728 face += token;
729
730 // skip the code which resets face below
731 continue;
85ab460e
VZ
732
733#if wxUSE_FONTMAP
734 }
735#endif // wxUSE_FONTMAP
ab5fe833
VZ
736 }
737
738 // if we had had the facename, we shouldn't continue appending tokens
739 // to it (i.e. "foo bold bar" shouldn't result in the facename "foo
740 // bar")
741 if ( !face.empty() )
742 {
85ab460e
VZ
743 // NB: the check on the facename is implemented in wxFontBase::SetFaceName
744 // and not in wxNativeFontInfo::SetFaceName thus we need to explicitely
745 // call here wxFontEnumerator::IsValidFacename
ff427585
VZ
746 if (
747#if wxUSE_FONTENUM
748 !wxFontEnumerator::IsValidFacename(face) ||
749#endif // wxUSE_FONTENUM
750 !SetFaceName(face) )
751 {
85ab460e 752 SetFaceName(wxNORMAL_FONT->GetFaceName());
ff427585
VZ
753 }
754
ab5fe833
VZ
755 face.clear();
756 }
757 }
758
759 // we might not have flushed it inside the loop
760 if ( !face.empty() )
761 {
85ab460e
VZ
762 // NB: the check on the facename is implemented in wxFontBase::SetFaceName
763 // and not in wxNativeFontInfo::SetFaceName thus we need to explicitely
764 // call here wxFontEnumerator::IsValidFacename
ff427585
VZ
765 if (
766#if wxUSE_FONTENUM
767 !wxFontEnumerator::IsValidFacename(face) ||
768#endif // wxUSE_FONTENUM
769 !SetFaceName(face) )
770 {
771 SetFaceName(wxNORMAL_FONT->GetFaceName());
772 }
ab5fe833
VZ
773 }
774
85ab460e
VZ
775 // set point size to default value if size was not given
776 if ( !pointsizefound )
777 SetPointSize(wxNORMAL_FONT->GetPointSize());
778
779 // set font weight to default value if weight was not given
780 if ( !weightfound )
781 SetWeight(wxFONTWEIGHT_NORMAL);
782
783#if wxUSE_FONTMAP
784 // set font encoding to default value if encoding was not given
785 if ( !encodingfound )
786 SetEncoding(wxFONTENCODING_SYSTEM);
787#endif // wxUSE_FONTMAP
788
a62848fd 789 return true;
ab5fe833
VZ
790}
791
0eb529d9 792#endif // generic or wxMSW or wxOS2
fc9361e3
VZ
793
794
795// wxFont <-> wxString utilities, used by wxConfig
796wxString wxToString(const wxFontBase& font)
797{
798 return font.IsOk() ? font.GetNativeFontInfoDesc()
799 : wxString();
800}
801
802bool wxFromString(const wxString& str, wxFontBase *font)
803{
804 wxCHECK_MSG( font, false, _T("NULL output parameter") );
805
806 if ( str.empty() )
807 {
808 *font = wxNullFont;
809 return true;
810 }
811
812 return font->SetNativeFontInfo(str);
813}
814
815