1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/fontcmn.cpp
3 // Purpose: implementation of wxFontBase methods
4 // Author: Vadim Zeitlin
8 // Copyright: (c) wxWidgets team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
33 #include "wx/dcscreen.h"
35 #include "wx/gdicmn.h"
38 #if defined(__WXMSW__)
39 #include "wx/msw/private.h" // includes windows.h for LOGFONT
40 #include "wx/msw/winundef.h"
43 #include "wx/fontutil.h" // for wxNativeFontInfo
44 #include "wx/fontmap.h"
45 #include "wx/fontenum.h"
47 #include "wx/tokenzr.h"
49 // debugger helper: this function can be called from a debugger to show what
51 extern const char *wxDumpFont(const wxFont
*font
)
55 const wxFontWeight weight
= font
->GetWeight();
58 s
.Printf(wxS("%s-%s-%s-%d-%d"),
60 weight
== wxFONTWEIGHT_NORMAL
62 : weight
== wxFONTWEIGHT_BOLD
65 font
->GetStyle() == wxFONTSTYLE_NORMAL
71 wxStrlcpy(buf
, s
.mb_str(), WXSIZEOF(buf
));
75 // ----------------------------------------------------------------------------
77 // ----------------------------------------------------------------------------
79 wxBEGIN_ENUM( wxFontFamily
)
80 wxENUM_MEMBER( wxFONTFAMILY_DEFAULT
)
81 wxENUM_MEMBER( wxFONTFAMILY_DECORATIVE
)
82 wxENUM_MEMBER( wxFONTFAMILY_ROMAN
)
83 wxENUM_MEMBER( wxFONTFAMILY_SCRIPT
)
84 wxENUM_MEMBER( wxFONTFAMILY_SWISS
)
85 wxENUM_MEMBER( wxFONTFAMILY_MODERN
)
86 wxENUM_MEMBER( wxFONTFAMILY_TELETYPE
)
87 wxEND_ENUM( wxFontFamily
)
89 wxBEGIN_ENUM( wxFontStyle
)
90 wxENUM_MEMBER( wxFONTSTYLE_NORMAL
)
91 wxENUM_MEMBER( wxFONTSTYLE_ITALIC
)
92 wxENUM_MEMBER( wxFONTSTYLE_SLANT
)
93 wxEND_ENUM( wxFontStyle
)
95 wxBEGIN_ENUM( wxFontWeight
)
96 wxENUM_MEMBER( wxFONTWEIGHT_NORMAL
)
97 wxENUM_MEMBER( wxFONTWEIGHT_LIGHT
)
98 wxENUM_MEMBER( wxFONTWEIGHT_BOLD
)
99 wxEND_ENUM( wxFontWeight
)
101 wxIMPLEMENT_DYNAMIC_CLASS_WITH_COPY_XTI(wxFont
, wxGDIObject
, "wx/font.h")
103 //WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxFont>)
105 wxBEGIN_PROPERTIES_TABLE(wxFont
)
106 wxPROPERTY( Size
,int, SetPointSize
, GetPointSize
, 12, 0 /*flags*/, \
107 wxT("Helpstring"), wxT("group"))
108 wxPROPERTY( Family
, wxFontFamily
, SetFamily
, GetFamily
, (wxFontFamily
)wxDEFAULT
, \
109 0 /*flags*/, wxT("Helpstring"), wxT("group")) // wxFontFamily
110 wxPROPERTY( Style
, wxFontStyle
, SetStyle
, GetStyle
, (wxFontStyle
)wxNORMAL
, 0 /*flags*/, \
111 wxT("Helpstring"), wxT("group")) // wxFontStyle
112 wxPROPERTY( Weight
, wxFontWeight
, SetWeight
, GetWeight
, (wxFontWeight
)wxNORMAL
, 0 /*flags*/, \
113 wxT("Helpstring"), wxT("group")) // wxFontWeight
114 wxPROPERTY( Underlined
, bool, SetUnderlined
, GetUnderlined
, false, 0 /*flags*/, \
115 wxT("Helpstring"), wxT("group"))
116 wxPROPERTY( Strikethrough
, bool, SetStrikethrough
, GetStrikethrough
, false, 0, \
117 wxT("Helpstring"), wxT("group"))
118 wxPROPERTY( Face
, wxString
, SetFaceName
, GetFaceName
, wxEMPTY_PARAMETER_VALUE
, \
119 0 /*flags*/, wxT("Helpstring"), wxT("group"))
120 wxPROPERTY( Encoding
, wxFontEncoding
, SetEncoding
, GetEncoding
, \
121 wxFONTENCODING_DEFAULT
, 0 /*flags*/, wxT("Helpstring"), wxT("group"))
122 wxEND_PROPERTIES_TABLE()
124 wxCONSTRUCTOR_6( wxFont
, int, Size
, wxFontFamily
, Family
, wxFontStyle
, Style
, wxFontWeight
, Weight
, \
125 bool, Underlined
, wxString
, Face
)
127 wxEMPTY_HANDLERS_TABLE(wxFont
)
129 // ============================================================================
131 // ============================================================================
133 // ----------------------------------------------------------------------------
135 // ----------------------------------------------------------------------------
137 wxFontEncoding
wxFontBase::ms_encodingDefault
= wxFONTENCODING_SYSTEM
;
140 void wxFontBase::SetDefaultEncoding(wxFontEncoding encoding
)
142 // GetDefaultEncoding() should return something != wxFONTENCODING_DEFAULT
143 // and, besides, using this value here doesn't make any sense
144 wxCHECK_RET( encoding
!= wxFONTENCODING_DEFAULT
,
145 wxT("can't set default encoding to wxFONTENCODING_DEFAULT") );
147 ms_encodingDefault
= encoding
;
150 wxFontBase::~wxFontBase()
152 // this destructor is required for Darwin
156 wxFont
*wxFontBase::New(int size
,
161 const wxString
& face
,
162 wxFontEncoding encoding
)
164 return new wxFont(size
, family
, style
, weight
, underlined
, face
, encoding
);
168 wxFont
*wxFontBase::New(const wxSize
& pixelSize
,
173 const wxString
& face
,
174 wxFontEncoding encoding
)
176 return new wxFont(pixelSize
, family
, style
, weight
, underlined
,
181 wxFont
*wxFontBase::New(int pointSize
,
184 const wxString
& face
,
185 wxFontEncoding encoding
)
187 return New(pointSize
, family
,
188 GetStyleFromFlags(flags
),
189 GetWeightFromFlags(flags
),
190 GetUnderlinedFromFlags(flags
),
195 wxFont
*wxFontBase::New(const wxSize
& pixelSize
,
198 const wxString
& face
,
199 wxFontEncoding encoding
)
201 return New(pixelSize
, family
,
202 GetStyleFromFlags(flags
),
203 GetWeightFromFlags(flags
),
204 GetUnderlinedFromFlags(flags
),
209 wxFont
*wxFontBase::New(const wxNativeFontInfo
& info
)
211 return new wxFont(info
);
215 wxFont
*wxFontBase::New(const wxString
& strNativeFontDesc
)
217 wxNativeFontInfo fontInfo
;
218 if ( !fontInfo
.FromString(strNativeFontDesc
) )
219 return new wxFont(*wxNORMAL_FONT
);
221 return New(fontInfo
);
224 bool wxFontBase::IsFixedWidth() const
226 return GetFamily() == wxFONTFAMILY_TELETYPE
;
229 wxSize
wxFontBase::GetPixelSize() const
232 dc
.SetFont(*(wxFont
*)this);
233 return wxSize(dc
.GetCharWidth(), dc
.GetCharHeight());
236 bool wxFontBase::IsUsingSizeInPixels() const
241 void wxFontBase::SetPixelSize( const wxSize
& pixelSize
)
243 wxCHECK_RET( pixelSize
.GetWidth() >= 0 && pixelSize
.GetHeight() > 0,
244 "Negative values for the pixel size or zero pixel height are not allowed" );
248 // NOTE: this algorithm for adjusting the font size is used by all
249 // implementations of wxFont except under wxMSW and wxGTK where
250 // native support to font creation using pixel-size is provided.
255 bool initialGoodFound
= false;
256 bool initialBadFound
= false;
258 // NB: this assignment was separated from the variable definition
259 // in order to fix a gcc v3.3.3 compiler crash
260 int currentSize
= GetPointSize();
261 while (currentSize
> 0)
263 dc
.SetFont(*static_cast<wxFont
*>(this));
265 // if currentSize (in points) results in a font that is smaller
266 // than required by pixelSize it is considered a good size
267 // NOTE: the pixel size width may be zero
268 if (dc
.GetCharHeight() <= pixelSize
.GetHeight() &&
269 (pixelSize
.GetWidth() == 0 ||
270 dc
.GetCharWidth() <= pixelSize
.GetWidth()))
272 largestGood
= currentSize
;
273 initialGoodFound
= true;
277 smallestBad
= currentSize
;
278 initialBadFound
= true;
280 if (!initialGoodFound
)
284 else if (!initialBadFound
)
290 int distance
= smallestBad
- largestGood
;
294 currentSize
= largestGood
+ distance
/ 2;
297 SetPointSize(currentSize
);
300 if (currentSize
!= largestGood
)
301 SetPointSize(largestGood
);
304 void wxFontBase::DoSetNativeFontInfo(const wxNativeFontInfo
& info
)
306 #ifdef wxNO_NATIVE_FONTINFO
307 SetPointSize(info
.pointSize
);
308 SetFamily(info
.family
);
309 SetStyle(info
.style
);
310 SetWeight(info
.weight
);
311 SetUnderlined(info
.underlined
);
312 SetStrikethrough(info
.strikethrough
);
313 SetFaceName(info
.faceName
);
314 SetEncoding(info
.encoding
);
320 wxString
wxFontBase::GetNativeFontInfoDesc() const
322 wxCHECK_MSG( IsOk(), wxEmptyString
, wxT("invalid font") );
325 const wxNativeFontInfo
*fontInfo
= GetNativeFontInfo();
328 fontDesc
= fontInfo
->ToString();
329 wxASSERT_MSG(!fontDesc
.empty(), wxT("This should be a non-empty string!"));
333 wxFAIL_MSG(wxT("Derived class should have created the wxNativeFontInfo!"));
339 wxString
wxFontBase::GetNativeFontInfoUserDesc() const
341 wxCHECK_MSG( IsOk(), wxEmptyString
, wxT("invalid font") );
344 const wxNativeFontInfo
*fontInfo
= GetNativeFontInfo();
347 fontDesc
= fontInfo
->ToUserString();
348 wxASSERT_MSG(!fontDesc
.empty(), wxT("This should be a non-empty string!"));
352 wxFAIL_MSG(wxT("Derived class should have created the wxNativeFontInfo!"));
358 bool wxFontBase::SetNativeFontInfo(const wxString
& info
)
360 wxNativeFontInfo fontInfo
;
361 if ( !info
.empty() && fontInfo
.FromString(info
) )
363 SetNativeFontInfo(fontInfo
);
370 bool wxFontBase::SetNativeFontInfoUserDesc(const wxString
& info
)
372 wxNativeFontInfo fontInfo
;
373 if ( !info
.empty() && fontInfo
.FromUserString(info
) )
375 SetNativeFontInfo(fontInfo
);
382 bool wxFontBase::operator==(const wxFont
& font
) const
384 // either it is the same font, i.e. they share the same common data or they
385 // have different ref datas but still describe the same font
386 return IsSameAs(font
) ||
388 IsOk() == font
.IsOk() &&
389 GetPointSize() == font
.GetPointSize() &&
390 // in wxGTK1 GetPixelSize() calls GetInternalFont() which uses
391 // operator==() resulting in infinite recursion so we can't use it
393 #if !defined(__WXGTK__) || defined(__WXGTK20__)
394 GetPixelSize() == font
.GetPixelSize() &&
396 GetFamily() == font
.GetFamily() &&
397 GetStyle() == font
.GetStyle() &&
398 GetWeight() == font
.GetWeight() &&
399 GetUnderlined() == font
.GetUnderlined() &&
400 GetStrikethrough() == font
.GetStrikethrough() &&
401 GetFaceName().IsSameAs(font
.GetFaceName(), false) &&
402 GetEncoding() == font
.GetEncoding()
406 wxFontFamily
wxFontBase::GetFamily() const
408 wxCHECK_MSG( IsOk(), wxFONTFAMILY_UNKNOWN
, wxS("invalid font") );
410 // Don't return wxFONTFAMILY_UNKNOWN from here because it prevents the code
411 // like wxFont(size, wxNORMAL_FONT->GetFamily(), ...) from working (see
412 // #12330). This is really just a hack but it allows to keep compatibility
413 // and doesn't really have any bad drawbacks so do this until someone comes
414 // up with a better idea.
415 const wxFontFamily family
= DoGetFamily();
417 return family
== wxFONTFAMILY_UNKNOWN
? wxFONTFAMILY_DEFAULT
: family
;
420 wxString
wxFontBase::GetFamilyString() const
422 wxCHECK_MSG( IsOk(), "wxFONTFAMILY_DEFAULT", "invalid font" );
424 switch ( GetFamily() )
426 case wxFONTFAMILY_DECORATIVE
: return "wxFONTFAMILY_DECORATIVE";
427 case wxFONTFAMILY_ROMAN
: return "wxFONTFAMILY_ROMAN";
428 case wxFONTFAMILY_SCRIPT
: return "wxFONTFAMILY_SCRIPT";
429 case wxFONTFAMILY_SWISS
: return "wxFONTFAMILY_SWISS";
430 case wxFONTFAMILY_MODERN
: return "wxFONTFAMILY_MODERN";
431 case wxFONTFAMILY_TELETYPE
: return "wxFONTFAMILY_TELETYPE";
432 case wxFONTFAMILY_UNKNOWN
: return "wxFONTFAMILY_UNKNOWN";
433 default: return "wxFONTFAMILY_DEFAULT";
437 wxString
wxFontBase::GetStyleString() const
439 wxCHECK_MSG( IsOk(), "wxFONTSTYLE_DEFAULT", "invalid font" );
441 switch ( GetStyle() )
443 case wxFONTSTYLE_NORMAL
: return "wxFONTSTYLE_NORMAL";
444 case wxFONTSTYLE_SLANT
: return "wxFONTSTYLE_SLANT";
445 case wxFONTSTYLE_ITALIC
: return "wxFONTSTYLE_ITALIC";
446 default: return "wxFONTSTYLE_DEFAULT";
450 wxString
wxFontBase::GetWeightString() const
452 wxCHECK_MSG( IsOk(), "wxFONTWEIGHT_DEFAULT", "invalid font" );
454 switch ( GetWeight() )
456 case wxFONTWEIGHT_NORMAL
: return "wxFONTWEIGHT_NORMAL";
457 case wxFONTWEIGHT_BOLD
: return "wxFONTWEIGHT_BOLD";
458 case wxFONTWEIGHT_LIGHT
: return "wxFONTWEIGHT_LIGHT";
459 default: return "wxFONTWEIGHT_DEFAULT";
463 bool wxFontBase::SetFaceName(const wxString
& facename
)
466 if (!wxFontEnumerator::IsValidFacename(facename
))
468 UnRef(); // make IsOk() return false
471 #else // !wxUSE_FONTENUM
472 wxUnusedVar(facename
);
473 #endif // wxUSE_FONTENUM/!wxUSE_FONTENUM
478 void wxFontBase::SetSymbolicSize(wxFontSymbolicSize size
)
480 SetSymbolicSizeRelativeTo(size
, wxNORMAL_FONT
->GetPointSize());
484 int wxFontBase::AdjustToSymbolicSize(wxFontSymbolicSize size
, int base
)
486 // Using a fixed factor (1.2, from CSS2) is a bad idea as explained at
487 // http://www.w3.org/TR/CSS21/fonts.html#font-size-props so use the values
488 // from http://style.cleverchimp.com/font_size_intervals/altintervals.html
490 static const float factors
[] = { 0.60f
, 0.75f
, 0.89f
, 1.f
, 1.2f
, 1.5f
, 2.f
};
492 wxCOMPILE_TIME_ASSERT
494 WXSIZEOF(factors
) == wxFONTSIZE_XX_LARGE
- wxFONTSIZE_XX_SMALL
+ 1,
495 WrongFontSizeFactorsSize
498 return wxRound(factors
[size
- wxFONTSIZE_XX_SMALL
]*base
);
501 wxFont
& wxFont::MakeBold()
503 SetWeight(wxFONTWEIGHT_BOLD
);
507 wxFont
wxFont::Bold() const
514 wxFont
& wxFont::MakeItalic()
516 SetStyle(wxFONTSTYLE_ITALIC
);
520 wxFont
wxFont::Italic() const
527 wxFont
& wxFont::MakeUnderlined()
533 wxFont
wxFont::Underlined() const
536 font
.MakeUnderlined();
540 wxFont
wxFont::Strikethrough() const
543 font
.MakeStrikethrough();
547 wxFont
& wxFont::MakeStrikethrough()
549 SetStrikethrough(true);
553 wxFont
& wxFont::Scale(float x
)
555 SetPointSize(int(x
*GetPointSize() + 0.5));
559 wxFont
wxFont::Scaled(float x
) const
566 // ----------------------------------------------------------------------------
568 // ----------------------------------------------------------------------------
570 // Up to now, there are no native implementations of this function:
571 void wxNativeFontInfo::SetFaceName(const wxArrayString
& facenames
)
574 for (size_t i
=0; i
< facenames
.GetCount(); i
++)
576 if (wxFontEnumerator::IsValidFacename(facenames
[i
]))
578 SetFaceName(facenames
[i
]);
583 // set the first valid facename we can find on this system
584 wxString validfacename
= wxFontEnumerator::GetFacenames().Item(0);
585 wxLogTrace(wxT("font"), wxT("Falling back to '%s'"), validfacename
.c_str());
586 SetFaceName(validfacename
);
587 #else // !wxUSE_FONTENUM
588 SetFaceName(facenames
[0]);
589 #endif // wxUSE_FONTENUM/!wxUSE_FONTENUM
593 #ifdef wxNO_NATIVE_FONTINFO
595 // These are the generic forms of FromString()/ToString.
597 // convert to/from the string representation: the general format is
598 // "version;the rest..." with currently defined versions being:
600 // 0;pointsize;family;style;weight;underlined;facename;encoding
601 // 1;pointsize;family;style;weight;underlined;strikethrough;facename;encoding
603 bool wxNativeFontInfo::FromString(const wxString
& s
)
606 unsigned long version
;
608 wxStringTokenizer
tokenizer(s
, wxT(";"));
610 wxString token
= tokenizer
.GetNextToken();
611 if ( !token
.ToULong(&version
) || version
> 1 )
614 token
= tokenizer
.GetNextToken();
615 if ( !token
.ToLong(&l
) )
619 token
= tokenizer
.GetNextToken();
620 if ( !token
.ToLong(&l
) )
622 family
= (wxFontFamily
)l
;
624 token
= tokenizer
.GetNextToken();
625 if ( !token
.ToLong(&l
) )
627 style
= (wxFontStyle
)l
;
629 token
= tokenizer
.GetNextToken();
630 if ( !token
.ToLong(&l
) )
632 weight
= (wxFontWeight
)l
;
634 token
= tokenizer
.GetNextToken();
635 if ( !token
.ToLong(&l
) )
641 token
= tokenizer
.GetNextToken();
642 if ( !token
.ToLong(&l
) )
644 strikethrough
= l
!= 0;
647 faceName
= tokenizer
.GetNextToken();
654 token
= tokenizer
.GetNextToken();
655 if ( !token
.ToLong(&l
) )
657 encoding
= (wxFontEncoding
)l
;
662 wxString
wxNativeFontInfo::ToString() const
666 s
.Printf(wxT("%d;%d;%d;%d;%d;%d;%d;%s;%d"),
680 void wxNativeFontInfo::Init()
683 family
= wxFONTFAMILY_DEFAULT
;
684 style
= wxFONTSTYLE_NORMAL
;
685 weight
= wxFONTWEIGHT_NORMAL
;
687 strikethrough
= false;
689 encoding
= wxFONTENCODING_DEFAULT
;
692 int wxNativeFontInfo::GetPointSize() const
697 wxFontStyle
wxNativeFontInfo::GetStyle() const
702 wxFontWeight
wxNativeFontInfo::GetWeight() const
707 bool wxNativeFontInfo::GetUnderlined() const
712 bool wxNativeFontInfo::GetStrikethrough() const
714 return strikethrough
;
717 wxString
wxNativeFontInfo::GetFaceName() const
722 wxFontFamily
wxNativeFontInfo::GetFamily() const
727 wxFontEncoding
wxNativeFontInfo::GetEncoding() const
732 void wxNativeFontInfo::SetPointSize(int pointsize
)
734 pointSize
= pointsize
;
737 void wxNativeFontInfo::SetStyle(wxFontStyle style_
)
742 void wxNativeFontInfo::SetWeight(wxFontWeight weight_
)
747 void wxNativeFontInfo::SetUnderlined(bool underlined_
)
749 underlined
= underlined_
;
752 void wxNativeFontInfo::SetStrikethrough(bool strikethrough_
)
754 strikethrough
= strikethrough_
;
757 bool wxNativeFontInfo::SetFaceName(const wxString
& facename_
)
759 faceName
= facename_
;
763 void wxNativeFontInfo::SetFamily(wxFontFamily family_
)
768 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_
)
770 encoding
= encoding_
;
773 #endif // generic wxNativeFontInfo implementation
775 // conversion to/from user-readable string: this is used in the generic
776 // versions and under MSW as well because there is no standard font description
777 // format there anyhow (but there is a well-defined standard for X11 fonts used
778 // by wxGTK and wxMotif)
780 #if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__) || defined(__WXOSX__)
782 wxString
wxNativeFontInfo::ToUserString() const
786 // first put the adjectives, if any - this is English-centric, of course,
787 // but what else can we do?
788 if ( GetUnderlined() )
790 desc
<< _("underlined");
793 if ( GetStrikethrough() )
795 desc
<< _("strikethrough");
798 switch ( GetWeight() )
801 wxFAIL_MSG( wxT("unknown font weight") );
804 case wxFONTWEIGHT_NORMAL
:
807 case wxFONTWEIGHT_LIGHT
:
811 case wxFONTWEIGHT_BOLD
:
816 switch ( GetStyle() )
819 wxFAIL_MSG( wxT("unknown font style") );
822 case wxFONTSTYLE_NORMAL
:
825 // we don't distinguish between the two for now anyhow...
826 case wxFONTSTYLE_ITALIC
:
827 case wxFONTSTYLE_SLANT
:
828 desc
<< _(" italic");
832 wxString face
= GetFaceName();
835 if (face
.Contains(' ') || face
.Contains(';') || face
.Contains(','))
837 face
.Replace("'", "");
838 // eventually remove quote characters: most systems do not
839 // allow them in a facename anyway so this usually does nothing
841 // make it possible for FromUserString() function to understand
842 // that the different words which compose this facename are
843 // not different adjectives or other data but rather all parts
845 desc
<< wxT(" '") << face
<< _("'");
848 desc
<< wxT(' ') << face
;
850 else // no face name specified
854 switch ( GetFamily() )
856 case wxFONTFAMILY_DECORATIVE
:
857 familyStr
= "decorative";
860 case wxFONTFAMILY_ROMAN
:
864 case wxFONTFAMILY_SCRIPT
:
865 familyStr
= "script";
868 case wxFONTFAMILY_SWISS
:
872 case wxFONTFAMILY_MODERN
:
873 familyStr
= "modern";
876 case wxFONTFAMILY_TELETYPE
:
877 familyStr
= "teletype";
880 case wxFONTFAMILY_DEFAULT
:
881 case wxFONTFAMILY_UNKNOWN
:
885 wxFAIL_MSG( "unknown font family" );
888 if ( !familyStr
.empty() )
889 desc
<< " '" << familyStr
<< " family'";
892 int size
= GetPointSize();
893 if ( size
!= wxNORMAL_FONT
->GetPointSize() )
895 desc
<< wxT(' ') << size
;
899 wxFontEncoding enc
= GetEncoding();
900 if ( enc
!= wxFONTENCODING_DEFAULT
&& enc
!= wxFONTENCODING_SYSTEM
)
902 desc
<< wxT(' ') << wxFontMapper::GetEncodingName(enc
);
904 #endif // wxUSE_FONTMAP
906 return desc
.Strip(wxString::both
).MakeLower();
909 bool wxNativeFontInfo::FromUserString(const wxString
& s
)
911 // reset to the default state
914 // ToUserString() will quote the facename if it contains spaces, commas
915 // or semicolons: we must be able to understand that quoted text is
919 // parse a more or less free form string
920 wxStringTokenizer
tokenizer(toparse
, wxT(";, "), wxTOKEN_STRTOK
);
924 bool weightfound
= false, pointsizefound
= false;
926 bool encodingfound
= false;
928 bool insideQuotes
= false;
930 while ( tokenizer
.HasMoreTokens() )
932 wxString token
= tokenizer
.GetNextToken();
935 token
.Trim(true).Trim(false).MakeLower();
938 if (token
.StartsWith("'") ||
941 insideQuotes
= false;
943 // add this last token to the facename:
946 // normalize facename:
947 face
= face
.Trim(true).Trim(false);
948 face
.Replace("'", "");
955 if (token
.StartsWith("'"))
959 // look for the known tokens
962 // only the facename may be quoted:
966 if ( token
== wxT("underlined") || token
== _("underlined") )
970 else if ( token
== wxT("strikethrough") || token
== _("strikethrough") )
972 SetStrikethrough(true);
974 else if ( token
== wxT("light") || token
== _("light") )
976 SetWeight(wxFONTWEIGHT_LIGHT
);
979 else if ( token
== wxT("bold") || token
== _("bold") )
981 SetWeight(wxFONTWEIGHT_BOLD
);
984 else if ( token
== wxT("italic") || token
== _("italic") )
986 SetStyle(wxFONTSTYLE_ITALIC
);
988 else if ( token
.ToULong(&size
) )
991 pointsizefound
= true;
996 // try to interpret this as an encoding
997 wxFontEncoding encoding
= wxFontMapper::Get()->CharsetToEncoding(token
, false);
998 if ( encoding
!= wxFONTENCODING_DEFAULT
&&
999 encoding
!= wxFONTENCODING_SYSTEM
) // returned when the recognition failed
1001 SetEncoding(encoding
);
1002 encodingfound
= true;
1006 #endif // wxUSE_FONTMAP
1008 // assume it is the face name
1009 if ( !face
.empty() )
1016 // skip the code which resets face below
1021 #endif // wxUSE_FONTMAP
1024 // if we had had the facename, we shouldn't continue appending tokens
1025 // to it (i.e. "foo bold bar" shouldn't result in the facename "foo
1027 if ( !face
.empty() )
1030 if ( face
.EndsWith(" family", &familyStr
) )
1032 // it's not a facename but rather a font family
1033 wxFontFamily family
;
1034 if ( familyStr
== "decorative" )
1035 family
= wxFONTFAMILY_DECORATIVE
;
1036 else if ( familyStr
== "roman" )
1037 family
= wxFONTFAMILY_ROMAN
;
1038 else if ( familyStr
== "script" )
1039 family
= wxFONTFAMILY_SCRIPT
;
1040 else if ( familyStr
== "swiss" )
1041 family
= wxFONTFAMILY_SWISS
;
1042 else if ( familyStr
== "modern" )
1043 family
= wxFONTFAMILY_MODERN
;
1044 else if ( familyStr
== "teletype" )
1045 family
= wxFONTFAMILY_TELETYPE
;
1051 // NB: the check on the facename is implemented in wxFontBase::SetFaceName
1052 // and not in wxNativeFontInfo::SetFaceName thus we need to explicitly
1053 // call here wxFontEnumerator::IsValidFacename
1056 !wxFontEnumerator::IsValidFacename(face
) ||
1057 #endif // wxUSE_FONTENUM
1058 !SetFaceName(face
) )
1060 SetFaceName(wxNORMAL_FONT
->GetFaceName());
1067 // we might not have flushed it inside the loop
1068 if ( !face
.empty() )
1070 // NB: the check on the facename is implemented in wxFontBase::SetFaceName
1071 // and not in wxNativeFontInfo::SetFaceName thus we need to explicitly
1072 // call here wxFontEnumerator::IsValidFacename
1075 !wxFontEnumerator::IsValidFacename(face
) ||
1076 #endif // wxUSE_FONTENUM
1077 !SetFaceName(face
) )
1079 SetFaceName(wxNORMAL_FONT
->GetFaceName());
1083 // set point size to default value if size was not given
1084 if ( !pointsizefound
)
1085 SetPointSize(wxNORMAL_FONT
->GetPointSize());
1087 // set font weight to default value if weight was not given
1089 SetWeight(wxFONTWEIGHT_NORMAL
);
1092 // set font encoding to default value if encoding was not given
1093 if ( !encodingfound
)
1094 SetEncoding(wxFONTENCODING_SYSTEM
);
1095 #endif // wxUSE_FONTMAP
1100 #endif // generic or wxMSW or wxOS2
1103 // wxFont <-> wxString utilities, used by wxConfig
1104 wxString
wxToString(const wxFontBase
& font
)
1106 return font
.IsOk() ? font
.GetNativeFontInfoDesc()
1110 bool wxFromString(const wxString
& str
, wxFontBase
*font
)
1112 wxCHECK_MSG( font
, false, wxT("NULL output parameter") );
1120 return font
->SetNativeFontInfo(str
);