+bool wxFontBase::SetFaceName(const wxString& facename)
+{
+#if wxUSE_FONTENUM
+ if (!wxFontEnumerator::IsValidFacename(facename))
+ {
+ UnRef(); // make IsOk() return false
+ return false;
+ }
+#else // !wxUSE_FONTENUM
+ wxUnusedVar(facename);
+#endif // wxUSE_FONTENUM/!wxUSE_FONTENUM
+
+ return true;
+}
+
+void wxFontBase::SetSymbolicSize(wxFontSymbolicSize size)
+{
+ SetSymbolicSizeRelativeTo(size, wxNORMAL_FONT->GetPointSize());
+}
+
+/* static */
+int wxFontBase::AdjustToSymbolicSize(wxFontSymbolicSize size, int base)
+{
+ // Using a fixed factor (1.2, from CSS2) is a bad idea as explained at
+ // http://www.w3.org/TR/CSS21/fonts.html#font-size-props so use the values
+ // from http://style.cleverchimp.com/font_size_intervals/altintervals.html
+ // instead.
+ static const float factors[] = { 0.60f, 0.75f, 0.89f, 1.f, 1.2f, 1.5f, 2.f };
+
+ wxCOMPILE_TIME_ASSERT
+ (
+ WXSIZEOF(factors) == wxFONTSIZE_XX_LARGE - wxFONTSIZE_XX_SMALL + 1,
+ WrongFontSizeFactorsSize
+ );
+
+ return wxRound(factors[size - wxFONTSIZE_XX_SMALL]*base);
+}
+
+wxFont& wxFont::MakeBold()
+{
+ SetWeight(wxFONTWEIGHT_BOLD);
+ return *this;
+}
+
+wxFont wxFont::Bold() const
+{
+ wxFont font(*this);
+ font.MakeBold();
+ return font;
+}
+
+wxFont& wxFont::MakeItalic()
+{
+ SetStyle(wxFONTSTYLE_ITALIC);
+ return *this;
+}
+
+wxFont wxFont::Italic() const
+{
+ wxFont font(*this);
+ font.MakeItalic();
+ return font;
+}
+
+wxFont& wxFont::MakeUnderlined()
+{
+ SetUnderlined(true);
+ return *this;
+}
+
+wxFont wxFont::Underlined() const
+{
+ wxFont font(*this);
+ font.MakeUnderlined();
+ return font;
+}
+
+wxFont& wxFont::Scale(float x)
+{
+ SetPointSize(int(x*GetPointSize() + 0.5));
+ return *this;
+}
+
+wxFont wxFont::Scaled(float x) const
+{
+ wxFont font(*this);
+ font.Scale(x);
+ return font;
+}
+
+// ----------------------------------------------------------------------------
+// wxNativeFontInfo
+// ----------------------------------------------------------------------------
+
+// Up to now, there are no native implementations of this function:
+void wxNativeFontInfo::SetFaceName(const wxArrayString& facenames)
+{
+#if wxUSE_FONTENUM
+ for (size_t i=0; i < facenames.GetCount(); i++)
+ {
+ if (wxFontEnumerator::IsValidFacename(facenames[i]))
+ {
+ SetFaceName(facenames[i]);
+ return;
+ }
+ }
+
+ // set the first valid facename we can find on this system
+ wxString validfacename = wxFontEnumerator::GetFacenames().Item(0);
+ wxLogTrace(wxT("font"), wxT("Falling back to '%s'"), validfacename.c_str());
+ SetFaceName(validfacename);
+#else // !wxUSE_FONTENUM
+ SetFaceName(facenames[0]);
+#endif // wxUSE_FONTENUM/!wxUSE_FONTENUM
+}
+
+
+#ifdef wxNO_NATIVE_FONTINFO
+
+// These are the generic forms of FromString()/ToString.
+//
+// convert to/from the string representation: format is
+// version;pointsize;family;style;weight;underlined;facename;encoding
+
+bool wxNativeFontInfo::FromString(const wxString& s)
+{
+ long l;
+
+ wxStringTokenizer tokenizer(s, wxT(";"));
+
+ wxString token = tokenizer.GetNextToken();
+ //
+ // Ignore the version for now
+ //
+
+ token = tokenizer.GetNextToken();
+ if ( !token.ToLong(&l) )
+ return false;
+ pointSize = (int)l;
+
+ token = tokenizer.GetNextToken();
+ if ( !token.ToLong(&l) )
+ return false;
+ family = (wxFontFamily)l;
+
+ token = tokenizer.GetNextToken();
+ if ( !token.ToLong(&l) )
+ return false;
+ style = (wxFontStyle)l;
+
+ token = tokenizer.GetNextToken();
+ if ( !token.ToLong(&l) )
+ return false;
+ weight = (wxFontWeight)l;
+
+ token = tokenizer.GetNextToken();
+ if ( !token.ToLong(&l) )
+ return false;
+ underlined = l != 0;
+
+ faceName = tokenizer.GetNextToken();
+
+#ifndef __WXMAC__
+ if( !faceName )
+ return false;
+#endif
+
+ token = tokenizer.GetNextToken();
+ if ( !token.ToLong(&l) )
+ return false;
+ encoding = (wxFontEncoding)l;
+
+ return true;
+}
+
+wxString wxNativeFontInfo::ToString() const
+{
+ wxString s;
+
+ s.Printf(wxT("%d;%d;%d;%d;%d;%d;%s;%d"),
+ 0, // version
+ pointSize,
+ family,
+ (int)style,
+ (int)weight,
+ underlined,
+ faceName.GetData(),
+ (int)encoding);
+
+ return s;
+}
+
+void wxNativeFontInfo::Init()
+{
+ pointSize = 0;
+ family = wxFONTFAMILY_DEFAULT;
+ style = wxFONTSTYLE_NORMAL;
+ weight = wxFONTWEIGHT_NORMAL;
+ underlined = false;
+ faceName.clear();
+ encoding = wxFONTENCODING_DEFAULT;
+}
+
+int wxNativeFontInfo::GetPointSize() const
+{
+ return pointSize;
+}
+
+wxFontStyle wxNativeFontInfo::GetStyle() const
+{
+ return style;
+}
+
+wxFontWeight wxNativeFontInfo::GetWeight() const
+{
+ return weight;
+}
+
+bool wxNativeFontInfo::GetUnderlined() const
+{
+ return underlined;
+}
+
+wxString wxNativeFontInfo::GetFaceName() const
+{
+ return faceName;
+}
+
+wxFontFamily wxNativeFontInfo::GetFamily() const
+{
+ return family;
+}
+
+wxFontEncoding wxNativeFontInfo::GetEncoding() const
+{
+ return encoding;
+}
+
+void wxNativeFontInfo::SetPointSize(int pointsize)
+{
+ pointSize = pointsize;
+}
+
+void wxNativeFontInfo::SetStyle(wxFontStyle style_)
+{
+ style = style_;
+}
+
+void wxNativeFontInfo::SetWeight(wxFontWeight weight_)
+{
+ weight = weight_;
+}
+
+void wxNativeFontInfo::SetUnderlined(bool underlined_)
+{
+ underlined = underlined_;
+}
+
+bool wxNativeFontInfo::SetFaceName(const wxString& facename_)
+{
+ faceName = facename_;
+ return true;
+}
+
+void wxNativeFontInfo::SetFamily(wxFontFamily family_)
+{
+ family = family_;
+}
+
+void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
+{
+ encoding = encoding_;
+}
+
+#endif // generic wxNativeFontInfo implementation
+
+// conversion to/from user-readable string: this is used in the generic
+// versions and under MSW as well because there is no standard font description
+// format there anyhow (but there is a well-defined standard for X11 fonts used
+// by wxGTK and wxMotif)
+
+#if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__) || defined(__WXOSX__)
+
+wxString wxNativeFontInfo::ToUserString() const
+{
+ wxString desc;
+
+ // first put the adjectives, if any - this is English-centric, of course,
+ // but what else can we do?
+ if ( GetUnderlined() )
+ {
+ desc << _("underlined");
+ }
+
+ switch ( GetWeight() )
+ {
+ default:
+ wxFAIL_MSG( wxT("unknown font weight") );
+ // fall through
+
+ case wxFONTWEIGHT_NORMAL:
+ break;
+
+ case wxFONTWEIGHT_LIGHT:
+ desc << _(" light");
+ break;
+
+ case wxFONTWEIGHT_BOLD:
+ desc << _(" bold");
+ break;
+ }
+
+ switch ( GetStyle() )
+ {
+ default:
+ wxFAIL_MSG( wxT("unknown font style") );
+ // fall through
+
+ case wxFONTSTYLE_NORMAL:
+ break;
+
+ // we don't distinguish between the two for now anyhow...
+ case wxFONTSTYLE_ITALIC:
+ case wxFONTSTYLE_SLANT:
+ desc << _(" italic");
+ break;
+ }
+
+ wxString face = GetFaceName();
+ if ( !face.empty() )
+ {
+ if (face.Contains(' ') || face.Contains(';') || face.Contains(','))
+ {
+ face.Replace("'", "");
+ // eventually remove quote characters: most systems do not
+ // allow them in a facename anyway so this usually does nothing
+
+ // make it possible for FromUserString() function to understand
+ // that the different words which compose this facename are
+ // not different adjectives or other data but rather all parts
+ // of the facename
+ desc << wxT(" '") << face << _("'");
+ }
+ else
+ desc << wxT(' ') << face;
+ }
+ else // no face name specified
+ {
+ // use the family
+ wxString familyStr;
+ switch ( GetFamily() )
+ {
+ case wxFONTFAMILY_DECORATIVE:
+ familyStr = "decorative";
+ break;
+
+ case wxFONTFAMILY_ROMAN:
+ familyStr = "roman";
+ break;
+
+ case wxFONTFAMILY_SCRIPT:
+ familyStr = "script";
+ break;
+
+ case wxFONTFAMILY_SWISS:
+ familyStr = "swiss";
+ break;
+
+ case wxFONTFAMILY_MODERN:
+ familyStr = "modern";
+ break;
+
+ case wxFONTFAMILY_TELETYPE:
+ familyStr = "teletype";
+ break;
+
+ case wxFONTFAMILY_DEFAULT:
+ case wxFONTFAMILY_UNKNOWN:
+ break;
+
+ default:
+ wxFAIL_MSG( "unknown font family" );
+ }
+
+ if ( !familyStr.empty() )
+ desc << " '" << familyStr << " family'";
+ }
+
+ int size = GetPointSize();
+ if ( size != wxNORMAL_FONT->GetPointSize() )
+ {
+ desc << wxT(' ') << size;
+ }
+
+#if wxUSE_FONTMAP
+ wxFontEncoding enc = GetEncoding();
+ if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM )
+ {
+ desc << wxT(' ') << wxFontMapper::GetEncodingName(enc);
+ }
+#endif // wxUSE_FONTMAP
+
+ return desc.Strip(wxString::both).MakeLower();
+}
+
+bool wxNativeFontInfo::FromUserString(const wxString& s)
+{
+ // reset to the default state
+ Init();
+
+ // ToUserString() will quote the facename if it contains spaces, commas
+ // or semicolons: we must be able to understand that quoted text is
+ // a single token:
+ wxString toparse(s);
+
+ // parse a more or less free form string
+ wxStringTokenizer tokenizer(toparse, wxT(";, "), wxTOKEN_STRTOK);
+
+ wxString face;
+ unsigned long size;
+ bool weightfound = false, pointsizefound = false;
+#if wxUSE_FONTMAP
+ bool encodingfound = false;
+#endif
+ bool insideQuotes = false;
+
+ while ( tokenizer.HasMoreTokens() )
+ {
+ wxString token = tokenizer.GetNextToken();
+
+ // normalize it
+ token.Trim(true).Trim(false).MakeLower();
+ if (insideQuotes)
+ {
+ if (token.StartsWith("'") ||
+ token.EndsWith("'"))
+ {
+ insideQuotes = false;
+
+ // add this last token to the facename:
+ face += " " + token;
+
+ // normalize facename:
+ face = face.Trim(true).Trim(false);
+ face.Replace("'", "");
+
+ continue;
+ }
+ }
+ else
+ {
+ if (token.StartsWith("'"))
+ insideQuotes = true;
+ }
+
+ // look for the known tokens
+ if ( insideQuotes )
+ {
+ // only the facename may be quoted:
+ face += " " + token;
+ continue;
+ }
+ if ( token == wxT("underlined") || token == _("underlined") )
+ {
+ SetUnderlined(true);
+ }
+ else if ( token == wxT("light") || token == _("light") )
+ {
+ SetWeight(wxFONTWEIGHT_LIGHT);
+ weightfound = true;
+ }
+ else if ( token == wxT("bold") || token == _("bold") )
+ {
+ SetWeight(wxFONTWEIGHT_BOLD);
+ weightfound = true;
+ }
+ else if ( token == wxT("italic") || token == _("italic") )
+ {
+ SetStyle(wxFONTSTYLE_ITALIC);
+ }
+ else if ( token.ToULong(&size) )
+ {
+ SetPointSize(size);
+ pointsizefound = true;
+ }
+ else
+ {
+#if wxUSE_FONTMAP
+ // try to interpret this as an encoding
+ wxFontEncoding encoding = wxFontMapper::Get()->CharsetToEncoding(token, false);
+ if ( encoding != wxFONTENCODING_DEFAULT &&
+ encoding != wxFONTENCODING_SYSTEM ) // returned when the recognition failed
+ {
+ SetEncoding(encoding);
+ encodingfound = true;
+ }
+ else
+ {
+#endif // wxUSE_FONTMAP
+
+ // assume it is the face name
+ if ( !face.empty() )
+ {
+ face += wxT(' ');
+ }
+
+ face += token;
+
+ // skip the code which resets face below
+ continue;
+
+#if wxUSE_FONTMAP
+ }
+#endif // wxUSE_FONTMAP
+ }
+
+ // if we had had the facename, we shouldn't continue appending tokens
+ // to it (i.e. "foo bold bar" shouldn't result in the facename "foo
+ // bar")
+ if ( !face.empty() )
+ {
+ wxString familyStr;
+ if ( face.EndsWith(" family", &familyStr) )
+ {
+ // it's not a facename but rather a font family
+ wxFontFamily family;
+ if ( familyStr == "decorative" )
+ family = wxFONTFAMILY_DECORATIVE;
+ else if ( familyStr == "roman" )
+ family = wxFONTFAMILY_ROMAN;
+ else if ( familyStr == "script" )
+ family = wxFONTFAMILY_SCRIPT;
+ else if ( familyStr == "swiss" )
+ family = wxFONTFAMILY_SWISS;
+ else if ( familyStr == "modern" )
+ family = wxFONTFAMILY_MODERN;
+ else if ( familyStr == "teletype" )
+ family = wxFONTFAMILY_TELETYPE;
+ else
+ return false;
+
+ SetFamily(family);
+ }
+ // NB: the check on the facename is implemented in wxFontBase::SetFaceName
+ // and not in wxNativeFontInfo::SetFaceName thus we need to explicitly
+ // call here wxFontEnumerator::IsValidFacename
+ else if (
+#if wxUSE_FONTENUM
+ !wxFontEnumerator::IsValidFacename(face) ||
+#endif // wxUSE_FONTENUM
+ !SetFaceName(face) )
+ {
+ SetFaceName(wxNORMAL_FONT->GetFaceName());
+ }
+
+ face.clear();
+ }
+ }
+
+ // we might not have flushed it inside the loop
+ if ( !face.empty() )
+ {
+ // NB: the check on the facename is implemented in wxFontBase::SetFaceName
+ // and not in wxNativeFontInfo::SetFaceName thus we need to explicitly
+ // call here wxFontEnumerator::IsValidFacename
+ if (
+#if wxUSE_FONTENUM
+ !wxFontEnumerator::IsValidFacename(face) ||
+#endif // wxUSE_FONTENUM
+ !SetFaceName(face) )
+ {
+ SetFaceName(wxNORMAL_FONT->GetFaceName());
+ }
+ }
+
+ // set point size to default value if size was not given
+ if ( !pointsizefound )
+ SetPointSize(wxNORMAL_FONT->GetPointSize());
+
+ // set font weight to default value if weight was not given
+ if ( !weightfound )
+ SetWeight(wxFONTWEIGHT_NORMAL);
+
+#if wxUSE_FONTMAP
+ // set font encoding to default value if encoding was not given
+ if ( !encodingfound )
+ SetEncoding(wxFONTENCODING_SYSTEM);
+#endif // wxUSE_FONTMAP
+
+ return true;
+}
+
+#endif // generic or wxMSW or wxOS2
+
+
+// wxFont <-> wxString utilities, used by wxConfig
+wxString wxToString(const wxFontBase& font)
+{
+ return font.IsOk() ? font.GetNativeFontInfoDesc()
+ : wxString();
+}
+
+bool wxFromString(const wxString& str, wxFontBase *font)
+{
+ wxCHECK_MSG( font, false, wxT("NULL output parameter") );
+
+ if ( str.empty() )
+ {
+ *font = wxNullFont;
+ return true;
+ }
+
+ return font->SetNativeFontInfo(str);
+}
+
+