1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/fontcmn.cpp
3 // Purpose: implementation of wxFontBase methods
4 // Author: Vadim Zeitlin
7 // Copyright: (c) wxWidgets team
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
32 #include "wx/dcscreen.h"
34 #include "wx/gdicmn.h"
37 #if defined(__WXMSW__)
38 #include "wx/msw/private.h" // includes windows.h for LOGFONT
39 #include "wx/msw/winundef.h"
42 #include "wx/fontutil.h" // for wxNativeFontInfo
43 #include "wx/fontmap.h"
44 #include "wx/fontenum.h"
46 #include "wx/tokenzr.h"
48 // debugger helper: this function can be called from a debugger to show what
50 extern const char *wxDumpFont(const wxFont
*font
)
54 const wxFontWeight weight
= font
->GetWeight();
57 s
.Printf(wxS("%s-%s-%s-%d-%d"),
59 weight
== wxFONTWEIGHT_NORMAL
61 : weight
== wxFONTWEIGHT_BOLD
64 font
->GetStyle() == wxFONTSTYLE_NORMAL
70 wxStrlcpy(buf
, s
.mb_str(), WXSIZEOF(buf
));
74 // ----------------------------------------------------------------------------
76 // ----------------------------------------------------------------------------
78 wxBEGIN_ENUM( wxFontFamily
)
79 wxENUM_MEMBER( wxFONTFAMILY_DEFAULT
)
80 wxENUM_MEMBER( wxFONTFAMILY_DECORATIVE
)
81 wxENUM_MEMBER( wxFONTFAMILY_ROMAN
)
82 wxENUM_MEMBER( wxFONTFAMILY_SCRIPT
)
83 wxENUM_MEMBER( wxFONTFAMILY_SWISS
)
84 wxENUM_MEMBER( wxFONTFAMILY_MODERN
)
85 wxENUM_MEMBER( wxFONTFAMILY_TELETYPE
)
86 wxEND_ENUM( wxFontFamily
)
88 wxBEGIN_ENUM( wxFontStyle
)
89 wxENUM_MEMBER( wxFONTSTYLE_NORMAL
)
90 wxENUM_MEMBER( wxFONTSTYLE_ITALIC
)
91 wxENUM_MEMBER( wxFONTSTYLE_SLANT
)
92 wxEND_ENUM( wxFontStyle
)
94 wxBEGIN_ENUM( wxFontWeight
)
95 wxENUM_MEMBER( wxFONTWEIGHT_NORMAL
)
96 wxENUM_MEMBER( wxFONTWEIGHT_LIGHT
)
97 wxENUM_MEMBER( wxFONTWEIGHT_BOLD
)
98 wxEND_ENUM( wxFontWeight
)
100 wxIMPLEMENT_DYNAMIC_CLASS_WITH_COPY_XTI(wxFont
, wxGDIObject
, "wx/font.h")
102 //WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxFont>)
104 wxBEGIN_PROPERTIES_TABLE(wxFont
)
105 wxPROPERTY( Size
,int, SetPointSize
, GetPointSize
, 12, 0 /*flags*/, \
106 wxT("Helpstring"), wxT("group"))
107 wxPROPERTY( Family
, wxFontFamily
, SetFamily
, GetFamily
, (wxFontFamily
)wxDEFAULT
, \
108 0 /*flags*/, wxT("Helpstring"), wxT("group")) // wxFontFamily
109 wxPROPERTY( Style
, wxFontStyle
, SetStyle
, GetStyle
, (wxFontStyle
)wxNORMAL
, 0 /*flags*/, \
110 wxT("Helpstring"), wxT("group")) // wxFontStyle
111 wxPROPERTY( Weight
, wxFontWeight
, SetWeight
, GetWeight
, (wxFontWeight
)wxNORMAL
, 0 /*flags*/, \
112 wxT("Helpstring"), wxT("group")) // wxFontWeight
113 wxPROPERTY( Underlined
, bool, SetUnderlined
, GetUnderlined
, false, 0 /*flags*/, \
114 wxT("Helpstring"), wxT("group"))
115 wxPROPERTY( Strikethrough
, bool, SetStrikethrough
, GetStrikethrough
, false, 0, \
116 wxT("Helpstring"), wxT("group"))
117 wxPROPERTY( Face
, wxString
, SetFaceName
, GetFaceName
, wxEMPTY_PARAMETER_VALUE
, \
118 0 /*flags*/, wxT("Helpstring"), wxT("group"))
119 wxPROPERTY( Encoding
, wxFontEncoding
, SetEncoding
, GetEncoding
, \
120 wxFONTENCODING_DEFAULT
, 0 /*flags*/, wxT("Helpstring"), wxT("group"))
121 wxEND_PROPERTIES_TABLE()
123 wxCONSTRUCTOR_6( wxFont
, int, Size
, wxFontFamily
, Family
, wxFontStyle
, Style
, wxFontWeight
, Weight
, \
124 bool, Underlined
, wxString
, Face
)
126 wxEMPTY_HANDLERS_TABLE(wxFont
)
128 // ============================================================================
130 // ============================================================================
132 // ----------------------------------------------------------------------------
134 // ----------------------------------------------------------------------------
136 wxFontEncoding
wxFontBase::ms_encodingDefault
= wxFONTENCODING_SYSTEM
;
139 void wxFontBase::SetDefaultEncoding(wxFontEncoding encoding
)
141 // GetDefaultEncoding() should return something != wxFONTENCODING_DEFAULT
142 // and, besides, using this value here doesn't make any sense
143 wxCHECK_RET( encoding
!= wxFONTENCODING_DEFAULT
,
144 wxT("can't set default encoding to wxFONTENCODING_DEFAULT") );
146 ms_encodingDefault
= encoding
;
149 wxFontBase::~wxFontBase()
151 // this destructor is required for Darwin
155 wxFont
*wxFontBase::New(int size
,
160 const wxString
& face
,
161 wxFontEncoding encoding
)
163 return new wxFont(size
, family
, style
, weight
, underlined
, face
, encoding
);
167 wxFont
*wxFontBase::New(const wxSize
& pixelSize
,
172 const wxString
& face
,
173 wxFontEncoding encoding
)
175 return new wxFont(pixelSize
, family
, style
, weight
, underlined
,
180 wxFont
*wxFontBase::New(int pointSize
,
183 const wxString
& face
,
184 wxFontEncoding encoding
)
186 return New(pointSize
, family
,
187 GetStyleFromFlags(flags
),
188 GetWeightFromFlags(flags
),
189 GetUnderlinedFromFlags(flags
),
194 wxFont
*wxFontBase::New(const wxSize
& pixelSize
,
197 const wxString
& face
,
198 wxFontEncoding encoding
)
200 return New(pixelSize
, family
,
201 GetStyleFromFlags(flags
),
202 GetWeightFromFlags(flags
),
203 GetUnderlinedFromFlags(flags
),
208 wxFont
*wxFontBase::New(const wxNativeFontInfo
& info
)
210 return new wxFont(info
);
214 wxFont
*wxFontBase::New(const wxString
& strNativeFontDesc
)
216 wxNativeFontInfo fontInfo
;
217 if ( !fontInfo
.FromString(strNativeFontDesc
) )
218 return new wxFont(*wxNORMAL_FONT
);
220 return New(fontInfo
);
223 bool wxFontBase::IsFixedWidth() const
225 return GetFamily() == wxFONTFAMILY_TELETYPE
;
228 wxSize
wxFontBase::GetPixelSize() const
231 dc
.SetFont(*(wxFont
*)this);
232 return wxSize(dc
.GetCharWidth(), dc
.GetCharHeight());
235 bool wxFontBase::IsUsingSizeInPixels() const
240 void wxFontBase::SetPixelSize( const wxSize
& pixelSize
)
242 wxCHECK_RET( pixelSize
.GetWidth() >= 0 && pixelSize
.GetHeight() > 0,
243 "Negative values for the pixel size or zero pixel height are not allowed" );
247 // NOTE: this algorithm for adjusting the font size is used by all
248 // implementations of wxFont except under wxMSW and wxGTK where
249 // native support to font creation using pixel-size is provided.
254 bool initialGoodFound
= false;
255 bool initialBadFound
= false;
257 // NB: this assignment was separated from the variable definition
258 // in order to fix a gcc v3.3.3 compiler crash
259 int currentSize
= GetPointSize();
260 while (currentSize
> 0)
262 dc
.SetFont(*static_cast<wxFont
*>(this));
264 // if currentSize (in points) results in a font that is smaller
265 // than required by pixelSize it is considered a good size
266 // NOTE: the pixel size width may be zero
267 if (dc
.GetCharHeight() <= pixelSize
.GetHeight() &&
268 (pixelSize
.GetWidth() == 0 ||
269 dc
.GetCharWidth() <= pixelSize
.GetWidth()))
271 largestGood
= currentSize
;
272 initialGoodFound
= true;
276 smallestBad
= currentSize
;
277 initialBadFound
= true;
279 if (!initialGoodFound
)
283 else if (!initialBadFound
)
289 int distance
= smallestBad
- largestGood
;
293 currentSize
= largestGood
+ distance
/ 2;
296 SetPointSize(currentSize
);
299 if (currentSize
!= largestGood
)
300 SetPointSize(largestGood
);
303 void wxFontBase::DoSetNativeFontInfo(const wxNativeFontInfo
& info
)
305 #ifdef wxNO_NATIVE_FONTINFO
306 SetPointSize(info
.pointSize
);
307 SetFamily(info
.family
);
308 SetStyle(info
.style
);
309 SetWeight(info
.weight
);
310 SetUnderlined(info
.underlined
);
311 SetStrikethrough(info
.strikethrough
);
312 SetFaceName(info
.faceName
);
313 SetEncoding(info
.encoding
);
319 wxString
wxFontBase::GetNativeFontInfoDesc() const
321 wxCHECK_MSG( IsOk(), wxEmptyString
, wxT("invalid font") );
324 const wxNativeFontInfo
*fontInfo
= GetNativeFontInfo();
327 fontDesc
= fontInfo
->ToString();
328 wxASSERT_MSG(!fontDesc
.empty(), wxT("This should be a non-empty string!"));
332 wxFAIL_MSG(wxT("Derived class should have created the wxNativeFontInfo!"));
338 wxString
wxFontBase::GetNativeFontInfoUserDesc() const
340 wxCHECK_MSG( IsOk(), wxEmptyString
, wxT("invalid font") );
343 const wxNativeFontInfo
*fontInfo
= GetNativeFontInfo();
346 fontDesc
= fontInfo
->ToUserString();
347 wxASSERT_MSG(!fontDesc
.empty(), wxT("This should be a non-empty string!"));
351 wxFAIL_MSG(wxT("Derived class should have created the wxNativeFontInfo!"));
357 bool wxFontBase::SetNativeFontInfo(const wxString
& info
)
359 wxNativeFontInfo fontInfo
;
360 if ( !info
.empty() && fontInfo
.FromString(info
) )
362 SetNativeFontInfo(fontInfo
);
369 bool wxFontBase::SetNativeFontInfoUserDesc(const wxString
& info
)
371 wxNativeFontInfo fontInfo
;
372 if ( !info
.empty() && fontInfo
.FromUserString(info
) )
374 SetNativeFontInfo(fontInfo
);
381 bool wxFontBase::operator==(const wxFont
& font
) const
383 // either it is the same font, i.e. they share the same common data or they
384 // have different ref datas but still describe the same font
385 return IsSameAs(font
) ||
387 IsOk() == font
.IsOk() &&
388 GetPointSize() == font
.GetPointSize() &&
389 // in wxGTK1 GetPixelSize() calls GetInternalFont() which uses
390 // operator==() resulting in infinite recursion so we can't use it
392 #if !defined(__WXGTK__) || defined(__WXGTK20__)
393 GetPixelSize() == font
.GetPixelSize() &&
395 GetFamily() == font
.GetFamily() &&
396 GetStyle() == font
.GetStyle() &&
397 GetWeight() == font
.GetWeight() &&
398 GetUnderlined() == font
.GetUnderlined() &&
399 GetStrikethrough() == font
.GetStrikethrough() &&
400 GetFaceName().IsSameAs(font
.GetFaceName(), false) &&
401 GetEncoding() == font
.GetEncoding()
405 wxFontFamily
wxFontBase::GetFamily() const
407 wxCHECK_MSG( IsOk(), wxFONTFAMILY_UNKNOWN
, wxS("invalid font") );
409 // Don't return wxFONTFAMILY_UNKNOWN from here because it prevents the code
410 // like wxFont(size, wxNORMAL_FONT->GetFamily(), ...) from working (see
411 // #12330). This is really just a hack but it allows to keep compatibility
412 // and doesn't really have any bad drawbacks so do this until someone comes
413 // up with a better idea.
414 const wxFontFamily family
= DoGetFamily();
416 return family
== wxFONTFAMILY_UNKNOWN
? wxFONTFAMILY_DEFAULT
: family
;
419 wxString
wxFontBase::GetFamilyString() const
421 wxCHECK_MSG( IsOk(), "wxFONTFAMILY_DEFAULT", "invalid font" );
423 switch ( GetFamily() )
425 case wxFONTFAMILY_DECORATIVE
: return "wxFONTFAMILY_DECORATIVE";
426 case wxFONTFAMILY_ROMAN
: return "wxFONTFAMILY_ROMAN";
427 case wxFONTFAMILY_SCRIPT
: return "wxFONTFAMILY_SCRIPT";
428 case wxFONTFAMILY_SWISS
: return "wxFONTFAMILY_SWISS";
429 case wxFONTFAMILY_MODERN
: return "wxFONTFAMILY_MODERN";
430 case wxFONTFAMILY_TELETYPE
: return "wxFONTFAMILY_TELETYPE";
431 case wxFONTFAMILY_UNKNOWN
: return "wxFONTFAMILY_UNKNOWN";
432 default: return "wxFONTFAMILY_DEFAULT";
436 wxString
wxFontBase::GetStyleString() const
438 wxCHECK_MSG( IsOk(), "wxFONTSTYLE_DEFAULT", "invalid font" );
440 switch ( GetStyle() )
442 case wxFONTSTYLE_NORMAL
: return "wxFONTSTYLE_NORMAL";
443 case wxFONTSTYLE_SLANT
: return "wxFONTSTYLE_SLANT";
444 case wxFONTSTYLE_ITALIC
: return "wxFONTSTYLE_ITALIC";
445 default: return "wxFONTSTYLE_DEFAULT";
449 wxString
wxFontBase::GetWeightString() const
451 wxCHECK_MSG( IsOk(), "wxFONTWEIGHT_DEFAULT", "invalid font" );
453 switch ( GetWeight() )
455 case wxFONTWEIGHT_NORMAL
: return "wxFONTWEIGHT_NORMAL";
456 case wxFONTWEIGHT_BOLD
: return "wxFONTWEIGHT_BOLD";
457 case wxFONTWEIGHT_LIGHT
: return "wxFONTWEIGHT_LIGHT";
458 default: return "wxFONTWEIGHT_DEFAULT";
462 bool wxFontBase::SetFaceName(const wxString
& facename
)
465 if (!wxFontEnumerator::IsValidFacename(facename
))
467 UnRef(); // make IsOk() return false
470 #else // !wxUSE_FONTENUM
471 wxUnusedVar(facename
);
472 #endif // wxUSE_FONTENUM/!wxUSE_FONTENUM
477 void wxFontBase::SetSymbolicSize(wxFontSymbolicSize size
)
479 SetSymbolicSizeRelativeTo(size
, wxNORMAL_FONT
->GetPointSize());
483 int wxFontBase::AdjustToSymbolicSize(wxFontSymbolicSize size
, int base
)
485 // Using a fixed factor (1.2, from CSS2) is a bad idea as explained at
486 // http://www.w3.org/TR/CSS21/fonts.html#font-size-props so use the values
487 // from http://style.cleverchimp.com/font_size_intervals/altintervals.html
489 static const float factors
[] = { 0.60f
, 0.75f
, 0.89f
, 1.f
, 1.2f
, 1.5f
, 2.f
};
491 wxCOMPILE_TIME_ASSERT
493 WXSIZEOF(factors
) == wxFONTSIZE_XX_LARGE
- wxFONTSIZE_XX_SMALL
+ 1,
494 WrongFontSizeFactorsSize
497 return wxRound(factors
[size
- wxFONTSIZE_XX_SMALL
]*base
);
500 wxFont
& wxFont::MakeBold()
502 SetWeight(wxFONTWEIGHT_BOLD
);
506 wxFont
wxFont::Bold() const
513 wxFont
& wxFont::MakeItalic()
515 SetStyle(wxFONTSTYLE_ITALIC
);
519 wxFont
wxFont::Italic() const
526 wxFont
& wxFont::MakeUnderlined()
532 wxFont
wxFont::Underlined() const
535 font
.MakeUnderlined();
539 wxFont
wxFont::Strikethrough() const
542 font
.MakeStrikethrough();
546 wxFont
& wxFont::MakeStrikethrough()
548 SetStrikethrough(true);
552 wxFont
& wxFont::Scale(float x
)
554 SetPointSize(int(x
*GetPointSize() + 0.5));
558 wxFont
wxFont::Scaled(float x
) const
565 // ----------------------------------------------------------------------------
567 // ----------------------------------------------------------------------------
569 // Up to now, there are no native implementations of this function:
570 void wxNativeFontInfo::SetFaceName(const wxArrayString
& facenames
)
573 for (size_t i
=0; i
< facenames
.GetCount(); i
++)
575 if (wxFontEnumerator::IsValidFacename(facenames
[i
]))
577 SetFaceName(facenames
[i
]);
582 // set the first valid facename we can find on this system
583 wxString validfacename
= wxFontEnumerator::GetFacenames().Item(0);
584 wxLogTrace(wxT("font"), wxT("Falling back to '%s'"), validfacename
.c_str());
585 SetFaceName(validfacename
);
586 #else // !wxUSE_FONTENUM
587 SetFaceName(facenames
[0]);
588 #endif // wxUSE_FONTENUM/!wxUSE_FONTENUM
592 #ifdef wxNO_NATIVE_FONTINFO
594 // These are the generic forms of FromString()/ToString.
596 // convert to/from the string representation: the general format is
597 // "version;the rest..." with currently defined versions being:
599 // 0;pointsize;family;style;weight;underlined;facename;encoding
600 // 1;pointsize;family;style;weight;underlined;strikethrough;facename;encoding
602 bool wxNativeFontInfo::FromString(const wxString
& s
)
605 unsigned long version
;
607 wxStringTokenizer
tokenizer(s
, wxT(";"));
609 wxString token
= tokenizer
.GetNextToken();
610 if ( !token
.ToULong(&version
) || version
> 1 )
613 token
= tokenizer
.GetNextToken();
614 if ( !token
.ToLong(&l
) )
618 token
= tokenizer
.GetNextToken();
619 if ( !token
.ToLong(&l
) )
621 family
= (wxFontFamily
)l
;
623 token
= tokenizer
.GetNextToken();
624 if ( !token
.ToLong(&l
) )
626 style
= (wxFontStyle
)l
;
628 token
= tokenizer
.GetNextToken();
629 if ( !token
.ToLong(&l
) )
631 weight
= (wxFontWeight
)l
;
633 token
= tokenizer
.GetNextToken();
634 if ( !token
.ToLong(&l
) )
640 token
= tokenizer
.GetNextToken();
641 if ( !token
.ToLong(&l
) )
643 strikethrough
= l
!= 0;
646 faceName
= tokenizer
.GetNextToken();
653 token
= tokenizer
.GetNextToken();
654 if ( !token
.ToLong(&l
) )
656 encoding
= (wxFontEncoding
)l
;
661 wxString
wxNativeFontInfo::ToString() const
665 s
.Printf(wxT("%d;%d;%d;%d;%d;%d;%d;%s;%d"),
679 void wxNativeFontInfo::Init()
682 family
= wxFONTFAMILY_DEFAULT
;
683 style
= wxFONTSTYLE_NORMAL
;
684 weight
= wxFONTWEIGHT_NORMAL
;
686 strikethrough
= false;
688 encoding
= wxFONTENCODING_DEFAULT
;
691 int wxNativeFontInfo::GetPointSize() const
696 wxFontStyle
wxNativeFontInfo::GetStyle() const
701 wxFontWeight
wxNativeFontInfo::GetWeight() const
706 bool wxNativeFontInfo::GetUnderlined() const
711 bool wxNativeFontInfo::GetStrikethrough() const
713 return strikethrough
;
716 wxString
wxNativeFontInfo::GetFaceName() const
721 wxFontFamily
wxNativeFontInfo::GetFamily() const
726 wxFontEncoding
wxNativeFontInfo::GetEncoding() const
731 void wxNativeFontInfo::SetPointSize(int pointsize
)
733 pointSize
= pointsize
;
736 void wxNativeFontInfo::SetStyle(wxFontStyle style_
)
741 void wxNativeFontInfo::SetWeight(wxFontWeight weight_
)
746 void wxNativeFontInfo::SetUnderlined(bool underlined_
)
748 underlined
= underlined_
;
751 void wxNativeFontInfo::SetStrikethrough(bool strikethrough_
)
753 strikethrough
= strikethrough_
;
756 bool wxNativeFontInfo::SetFaceName(const wxString
& facename_
)
758 faceName
= facename_
;
762 void wxNativeFontInfo::SetFamily(wxFontFamily family_
)
767 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_
)
769 encoding
= encoding_
;
772 #endif // generic wxNativeFontInfo implementation
774 // conversion to/from user-readable string: this is used in the generic
775 // versions and under MSW as well because there is no standard font description
776 // format there anyhow (but there is a well-defined standard for X11 fonts used
777 // by wxGTK and wxMotif)
779 #if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__) || defined(__WXOSX__)
781 wxString
wxNativeFontInfo::ToUserString() const
785 // first put the adjectives, if any - this is English-centric, of course,
786 // but what else can we do?
787 if ( GetUnderlined() )
789 desc
<< _("underlined");
792 if ( GetStrikethrough() )
794 desc
<< _("strikethrough");
797 switch ( GetWeight() )
800 wxFAIL_MSG( wxT("unknown font weight") );
803 case wxFONTWEIGHT_NORMAL
:
806 case wxFONTWEIGHT_LIGHT
:
810 case wxFONTWEIGHT_BOLD
:
815 switch ( GetStyle() )
818 wxFAIL_MSG( wxT("unknown font style") );
821 case wxFONTSTYLE_NORMAL
:
824 // we don't distinguish between the two for now anyhow...
825 case wxFONTSTYLE_ITALIC
:
826 case wxFONTSTYLE_SLANT
:
827 desc
<< _(" italic");
831 wxString face
= GetFaceName();
834 if (face
.Contains(' ') || face
.Contains(';') || face
.Contains(','))
836 face
.Replace("'", "");
837 // eventually remove quote characters: most systems do not
838 // allow them in a facename anyway so this usually does nothing
840 // make it possible for FromUserString() function to understand
841 // that the different words which compose this facename are
842 // not different adjectives or other data but rather all parts
844 desc
<< wxT(" '") << face
<< wxT("'");
847 desc
<< wxT(' ') << face
;
849 else // no face name specified
853 switch ( GetFamily() )
855 case wxFONTFAMILY_DECORATIVE
:
856 familyStr
= "decorative";
859 case wxFONTFAMILY_ROMAN
:
863 case wxFONTFAMILY_SCRIPT
:
864 familyStr
= "script";
867 case wxFONTFAMILY_SWISS
:
871 case wxFONTFAMILY_MODERN
:
872 familyStr
= "modern";
875 case wxFONTFAMILY_TELETYPE
:
876 familyStr
= "teletype";
879 case wxFONTFAMILY_DEFAULT
:
880 case wxFONTFAMILY_UNKNOWN
:
884 wxFAIL_MSG( "unknown font family" );
887 if ( !familyStr
.empty() )
888 desc
<< " '" << familyStr
<< " family'";
891 int size
= GetPointSize();
892 if ( size
!= wxNORMAL_FONT
->GetPointSize() )
894 desc
<< wxT(' ') << size
;
898 wxFontEncoding enc
= GetEncoding();
899 if ( enc
!= wxFONTENCODING_DEFAULT
&& enc
!= wxFONTENCODING_SYSTEM
)
901 desc
<< wxT(' ') << wxFontMapper::GetEncodingName(enc
);
903 #endif // wxUSE_FONTMAP
905 return desc
.Strip(wxString::both
).MakeLower();
908 bool wxNativeFontInfo::FromUserString(const wxString
& s
)
910 // reset to the default state
913 // ToUserString() will quote the facename if it contains spaces, commas
914 // or semicolons: we must be able to understand that quoted text is
918 // parse a more or less free form string
919 wxStringTokenizer
tokenizer(toparse
, wxT(";, "), wxTOKEN_STRTOK
);
923 bool weightfound
= false, pointsizefound
= false;
925 bool encodingfound
= false;
927 bool insideQuotes
= false;
929 while ( tokenizer
.HasMoreTokens() )
931 wxString token
= tokenizer
.GetNextToken();
934 token
.Trim(true).Trim(false).MakeLower();
937 if (token
.StartsWith("'") ||
940 insideQuotes
= false;
942 // add this last token to the facename:
945 // normalize facename:
946 face
= face
.Trim(true).Trim(false);
947 face
.Replace("'", "");
954 if (token
.StartsWith("'"))
958 // look for the known tokens
961 // only the facename may be quoted:
965 if ( token
== wxT("underlined") || token
== _("underlined") )
969 else if ( token
== wxT("strikethrough") || token
== _("strikethrough") )
971 SetStrikethrough(true);
973 else if ( token
== wxT("light") || token
== _("light") )
975 SetWeight(wxFONTWEIGHT_LIGHT
);
978 else if ( token
== wxT("bold") || token
== _("bold") )
980 SetWeight(wxFONTWEIGHT_BOLD
);
983 else if ( token
== wxT("italic") || token
== _("italic") )
985 SetStyle(wxFONTSTYLE_ITALIC
);
987 else if ( token
.ToULong(&size
) )
990 pointsizefound
= true;
995 // try to interpret this as an encoding
996 wxFontEncoding encoding
= wxFontMapper::Get()->CharsetToEncoding(token
, false);
997 if ( encoding
!= wxFONTENCODING_DEFAULT
&&
998 encoding
!= wxFONTENCODING_SYSTEM
) // returned when the recognition failed
1000 SetEncoding(encoding
);
1001 encodingfound
= true;
1005 #endif // wxUSE_FONTMAP
1007 // assume it is the face name
1008 if ( !face
.empty() )
1015 // skip the code which resets face below
1020 #endif // wxUSE_FONTMAP
1023 // if we had had the facename, we shouldn't continue appending tokens
1024 // to it (i.e. "foo bold bar" shouldn't result in the facename "foo
1026 if ( !face
.empty() )
1029 if ( face
.EndsWith(" family", &familyStr
) )
1031 // it's not a facename but rather a font family
1032 wxFontFamily family
;
1033 if ( familyStr
== "decorative" )
1034 family
= wxFONTFAMILY_DECORATIVE
;
1035 else if ( familyStr
== "roman" )
1036 family
= wxFONTFAMILY_ROMAN
;
1037 else if ( familyStr
== "script" )
1038 family
= wxFONTFAMILY_SCRIPT
;
1039 else if ( familyStr
== "swiss" )
1040 family
= wxFONTFAMILY_SWISS
;
1041 else if ( familyStr
== "modern" )
1042 family
= wxFONTFAMILY_MODERN
;
1043 else if ( familyStr
== "teletype" )
1044 family
= wxFONTFAMILY_TELETYPE
;
1050 // NB: the check on the facename is implemented in wxFontBase::SetFaceName
1051 // and not in wxNativeFontInfo::SetFaceName thus we need to explicitly
1052 // call here wxFontEnumerator::IsValidFacename
1055 !wxFontEnumerator::IsValidFacename(face
) ||
1056 #endif // wxUSE_FONTENUM
1057 !SetFaceName(face
) )
1059 SetFaceName(wxNORMAL_FONT
->GetFaceName());
1066 // we might not have flushed it inside the loop
1067 if ( !face
.empty() )
1069 // NB: the check on the facename is implemented in wxFontBase::SetFaceName
1070 // and not in wxNativeFontInfo::SetFaceName thus we need to explicitly
1071 // call here wxFontEnumerator::IsValidFacename
1074 !wxFontEnumerator::IsValidFacename(face
) ||
1075 #endif // wxUSE_FONTENUM
1076 !SetFaceName(face
) )
1078 SetFaceName(wxNORMAL_FONT
->GetFaceName());
1082 // set point size to default value if size was not given
1083 if ( !pointsizefound
)
1084 SetPointSize(wxNORMAL_FONT
->GetPointSize());
1086 // set font weight to default value if weight was not given
1088 SetWeight(wxFONTWEIGHT_NORMAL
);
1091 // set font encoding to default value if encoding was not given
1092 if ( !encodingfound
)
1093 SetEncoding(wxFONTENCODING_SYSTEM
);
1094 #endif // wxUSE_FONTMAP
1099 #endif // generic or wxMSW or wxOS2
1102 // wxFont <-> wxString utilities, used by wxConfig
1103 wxString
wxToString(const wxFontBase
& font
)
1105 return font
.IsOk() ? font
.GetNativeFontInfoDesc()
1109 bool wxFromString(const wxString
& str
, wxFontBase
*font
)
1111 wxCHECK_MSG( font
, false, wxT("NULL output parameter") );
1119 return font
->SetNativeFontInfo(str
);