From: Vadim Zeitlin Date: Fri, 21 Dec 2001 21:39:45 +0000 (+0000) Subject: add more methods to wxNativeFontInfo: To/FromUserString and all the X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/ab5fe83396c13f9fbf01630c52adf4df7607cbfe?ds=inline add more methods to wxNativeFontInfo: To/FromUserString and all the accessor methods and implemented some of them git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13156 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/font.h b/include/wx/font.h index 262bce29f5..f324d115c9 100644 --- a/include/wx/font.h +++ b/include/wx/font.h @@ -114,7 +114,9 @@ public: 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; @@ -125,7 +127,9 @@ public: 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, ...) diff --git a/include/wx/fontutil.h b/include/wx/fontutil.h index 7bb3859bcb..c8df0749ca 100644 --- a/include/wx/fontutil.h +++ b/include/wx/fontutil.h @@ -27,8 +27,8 @@ #include "wx/font.h" // for wxFont and wxFontEncoding #if defined(__WXMSW__) -#include -#include "wx/msw/winundef.h" + #include + #include "wx/msw/winundef.h" #endif // ---------------------------------------------------------------------------- @@ -40,10 +40,23 @@ // 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 @@ -51,19 +64,50 @@ struct WXDLLEXPORT wxNativeFontInfo // 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; }; // ---------------------------------------------------------------------------- diff --git a/samples/font/font.cpp b/samples/font/font.cpp index c83ba331b4..8b526f403b 100644 --- a/samples/font/font.cpp +++ b/samples/font/font.cpp @@ -426,26 +426,18 @@ void MyFrame::OnCheckNativeToFromString(wxCommandEvent& WXUNUSED(event)) 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) @@ -647,7 +639,7 @@ void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) 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()); } diff --git a/src/common/fontcmn.cpp b/src/common/fontcmn.cpp index 1cc5f55b45..ad280cef8e 100644 --- a/src/common/fontcmn.cpp +++ b/src/common/fontcmn.cpp @@ -34,6 +34,7 @@ #include "wx/gdicmn.h" #include "wx/fontutil.h" // for wxNativeFontInfo +#include "wx/fontmap.h" #include "wx/tokenzr.h" @@ -77,16 +78,16 @@ wxFont *wxFontBase::New(const wxString& strNativeFontDesc) 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 @@ -96,7 +97,7 @@ wxNativeFontInfo *wxFontBase::GetNativeFontInfo() const void wxFontBase::SetNativeFontInfo(const wxNativeFontInfo& info) { -#if !defined(__WXGTK__) && !defined(__WXMSW__) +#ifdef wxNO_NATIVE_FONTINFO SetPointSize(info.pointSize); SetFamily(info.family); SetStyle(info.style); @@ -122,6 +123,19 @@ wxString wxFontBase::GetNativeFontInfoDesc() const 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; @@ -131,6 +145,15 @@ void wxFontBase::SetNativeFontInfo(const wxString& info) } } +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 ) @@ -203,12 +226,12 @@ wxString wxFontBase::GetWeightString() const } } -#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 @@ -238,12 +261,12 @@ bool wxNativeFontInfo::FromString(const wxString& s) 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) ) @@ -270,8 +293,8 @@ wxString wxNativeFontInfo::ToString() const 0, // version pointSize, family, - style, - weight, + (int)style, + (int)weight, underlined, faceName.GetData(), (int)encoding); @@ -279,5 +302,220 @@ wxString wxNativeFontInfo::ToString() const 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 + diff --git a/src/gtk/font.cpp b/src/gtk/font.cpp index 74864d1882..15909254a4 100644 --- a/src/gtk/font.cpp +++ b/src/gtk/font.cpp @@ -146,37 +146,6 @@ wxFontRefData::~wxFontRefData() } } -// ---------------------------------------------------------------------------- -// 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 // ---------------------------------------------------------------------------- diff --git a/src/gtk1/font.cpp b/src/gtk1/font.cpp index 74864d1882..15909254a4 100644 --- a/src/gtk1/font.cpp +++ b/src/gtk1/font.cpp @@ -146,37 +146,6 @@ wxFontRefData::~wxFontRefData() } } -// ---------------------------------------------------------------------------- -// 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 // ---------------------------------------------------------------------------- diff --git a/src/unix/fontutil.cpp b/src/unix/fontutil.cpp index f190de22b6..841e90bf64 100644 --- a/src/unix/fontutil.cpp +++ b/src/unix/fontutil.cpp @@ -153,6 +153,91 @@ wxString wxNativeEncodingInfo::ToString() const 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 // ---------------------------------------------------------------------------- @@ -228,7 +313,7 @@ bool wxGetNativeFontEncoding(wxFontEncoding encoding, return FALSE; } - info->encoding = encoding; + info->encoding = encoding; return TRUE; }