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
This commit is contained in:
Vadim Zeitlin
2012-09-15 23:17:12 +00:00
parent cba4e486a4
commit a349dc1085
5 changed files with 87 additions and 34 deletions

View File

@@ -71,6 +71,11 @@ class WXDLLIMPEXP_CORE wxNativeFontInfo
public: public:
#if wxUSE_PANGO #if wxUSE_PANGO
PangoFontDescription *description; 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) #elif defined(_WX_X_FONTLIKE)
// the members can't be accessed directly as we only parse the // the members can't be accessed directly as we only parse the
// xFontName on demand // xFontName on demand

View File

@@ -817,7 +817,7 @@ public:
@beginTable @beginTable
@hdr3col{platform, generic syntax, example} @hdr3col{platform, generic syntax, example}
@row3col{wxGTK2, <tt>[FACE-NAME] [bold] [oblique|italic] [POINTSIZE]</tt>, Monospace bold 10} @row3col{wxGTK2, <tt>[underlined] [strikethrough] [FACE-NAME] [bold] [oblique|italic] [POINTSIZE]</tt>, Monospace bold 10}
@row3col{wxMSW, <tt>[light|bold] [italic] [FACE-NAME] [POINTSIZE] [ENCODING]</tt>, Tahoma 10 WINDOWS-1252} @row3col{wxMSW, <tt>[light|bold] [italic] [FACE-NAME] [POINTSIZE] [ENCODING]</tt>, Tahoma 10 WINDOWS-1252}
@endTable @endTable
@@ -825,7 +825,9 @@ public:
For more detailed information about the allowed syntaxes you can look at the For more detailed information about the allowed syntaxes you can look at the
documentation of the native API used for font-rendering 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 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 attributes of the wxFont object under all platforms; e.g. on wxMSW the font family

View File

