From a349dc1085c34b54deaaab3022b01dfd8aeb3cbd Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 15 Sep 2012 23:17:12 +0000 Subject: [PATCH] Handle underlined and strikethrough attributes in wxGTK native font info. These attributes were not handled by wxFont::GetNativeFontInfoDesc() as it only serialized the Pango font description which doesn't support them. Fix this by handling these attributes explicitly and prepending them to the Pango font string if necessary. Closes #14559. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72488 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/fontutil.h | 5 ++++ interface/wx/font.h | 6 +++-- src/gtk/font.cpp | 33 +++++++++----------------- src/unix/fontutil.cpp | 51 ++++++++++++++++++++++++++++++++--------- tests/font/fonttest.cpp | 28 ++++++++++++++++++++++ 5 files changed, 88 insertions(+), 35 deletions(-) diff --git a/include/wx/fontutil.h b/include/wx/fontutil.h index 0291b92176..106205f24c 100644 --- a/include/wx/fontutil.h +++ b/include/wx/fontutil.h @@ -71,6 +71,11 @@ class WXDLLIMPEXP_CORE wxNativeFontInfo public: #if wxUSE_PANGO PangoFontDescription *description; + + // Pango font description doesn't have these attributes, so we store them + // separately and handle them ourselves in {To,From}String() methods. + bool m_underlined; + bool m_strikethrough; #elif defined(_WX_X_FONTLIKE) // the members can't be accessed directly as we only parse the // xFontName on demand diff --git a/interface/wx/font.h b/interface/wx/font.h index 38238a2216..b53a2e2c82 100644 --- a/interface/wx/font.h +++ b/interface/wx/font.h @@ -817,7 +817,7 @@ public: @beginTable @hdr3col{platform, generic syntax, example} - @row3col{wxGTK2, [FACE-NAME] [bold] [oblique|italic] [POINTSIZE], Monospace bold 10} + @row3col{wxGTK2, [underlined] [strikethrough] [FACE-NAME] [bold] [oblique|italic] [POINTSIZE], Monospace bold 10} @row3col{wxMSW, [light|bold] [italic] [FACE-NAME] [POINTSIZE] [ENCODING], Tahoma 10 WINDOWS-1252} @endTable @@ -825,7 +825,9 @@ public: For more detailed information about the allowed syntaxes you can look at the documentation of the native API used for font-rendering - (e.g. @c pango_font_description_from_string on GTK). + (e.g. @c pango_font_description_from_string under GTK, although notice + that it doesn't support the "underlined" and "strikethrough" attributes + and so those are handled by wxWidgets itself). Note that unlike SetNativeFontInfo(), this function doesn't always restore all attributes of the wxFont object under all platforms; e.g. on wxMSW the font family diff --git a/src/gtk/font.cpp b/src/gtk/font.cpp index 5ff6a3a10f..f2e48c3ca8 100644 --- a/src/gtk/font.cpp +++ b/src/gtk/font.cpp @@ -92,9 +92,8 @@ protected: void InitFromNative(); private: - bool m_underlined; - bool m_strikethrough; - // The native font info: basically a PangoFontDescription + // The native font info: basically a PangoFontDescription, plus + // 'underlined' and 'strikethrough' attributes not supported by Pango. wxNativeFontInfo m_nativeFontInfo; friend class wxFont; @@ -118,9 +117,6 @@ void wxFontRefData::Init(int pointSize, if (family == wxFONTFAMILY_DEFAULT) family = wxFONTFAMILY_SWISS; - m_underlined = underlined; - m_strikethrough = strikethrough; - // Create native font info m_nativeFontInfo.description = pango_font_description_new(); @@ -140,6 +136,8 @@ void wxFontRefData::Init(int pointSize, ? wxDEFAULT_FONT_SIZE : pointSize ); SetWeight( weight == wxDEFAULT ? wxFONTWEIGHT_NORMAL : weight ); + SetUnderlined( underlined ); + SetStrikethrough( strikethrough ); } void wxFontRefData::InitFromNative() @@ -151,18 +149,11 @@ void wxFontRefData::InitFromNative() int pango_size = pango_font_description_get_size( desc ); if (pango_size == 0) m_nativeFontInfo.SetPointSize(wxDEFAULT_FONT_SIZE); - - // Pango description are never underlined - m_underlined = false; - m_strikethrough = false; } wxFontRefData::wxFontRefData( const wxFontRefData& data ) : wxGDIRefData() { - m_underlined = data.m_underlined; - m_strikethrough = data.m_strikethrough; - // Forces a copy of the internal data. wxNativeFontInfo should probably // have a copy ctor and assignment operator to fix this properly but that // would break binary compatibility... @@ -243,17 +234,12 @@ void wxFontRefData::SetWeight(wxFontWeight weight) void wxFontRefData::SetUnderlined(bool underlined) { - m_underlined = underlined; - - // the Pango font descriptor does not have an underlined attribute - // (and wxNativeFontInfo::SetUnderlined asserts); rather it's - // wxWindowDCImpl::DoDrawText that handles underlined fonts, so we - // here we just need to save the underlined attribute + m_nativeFontInfo.SetUnderlined(underlined); } void wxFontRefData::SetStrikethrough(bool strikethrough) { - m_strikethrough = strikethrough; + m_nativeFontInfo.SetStrikethrough(strikethrough); } bool wxFontRefData::SetFaceName(const wxString& facename) @@ -287,6 +273,9 @@ wxFont::wxFont(const wxNativeFontInfo& info) info.GetUnderlined(), info.GetFaceName(), info.GetEncoding() ); + + if ( info.GetStrikethrough() ) + SetStrikethrough(true); } wxFont::wxFont(int pointSize, @@ -379,14 +368,14 @@ bool wxFont::GetUnderlined() const { wxCHECK_MSG( IsOk(), false, wxT("invalid font") ); - return M_FONTDATA->m_underlined; + return M_FONTDATA->m_nativeFontInfo.GetUnderlined(); } bool wxFont::GetStrikethrough() const { wxCHECK_MSG( IsOk(), false, wxT("invalid font") ); - return M_FONTDATA->m_strikethrough; + return M_FONTDATA->m_nativeFontInfo.GetStrikethrough(); } wxFontEncoding wxFont::GetEncoding() const diff --git a/src/unix/fontutil.cpp b/src/unix/fontutil.cpp index 8751cd3c39..23fc29e761 100644 --- a/src/unix/fontutil.cpp +++ b/src/unix/fontutil.cpp @@ -64,14 +64,24 @@ void wxNativeFontInfo::Init() { description = NULL; + m_underlined = false; + m_strikethrough = false; } void wxNativeFontInfo::Init(const wxNativeFontInfo& info) { if (info.description) + { description = pango_font_description_copy(info.description); + m_underlined = info.GetUnderlined(); + m_strikethrough = info.GetStrikethrough(); + } else + { description = NULL; + m_underlined = false; + m_strikethrough = false; + } } void wxNativeFontInfo::Free() @@ -130,12 +140,12 @@ wxFontWeight wxNativeFontInfo::GetWeight() const bool wxNativeFontInfo::GetUnderlined() const { - return false; + return m_underlined; } bool wxNativeFontInfo::GetStrikethrough() const { - return false; + return m_strikethrough; } wxString wxNativeFontInfo::GetFaceName() const @@ -262,16 +272,18 @@ void wxNativeFontInfo::SetWeight(wxFontWeight weight) } } -void wxNativeFontInfo::SetUnderlined(bool WXUNUSED(underlined)) +void wxNativeFontInfo::SetUnderlined(bool underlined) { - // wxWindowDCImpl::DoDrawText will take care of rendering font with - // the underline attribute! - wxFAIL_MSG( "not implemented" ); + // Pango doesn't have the underlined attribute so we store it separately + // (and handle it specially in wxWindowDCImpl::DoDrawText()). + m_underlined = underlined; } -void wxNativeFontInfo::SetStrikethrough(bool WXUNUSED(strikethrough)) +void wxNativeFontInfo::SetStrikethrough(bool strikethrough) { - wxFAIL_MSG( "not implemented" ); + // As with the underlined attribute above, we handle this one separately as + // Pango doesn't support it as part of the font description. + m_strikethrough = strikethrough; } bool wxNativeFontInfo::SetFaceName(const wxString& facename) @@ -365,6 +377,14 @@ void wxNativeFontInfo::SetEncoding(wxFontEncoding WXUNUSED(encoding)) bool wxNativeFontInfo::FromString(const wxString& s) { + wxString str(s); + + // Pango font description doesn't have 'underlined' or 'strikethrough' + // attributes, so we handle them specially by extracting them from the + // string before passing it to Pango. + m_underlined = str.StartsWith(wxS("underlined "), &str); + m_strikethrough = str.StartsWith(wxS("strikethrough "), &str); + if (description) pango_font_description_free( description ); @@ -375,7 +395,6 @@ bool wxNativeFontInfo::FromString(const wxString& s) // we do the check on the size here using same (arbitrary) limits used by // pango > 1.13. Note that the segfault could happen also for pointsize // smaller than this limit !! - wxString str(s); const size_t pos = str.find_last_of(wxS(" ")); double size; if ( pos != wxString::npos && wxString(str, pos + 1).ToDouble(&size) ) @@ -407,8 +426,18 @@ bool wxNativeFontInfo::FromString(const wxString& s) wxString wxNativeFontInfo::ToString() const { wxGtkString str(pango_font_description_to_string( description )); - - return wxPANGO_CONV_BACK(str); + wxString desc = wxPANGO_CONV_BACK(str); + + // Augment the string with the attributes not handled by Pango. + // + // Notice that we must add them in the same order they are extracted in + // FromString() above. + if (m_strikethrough) + desc.insert(0, wxS("strikethrough ")); + if (m_underlined) + desc.insert(0, wxS("underlined ")); + + return desc; } bool wxNativeFontInfo::FromUserString(const wxString& s) diff --git a/tests/font/fonttest.cpp b/tests/font/fonttest.cpp index e597a5b1b9..de529f62b2 100644 --- a/tests/font/fonttest.cpp +++ b/tests/font/fonttest.cpp @@ -26,6 +26,8 @@ #include "wx/font.h" +#include "asserthelper.h" + // ---------------------------------------------------------------------------- // test class // ---------------------------------------------------------------------------- @@ -204,6 +206,12 @@ void FontTestCase::GetSet() CPPUNIT_ASSERT( test.IsOk() ); CPPUNIT_ASSERT_EQUAL( true, test.GetUnderlined() ); + // test Get/SetStrikethrough() + + test.SetStrikethrough(true); + CPPUNIT_ASSERT( test.IsOk() ); + CPPUNIT_ASSERT_EQUAL( true, test.GetStrikethrough() ); + // test Get/SetWeight() @@ -245,6 +253,26 @@ void FontTestCase::NativeFontInfo() #if !defined(__WXGTK__) && !defined(__WXX11__) CPPUNIT_ASSERT( !font.SetNativeFontInfo("bloordyblop") ); #endif + + // Pango font description doesn't have 'underlined' and 'strikethrough' + // attributes, so wxNativeFontInfo implements these itself. Test if these + // are properly preserved by wxNativeFontInfo or its string description. + font.SetUnderlined(true); + font.SetStrikethrough(true); + CPPUNIT_ASSERT_EQUAL(font, wxFont(font)); + CPPUNIT_ASSERT_EQUAL(font, wxFont(*font.GetNativeFontInfo())); + CPPUNIT_ASSERT_EQUAL(font, wxFont(font.GetNativeFontInfoDesc())); + font.SetUnderlined(false); + CPPUNIT_ASSERT_EQUAL(font, wxFont(font)); + CPPUNIT_ASSERT_EQUAL(font, wxFont(*font.GetNativeFontInfo())); + CPPUNIT_ASSERT_EQUAL(font, wxFont(font.GetNativeFontInfoDesc())); + font.SetUnderlined(true); + font.SetStrikethrough(false); + CPPUNIT_ASSERT_EQUAL(font, wxFont(font)); + CPPUNIT_ASSERT_EQUAL(font, wxFont(*font.GetNativeFontInfo())); + CPPUNIT_ASSERT_EQUAL(font, wxFont(font.GetNativeFontInfoDesc())); + // note: the GetNativeFontInfoUserDesc() doesn't preserve all attributes + // according to docs, so it is not tested. } void FontTestCase::NativeFontInfoUserDesc() -- 2.45.2