virtual wxString GetFaceName() const = 0;
virtual wxFontEncoding GetEncoding() const = 0;
virtual wxNativeFontInfo *GetNativeFontInfo() const;
+
wxString GetNativeFontInfoDesc() const;
+ wxString GetNativeFontInfoUserDesc() const;
// change the font characteristics
virtual void SetPointSize( int pointSize ) = 0;
virtual void SetUnderlined( bool underlined ) = 0;
virtual void SetEncoding(wxFontEncoding encoding) = 0;
virtual void SetNativeFontInfo(const wxNativeFontInfo& info);
+
void SetNativeFontInfo(const wxString& info);
+ void SetNativeFontInfoUserDesc(const wxString& info);
// translate the fonts into human-readable string (i.e. GetStyleString()
// will return "wxITALIC" for an italic font, ...)
#include "wx/font.h" // for wxFont and wxFontEncoding
#if defined(__WXMSW__)
-#include <windows.h>
-#include "wx/msw/winundef.h"
+ #include <windows.h>
+ #include "wx/msw/winundef.h"
#endif
// ----------------------------------------------------------------------------
// functions, the user code can only get the objects of this type from
// somewhere and pass it somewhere else (possibly save them somewhere using
// ToString() and restore them using FromString())
+//
+// NB: it is a POD currently for max efficiency but if it continues to grow
+// further it might make sense to make it a real class with virtual methods
struct WXDLLEXPORT wxNativeFontInfo
{
-#if defined(__WXGTK__)
+#if defined(__WXGTK__) || defined(__WXMOTIF__)
+ // the components of the XLFD
+ wxString fontElements[14];
+
+ // the full XLFD
wxString xFontName;
+
+ // init the elements from an XLFD, return TRUE if ok
+ bool FromXFontName(const wxString& xFontName);
+
+ // generate an XLFD using the fontElements
+ wxString GetXFontName() const;
#elif defined(__WXMSW__)
LOGFONT lf;
#else // other platforms
// This is a generic implementation that should work on all ports
// without specific support by the port.
//
+ #define wNO_NATIVE_FONTINFO
+
int pointSize;
int family;
- int style;
- int weight;
+ wxFontStyle style;
+ wxFontWeight weight;
bool underlined;
wxString faceName;
wxFontEncoding encoding;
#endif // platforms
+ // default ctor (default copy ctor is ok)
+ wxNativeFontInfo() { Init(); }
+
+ // reset to the default state
+ void Init();
+
+ // accessors and modifiers for the font elements: note that there is no
+ // GetFamily() because in general it is impossible to get the family for an
+ // arbitrary native font
+ int GetPointSize() const;
+ wxFontStyle GetStyle() const;
+ wxFontWeight GetWeight() const;
+ bool GetUnderlined() const;
+ wxString GetFaceName() const;
+ wxFontEncoding GetEncoding() const;
+
+ void SetPointSize(int pointsize);
+ void SetStyle(wxFontStyle style);
+ void SetWeight(wxFontWeight weight);
+ void SetUnderlined(bool underlined);
+ void SetFaceName(wxString facename);
+ void SetEncoding(wxFontEncoding encoding);
+
// it is important to be able to serialize wxNativeFontInfo objects to be
// able to store them (in config file, for example)
bool FromString(const wxString& s);
wxString ToString() const;
+
+ // we also want to present the native font descriptions to the user in some
+ // human-readable form (it is not platform independent neither, but can
+ // hopefully be understood by the user)
+ bool FromUserString(const wxString& s);
+ wxString ToUserString() const;
};
// ----------------------------------------------------------------------------
if ( fontInfo != font->GetNativeFontInfoDesc() )
wxLogError(wxT("wxNativeFontInfo ToString()/FromString() broken!"));
else
- wxLogError(wxT("wxNativeFontInfo works: %s"), fontInfo.c_str());
+ wxLogMessage(wxT("wxNativeFontInfo works: %s"), fontInfo.c_str());
+
delete font;
}
}
void MyFrame::DoResizeFont(int diff)
{
- wxFont fontOld = m_canvas->GetTextFont();
-
- DoChangeFont(
- wxFont(
- fontOld.GetPointSize() + diff,
- fontOld.GetFamily(),
- fontOld.GetStyle(),
- fontOld.GetWeight(),
- fontOld.GetUnderlined(),
- fontOld.GetFaceName(),
- fontOld.GetEncoding()
- )
- );
+ wxFont font = m_canvas->GetTextFont();
+
+ font.SetPointSize(font.GetPointSize() + diff);
+ DoChangeFont(font);
}
void MyFrame::DoChangeFont(const wxFont& font, const wxColour& col)
if ( m_font.Ok() )
{
- wxString fontDesc = m_font.GetNativeFontInfoDesc();
+ wxString fontDesc = m_font.GetNativeFontInfoUserDesc();
fontInfo.Printf(wxT("Native font info: %s"), fontDesc.c_str());
dc.DrawText(fontInfo, 5, 5 + dc.GetCharHeight());
}
#include "wx/gdicmn.h"
#include "wx/fontutil.h" // for wxNativeFontInfo
+#include "wx/fontmap.h"
#include "wx/tokenzr.h"
wxNativeFontInfo *wxFontBase::GetNativeFontInfo() const
{
-#if !defined(__WXGTK__) && !defined(__WXMSW__)
- wxNativeFontInfo *fontInfo = new wxNativeFontInfo;
+#ifdef wxNO_NATIVE_FONTINFO
+ wxNativeFontInfo *fontInfo = new wxNativeFontInfo();
- fontInfo->pointSize = GetPointSize();
- fontInfo->family = GetFamily();
- fontInfo->style = GetStyle();
- fontInfo->weight = GetWeight();
- fontInfo->underlined = GetUnderlined();
- fontInfo->faceName = GetFaceName();
- fontInfo->encoding = GetEncoding();
+ fontInfo->SetPointSize(GetPointSize());
+ fontInfo->SetFamily(GetFamily());
+ fontInfo->SetStyle((wxFontStyle)GetStyle());
+ fontInfo->SetWeight((wxFontWeight)GetWeight());
+ fontInfo->SetUnderlined(GetUnderlined());
+ fontInfo->SetFaceName(GetFaceName());
+ fontInfo->SetEncoding(GetEncoding());
return fontInfo;
#else
void wxFontBase::SetNativeFontInfo(const wxNativeFontInfo& info)
{
-#if !defined(__WXGTK__) && !defined(__WXMSW__)
+#ifdef wxNO_NATIVE_FONTINFO
SetPointSize(info.pointSize);
SetFamily(info.family);
SetStyle(info.style);
return fontDesc;
}
+wxString wxFontBase::GetNativeFontInfoUserDesc() const
+{
+ wxString fontDesc;
+ wxNativeFontInfo *fontInfo = GetNativeFontInfo();
+ if ( fontInfo )
+ {
+ fontDesc = fontInfo->ToUserString();
+ delete fontInfo;
+ }
+
+ return fontDesc;
+}
+
void wxFontBase::SetNativeFontInfo(const wxString& info)
{
wxNativeFontInfo fontInfo;
}
}
+void wxFontBase::SetNativeFontInfoUserDesc(const wxString& info)
+{
+ wxNativeFontInfo fontInfo;
+ if ( !info.empty() && fontInfo.FromUserString(info) )
+ {
+ SetNativeFontInfo(fontInfo);
+ }
+}
+
wxFont& wxFont::operator=(const wxFont& font)
{
if ( this != &font )
}
}
-#if !defined(__WXGTK__) && !defined(__WXMSW__)
-
// ----------------------------------------------------------------------------
// wxNativeFontInfo
// ----------------------------------------------------------------------------
+#ifdef wxNO_NATIVE_FONTINFO
+
// These are the generic forms of FromString()/ToString.
//
// convert to/from the string representation: format is
token = tokenizer.GetNextToken();
if ( !token.ToLong(&l) )
return FALSE;
- style = (int)l;
+ style = (wxFontStyle)l;
token = tokenizer.GetNextToken();
if ( !token.ToLong(&l) )
return FALSE;
- weight = (int)l;
+ weight = (wxFontWeight)l;
token = tokenizer.GetNextToken();
if ( !token.ToLong(&l) )
0, // version
pointSize,
family,
- style,
- weight,
+ (int)style,
+ (int)weight,
underlined,
faceName.GetData(),
(int)encoding);
return s;
}
+void wxNativeFontInfo::Init()
+{
+ pointSize = wxNORMAL_FONT->GetPointSize();
+ 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;
+}
+
+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_;
+}
+
+void wxNativeFontInfo::SetFaceName(wxString facename_)
+{
+ facename = facename_;
+}
+
+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__)
+
+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( _T("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( _T("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;
+ }
+
+ if ( !facename.empty() )
+ {
+ desc << facename << _T(' ');
+ }
+
+ if ( pointsize != wxNORMAL_FONT->GetPointSize() )
+ {
+ desc << pointsize;
+ }
+}
+
+bool wxNativeFontInfo::FromUserString(const wxString& s)
+{
+ // reset to the default state
+ Init();
+
+ // parse a more or less free form string
+ //
+ // TODO: we should handle at least the quoted facenames
+ wxStringTokenizer tokenizer(s, _T(";, "), wxTOKEN_STRTOK);
+
+ wxString face;
+ unsigned long size;
+ wxFontEncoding encoding;
+
+ while ( tokenizer.HasMoreTokens() )
+ {
+ wxString token = tokenizer.GetNextToken();
+
+ // normalize it
+ token.Trim(TRUE).Trim(FALSE).MakeLower();
+
+ // look for the known tokens
+ if ( token == _T("underlined") || token == _("underlined") )
+ {
+ SetUnderlined(TRUE);
+ }
+ else if ( token == _T("light") || token == _("light") )
+ {
+ SetWeight(wxFONTWEIGHT_LIGHT);
+ }
+ else if ( token == _T("bold") || token == _("bold") )
+ {
+ SetWeight(wxFONTWEIGHT_BOLD);
+ }
+ else if ( token == _T("italic") || token == _("italic") )
+ {
+ SetStyle(wxFONTSTYLE_ITALIC);
+ }
+ else if ( token.ToULong(&size) )
+ {
+ pointsize = (int)size;
+ }
+ else if ( (encoding = wxTheFontMapper->CharsetToEncoding(token, FALSE))
+ != wxFONTENCODING_DEFAULT )
+ {
+ SetEncoding(encoding);
+ }
+ else // assume it is the face name
+ {
+ if ( !face.empty() )
+ {
+ face += _T(' ');
+ }
+
+ face += token;
+
+ // skip the code which resets face below
+ continue;
+ }
+
+ // 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() )
+ {
+ SetFaceName(face);
+ face.clear();
+ }
+ }
+
+ // we might not have flushed it inside the loop
+ if ( !face.empty() )
+ {
+ SetFaceName(face);
+ }
+
+ return TRUE;
+}
+
+#endif // generic or wxMSW
+
}
}
-// ----------------------------------------------------------------------------
-// wxNativeFontInfo
-// ----------------------------------------------------------------------------
-
-bool wxNativeFontInfo::FromString(const wxString& s)
-{
- wxStringTokenizer tokenizer(s, _T(";"));
-
- wxString token = tokenizer.GetNextToken();
- //
- // Ignore the version for now
- //
-
- xFontName = tokenizer.GetNextToken();
- if(!xFontName)
- return FALSE;
-
- return TRUE;
-}
-
-wxString wxNativeFontInfo::ToString() const
-{
- wxString s;
-
- s.Printf(_T("%d;%s"),
- 0, // version
- xFontName.c_str());
-
- return s;
-}
-
// ----------------------------------------------------------------------------
// wxFont
// ----------------------------------------------------------------------------
}
}
-// ----------------------------------------------------------------------------
-// wxNativeFontInfo
-// ----------------------------------------------------------------------------
-
-bool wxNativeFontInfo::FromString(const wxString& s)
-{
- wxStringTokenizer tokenizer(s, _T(";"));
-
- wxString token = tokenizer.GetNextToken();
- //
- // Ignore the version for now
- //
-
- xFontName = tokenizer.GetNextToken();
- if(!xFontName)
- return FALSE;
-
- return TRUE;
-}
-
-wxString wxNativeFontInfo::ToString() const
-{
- wxString s;
-
- s.Printf(_T("%d;%s"),
- 0, // version
- xFontName.c_str());
-
- return s;
-}
-
// ----------------------------------------------------------------------------
// wxFont
// ----------------------------------------------------------------------------
return s;
}
+// ----------------------------------------------------------------------------
+// wxNativeFontInfo
+// ----------------------------------------------------------------------------
+
+void wxNativeFontInfo::Init()
+{
+ xFontName.clear();
+}
+
+bool wxNativeFontInfo::FromString(const wxString& s)
+{
+ wxStringTokenizer tokenizer(s, _T(";"));
+
+ // check the version
+ wxString token = tokenizer.GetNextToken();
+ if ( token != _T('0') )
+ return FALSE;
+
+ xFontName = tokenizer.GetNextToken();
+
+ // this should be the end
+ if ( tokenizer.HasMoreTokens() )
+ return FALSE;
+
+ return FromXFontName(xFontName);
+}
+
+wxString wxNativeFontInfo::ToString() const
+{
+ // 0 is the version
+ return wxString::Format(_T("%d;%s"), 0, GetXFontName().c_str());
+}
+
+bool wxNativeFontInfo::FromUserString(const wxString& s)
+{
+ return FromXFontName(s);
+}
+
+wxString wxNativeFontInfo::ToUserString() const
+{
+ return GetXFontName();
+}
+
+bool wxNativeFontInfo::FromXFontName(const wxString& xFontName)
+{
+ // TODO: we should be able to handle the font aliases here, but how?
+ wxStringTokenizer tokenizer(xFontName, _T("-"), wxTOKEN_STRTOK);
+
+ for ( size_t n = 0; n < WXSIZEOF(fontElements); n++ )
+ {
+ if ( !tokenizer.HasMoreTokens() )
+ {
+ // not enough elements in the XLFD - or maybe an alias
+ return FALSE;
+ }
+
+ fontElements[n] = tokenizer.GetNextToken();
+ }
+
+ // this should be all
+ return !tokenizer.HasMoreTokens();
+}
+
+wxString wxNativeFontInfo::GetXFontName() const
+{
+ if ( xFontName.empty() )
+ {
+ for ( size_t n = 0; n < WXSIZEOF(fontElements); n++ )
+ {
+ // replace the non specified elements with '*' except for the
+ // additional style which is usually just omitted
+ wxString elt = fontElements[n];
+ if ( elt.empty() && n != 5 )
+ {
+ elt = _T('*');
+ }
+
+ // const_cast
+ ((wxNativeFontInfo *)this)->xFontName << _T('-') << elt;
+ }
+ }
+
+ return xFontName;
+}
+
// ----------------------------------------------------------------------------
// common functions
// ----------------------------------------------------------------------------
return FALSE;
}
- info->encoding = encoding;
+ info->encoding = encoding;
return TRUE;
}