@@ -92,9 +92,8 @@ protected:
void InitFromNative(); void InitFromNative();
private: private:
bool m_underlined; // The native font info: basically a PangoFontDescription, plus
bool m_strikethrough; // 'underlined' and 'strikethrough' attributes not supported by Pango.
// The native font info: basically a PangoFontDescription
wxNativeFontInfo m_nativeFontInfo; wxNativeFontInfo m_nativeFontInfo;
friend class wxFont; friend class wxFont;
@@ -118,9 +117,6 @@ void wxFontRefData::Init(int pointSize,
if (family == wxFONTFAMILY_DEFAULT) if (family == wxFONTFAMILY_DEFAULT)
family = wxFONTFAMILY_SWISS; family = wxFONTFAMILY_SWISS;
m_underlined = underlined;
m_strikethrough = strikethrough;
// Create native font info // Create native font info
m_nativeFontInfo.description = pango_font_description_new(); m_nativeFontInfo.description = pango_font_description_new();
@@ -140,6 +136,8 @@ void wxFontRefData::Init(int pointSize,
? wxDEFAULT_FONT_SIZE ? wxDEFAULT_FONT_SIZE
: pointSize ); : pointSize );
SetWeight( weight == wxDEFAULT ? wxFONTWEIGHT_NORMAL : weight ); SetWeight( weight == wxDEFAULT ? wxFONTWEIGHT_NORMAL : weight );
SetUnderlined( underlined );
SetStrikethrough( strikethrough );
} }
void wxFontRefData::InitFromNative() void wxFontRefData::InitFromNative()
@@ -151,18 +149,11 @@ void wxFontRefData::InitFromNative()
int pango_size = pango_font_description_get_size( desc ); int pango_size = pango_font_description_get_size( desc );
if (pango_size == 0) if (pango_size == 0)
m_nativeFontInfo.SetPointSize(wxDEFAULT_FONT_SIZE); m_nativeFontInfo.SetPointSize(wxDEFAULT_FONT_SIZE);
// Pango description are never underlined
m_underlined = false;
m_strikethrough = false;
} }
wxFontRefData::wxFontRefData( const wxFontRefData& data ) wxFontRefData::wxFontRefData( const wxFontRefData& data )
: wxGDIRefData() : wxGDIRefData()
{ {
m_underlined = data.m_underlined;
m_strikethrough = data.m_strikethrough;
// Forces a copy of the internal data. wxNativeFontInfo should probably // Forces a copy of the internal data. wxNativeFontInfo should probably
// have a copy ctor and assignment operator to fix this properly but that // have a copy ctor and assignment operator to fix this properly but that
// would break binary compatibility... // would break binary compatibility...
@@ -243,17 +234,12 @@ void wxFontRefData::SetWeight(wxFontWeight weight)
void wxFontRefData::SetUnderlined(bool underlined) void wxFontRefData::SetUnderlined(bool underlined)
{ {
m_underlined = underlined; m_nativeFontInfo.SetUnderlined(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
} }
void wxFontRefData::SetStrikethrough(bool strikethrough) void wxFontRefData::SetStrikethrough(bool strikethrough)
{ {
m_strikethrough = strikethrough; m_nativeFontInfo.SetStrikethrough(strikethrough);
} }
bool wxFontRefData::SetFaceName(const wxString& facename) bool wxFontRefData::SetFaceName(const wxString& facename)
@@ -287,6 +273,9 @@ wxFont::wxFont(const wxNativeFontInfo& info)
info.GetUnderlined(), info.GetUnderlined(),
info.GetFaceName(), info.GetFaceName(),
info.GetEncoding() ); info.GetEncoding() );
if ( info.GetStrikethrough() )
SetStrikethrough(true);
} }
wxFont::wxFont(int pointSize, wxFont::wxFont(int pointSize,
@@ -379,14 +368,14 @@ bool wxFont::GetUnderlined() const
{ {
wxCHECK_MSG( IsOk(), false, wxT("invalid font") ); wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
return M_FONTDATA->m_underlined; return M_FONTDATA->m_nativeFontInfo.GetUnderlined();
} }
bool wxFont::GetStrikethrough() const bool wxFont::GetStrikethrough() const
{ {
wxCHECK_MSG( IsOk(), false, wxT("invalid font") ); wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
return M_FONTDATA->m_strikethrough; return M_FONTDATA->m_nativeFontInfo.GetStrikethrough();
} }
wxFontEncoding wxFont::GetEncoding() const wxFontEncoding wxFont::GetEncoding() const

View File

@@ -64,14 +64,24 @@
void wxNativeFontInfo::Init() void wxNativeFontInfo::Init()
{ {
description = NULL; description = NULL;
m_underlined = false;
m_strikethrough = false;
} }
void wxNativeFontInfo::Init(const wxNativeFontInfo& info) void wxNativeFontInfo::Init(const wxNativeFontInfo& info)
{ {
if (info.description) if (info.description)
{
description = pango_font_description_copy(info.description); description = pango_font_description_copy(info.description);
m_underlined = info.GetUnderlined();
m_strikethrough = info.GetStrikethrough();
}
else else
{
description = NULL; description = NULL;
m_underlined = false;
m_strikethrough = false;
}
} }
void wxNativeFontInfo::Free() void wxNativeFontInfo::Free()
@@ -130,12 +140,12 @@ wxFontWeight wxNativeFontInfo::GetWeight() const
bool wxNativeFontInfo::GetUnderlined() const bool wxNativeFontInfo::GetUnderlined() const
{ {
return false; return m_underlined;
} }
bool wxNativeFontInfo::GetStrikethrough() const bool wxNativeFontInfo::GetStrikethrough() const
{ {
return false; return m_strikethrough;
} }
wxString wxNativeFontInfo::GetFaceName() const 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 // Pango doesn't have the underlined attribute so we store it separately
// the underline attribute! // (and handle it specially in wxWindowDCImpl::DoDrawText()).
wxFAIL_MSG( "not implemented" ); 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) bool wxNativeFontInfo::SetFaceName(const wxString& facename)
@@ -365,6 +377,14 @@ void wxNativeFontInfo::SetEncoding(wxFontEncoding WXUNUSED(encoding))
bool wxNativeFontInfo::FromString(const wxString& s) 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) if (description)
pango_font_description_free( 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 // 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 // pango > 1.13. Note that the segfault could happen also for pointsize
// smaller than this limit !! // smaller than this limit !!
wxString str(s);
const size_t pos = str.find_last_of(wxS(" ")); const size_t pos = str.find_last_of(wxS(" "));
double size; double size;
if ( pos != wxString::npos && wxString(str, pos + 1).ToDouble(&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 wxString wxNativeFontInfo::ToString() const
{ {
wxGtkString str(pango_font_description_to_string( description )); wxGtkString str(pango_font_description_to_string( description ));
wxString desc = wxPANGO_CONV_BACK(str);
return 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) bool wxNativeFontInfo::FromUserString(const wxString& s)

View File

@@ -26,6 +26,8 @@
#include "wx/font.h" #include "wx/font.h"
#include "asserthelper.h"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// test class // test class
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -204,6 +206,12 @@ void FontTestCase::GetSet()
CPPUNIT_ASSERT( test.IsOk() ); CPPUNIT_ASSERT( test.IsOk() );
CPPUNIT_ASSERT_EQUAL( true, test.GetUnderlined() ); 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() // test Get/SetWeight()
@@ -245,6 +253,26 @@ void FontTestCase::NativeFontInfo()
#if !defined(__WXGTK__) && !defined(__WXX11__) #if !defined(__WXGTK__) && !defined(__WXX11__)
CPPUNIT_ASSERT( !font.SetNativeFontInfo("bloordyblop") ); CPPUNIT_ASSERT( !font.SetNativeFontInfo("bloordyblop") );
#endif #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() void FontTestCase::NativeFontInfoUserDesc()