/////////////////////////////////////////////////////////////////////////////
-// Name: common/fontcmn.cpp
+// Name: src/common/fontcmn.cpp
// Purpose: implementation of wxFontBase methods
// Author: Vadim Zeitlin
// Modified by:
// headers
// ----------------------------------------------------------------------------
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
-#pragma implementation "fontbase.h"
-#endif
-
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
-#pragma hdrstop
+ #pragma hdrstop
#endif
+#include "wx/font.h"
+
#ifndef WX_PRECOMP
- #include "wx/font.h"
+ #include "wx/dc.h"
#include "wx/intl.h"
#include "wx/dcscreen.h"
+ #include "wx/log.h"
+ #include "wx/gdicmn.h"
#endif // WX_PRECOMP
-#include "wx/gdicmn.h"
-
-#if defined(__WXMSW__) && !defined(__WXPALMOS__)
- #include "wx/msw/private.h" // includes windows.h for LOGFONT
- #include "wx/msw/winundef.h"
+#if defined(__WXMSW__)
+ #include "wx/msw/private.h" // includes windows.h for LOGFONT
+ #include "wx/msw/winundef.h"
#endif
#include "wx/fontutil.h" // for wxNativeFontInfo
#include "wx/fontmap.h"
+#include "wx/fontenum.h"
#include "wx/tokenzr.h"
static void AdjustFontSize(wxFont& font, wxDC& dc, const wxSize& pixelSize)
{
- int currentSize = font.GetPointSize();
+ int currentSize = 0;
int largestGood = 0;
int smallestBad = 0;
bool initialGoodFound = false;
bool initialBadFound = false;
+ // NB: this assignment was separated from the variable definition
+ // in order to fix a gcc v3.3.3 compiler crash
+ currentSize = font.GetPointSize();
while (currentSize > 0)
{
dc.SetFont(font);
if ( fontInfo )
{
fontDesc = fontInfo->ToString();
+ wxASSERT_MSG(!fontDesc.empty(), wxT("This should be a non-empty string!"));
+ }
+ else
+ {
+ wxFAIL_MSG(wxT("Derived class should have created the wxNativeFontInfo!"));
}
return fontDesc;
if ( fontInfo )
{
fontDesc = fontInfo->ToUserString();
+ wxASSERT_MSG(!fontDesc.empty(), wxT("This should be a non-empty string!"));
+ }
+ else
+ {
+ wxFAIL_MSG(wxT("Derived class should have created the wxNativeFontInfo!"));
}
return fontDesc;
}
-void wxFontBase::SetNativeFontInfo(const wxString& info)
+bool wxFontBase::SetNativeFontInfo(const wxString& info)
{
wxNativeFontInfo fontInfo;
if ( !info.empty() && fontInfo.FromString(info) )
{
SetNativeFontInfo(fontInfo);
+ return true;
}
+
+ return false;
}
-void wxFontBase::SetNativeFontInfoUserDesc(const wxString& info)
+bool wxFontBase::SetNativeFontInfoUserDesc(const wxString& info)
{
wxNativeFontInfo fontInfo;
if ( !info.empty() && fontInfo.FromUserString(info) )
{
SetNativeFontInfo(fontInfo);
+ return true;
}
-}
-
-wxFont& wxFont::operator=(const wxFont& font)
-{
- if ( this != &font )
- Ref(font);
- return (wxFont &)*this;
+ return false;
}
bool wxFontBase::operator==(const wxFont& font) const
{
// either it is the same font, i.e. they share the same common data or they
// have different ref datas but still describe the same font
- return GetFontData() == font.GetFontData() ||
+ return IsSameAs(font) ||
(
Ok() == font.Ok() &&
GetPointSize() == font.GetPointSize() &&
+ // in wxGTK1 GetPixelSize() calls GetInternalFont() which uses
+ // operator==() resulting in infinite recursion so we can't use it
+ // in that port
+#if !defined(__WXGTK__) || defined(__WXGTK20__)
+ GetPixelSize() == font.GetPixelSize() &&
+#endif
GetFamily() == font.GetFamily() &&
GetStyle() == font.GetStyle() &&
GetWeight() == font.GetWeight() &&
GetUnderlined() == font.GetUnderlined() &&
- GetFaceName() == font.GetFaceName() &&
+ GetFaceName().IsSameAs(font.GetFaceName(), false) &&
GetEncoding() == font.GetEncoding()
);
}
-bool wxFontBase::operator!=(const wxFont& font) const
-{
- return !(*this == font);
-}
-
wxString wxFontBase::GetFamilyString() const
{
wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
}
}
+bool wxFontBase::SetFaceName(const wxString& facename)
+{
+#if wxUSE_FONTENUM
+ if (!wxFontEnumerator::IsValidFacename(facename))
+ {
+ UnRef(); // make Ok() return false
+ return false;
+ }
+#else // !wxUSE_FONTENUM
+ wxUnusedVar(facename);
+#endif // wxUSE_FONTENUM/!wxUSE_FONTENUM
+
+ return true;
+}
+
+
// ----------------------------------------------------------------------------
// 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.
underlined = underlined_;
}
-void wxNativeFontInfo::SetFaceName(wxString facename_)
+bool wxNativeFontInfo::SetFaceName(const wxString& facename_)
{
faceName = facename_;
+ return true;
}
void wxNativeFontInfo::SetFamily(wxFontFamily family_)
// but what else can we do?
if ( GetUnderlined() )
{
- desc << _("underlined ");
+ desc << _("underlined");
}
switch ( GetWeight() )
break;
case wxFONTWEIGHT_LIGHT:
- desc << _("light ");
+ desc << _(" light");
break;
case wxFONTWEIGHT_BOLD:
- desc << _("bold ");
+ desc << _(" bold");
break;
}
// we don't distinguish between the two for now anyhow...
case wxFONTSTYLE_ITALIC:
case wxFONTSTYLE_SLANT:
- desc << _("italic");
+ desc << _(" italic");
break;
}
wxFontEncoding enc = GetEncoding();
if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM )
{
- desc << _T(' ') << wxFontMapper::Get()->GetEncodingName(enc);
+ desc << _T(' ') << wxFontMapper::GetEncodingName(enc);
}
#endif // wxUSE_FONTMAP
- return desc;
+ return desc.Strip(wxString::both).MakeLower();
}
bool wxNativeFontInfo::FromUserString(const wxString& s)
wxString face;
unsigned long size;
-
+ bool weightfound = false, pointsizefound = false;
#if wxUSE_FONTMAP
- wxFontEncoding encoding;
-#endif // wxUSE_FONTMAP
+ bool encodingfound = false;
+#endif
while ( tokenizer.HasMoreTokens() )
{
else if ( token == _T("light") || token == _("light") )
{
SetWeight(wxFONTWEIGHT_LIGHT);
+ weightfound = true;
}
else if ( token == _T("bold") || token == _("bold") )
{
SetWeight(wxFONTWEIGHT_BOLD);
+ weightfound = true;
}
else if ( token == _T("italic") || token == _("italic") )
{
else if ( token.ToULong(&size) )
{
SetPointSize(size);
+ pointsizefound = true;
}
+ else
+ {
#if wxUSE_FONTMAP
- else if ( (encoding = wxFontMapper::Get()->CharsetToEncoding(token, false))
- != wxFONTENCODING_DEFAULT )
+ // 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;
}
-#endif // wxUSE_FONTMAP
- else // assume it is the face name
+ else
{
+#endif // wxUSE_FONTMAP
+
+ // assume it is the face name
if ( !face.empty() )
{
face += _T(' ');
// 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
// bar")
if ( !face.empty() )
{
- SetFaceName(face);
+ // NB: the check on the facename is implemented in wxFontBase::SetFaceName
+ // and not in wxNativeFontInfo::SetFaceName thus we need to explicitely
+ // call here wxFontEnumerator::IsValidFacename
+ 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() )
{
- SetFaceName(face);
+ // NB: the check on the facename is implemented in wxFontBase::SetFaceName
+ // and not in wxNativeFontInfo::SetFaceName thus we need to explicitely
+ // 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, _T("NULL output parameter") );
+
+ if ( str.empty() )
+ {
+ *font = wxNullFont;
+ return true;
+ }
+
+ return font->SetNativeFontInfo(str);
+}
+
+