move Pango underline workaround into wxFont::GTKSetPangoAttrs
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70476 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -104,16 +104,12 @@ public:
|
|||||||
|
|
||||||
wxDECLARE_COMMON_FONT_METHODS();
|
wxDECLARE_COMMON_FONT_METHODS();
|
||||||
|
|
||||||
// Set Pango attributes for the span 0..len (or
|
// Set Pango attributes in the specified layout. Currently only
|
||||||
// without any bounds if len == 0) in the specified layout. Currently only
|
|
||||||
// underlined and strike-through attributes are handled by this function.
|
// underlined and strike-through attributes are handled by this function.
|
||||||
//
|
//
|
||||||
// Special "addDummyAttrs" parameter is used to work around a bug in old Pango
|
|
||||||
// versions in wxWindowDCImpl::DoDrawText(), see comment there.
|
|
||||||
//
|
|
||||||
// If neither of them is specified, returns false, otherwise sets up the
|
// If neither of them is specified, returns false, otherwise sets up the
|
||||||
// attributes and returns true.
|
// attributes and returns true.
|
||||||
bool GTKSetPangoAttrs(PangoLayout* layout, size_t len = 0, bool addDummyAttrs = false) const;
|
bool GTKSetPangoAttrs(PangoLayout* layout) const;
|
||||||
|
|
||||||
// implementation from now on
|
// implementation from now on
|
||||||
void Unshare();
|
void Unshare();
|
||||||
|
@@ -1372,44 +1372,12 @@ void wxWindowDCImpl::DoDrawText(const wxString& text,
|
|||||||
|
|
||||||
gdk_pango_context_set_colormap( m_context, m_cmap ); // not needed in gtk+ >= 2.6
|
gdk_pango_context_set_colormap( m_context, m_cmap ); // not needed in gtk+ >= 2.6
|
||||||
|
|
||||||
bool underlined = m_font.IsOk() && m_font.GetUnderlined();
|
|
||||||
|
|
||||||
wxCharBuffer data = wxGTK_CONV(text);
|
wxCharBuffer data = wxGTK_CONV(text);
|
||||||
if ( !data )
|
if ( !data )
|
||||||
return;
|
return;
|
||||||
size_t datalen = strlen(data);
|
|
||||||
|
|
||||||
// in Pango >= 1.16 the "underline of leading/trailing spaces" bug
|
pango_layout_set_text(m_layout, data, data.length());
|
||||||
// has been fixed and thus the hack implemented below should never be used
|
const bool setAttrs = m_font.GTKSetPangoAttrs(m_layout);
|
||||||
static bool pangoOk = !wx_pango_version_check(1, 16, 0);
|
|
||||||
|
|
||||||
bool needshack = underlined && !pangoOk;
|
|
||||||
|
|
||||||
if (needshack)
|
|
||||||
{
|
|
||||||
// a PangoLayout which has leading/trailing spaces with underlined font
|
|
||||||
// is not correctly drawn by this pango version: Pango won't underline the spaces.
|
|
||||||
// This can be a problem; e.g. wxHTML rendering of underlined text relies on
|
|
||||||
// this behaviour. To workaround this problem, we use a special hack here
|
|
||||||
// suggested by pango maintainer Behdad Esfahbod: we prepend and append two
|
|
||||||
// empty space characters and give them a dummy colour attribute.
|
|
||||||
// This will force Pango to underline the leading/trailing spaces, too.
|
|
||||||
|
|
||||||
wxCharBuffer data_tmp(datalen + 6);
|
|
||||||
// copy the leading U+200C ZERO WIDTH NON-JOINER encoded in UTF8 format
|
|
||||||
memcpy(data_tmp.data(), "\342\200\214", 3);
|
|
||||||
// copy the user string
|
|
||||||
memcpy(data_tmp.data() + 3, data, datalen);
|
|
||||||
// copy the trailing U+200C ZERO WIDTH NON-JOINER encoded in UTF8 format
|
|
||||||
memcpy(data_tmp.data() + 3 + datalen, "\342\200\214", 3);
|
|
||||||
|
|
||||||
data = data_tmp;
|
|
||||||
datalen += 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
pango_layout_set_text(m_layout, data, datalen);
|
|
||||||
const bool
|
|
||||||
setAttrs = m_font.GTKSetPangoAttrs(m_layout, datalen, needshack);
|
|
||||||
|
|
||||||
int oldSize = 0;
|
int oldSize = 0;
|
||||||
const bool isScaled = fabs(m_scaleY - 1.0) > 0.00001;
|
const bool isScaled = fabs(m_scaleY - 1.0) > 0.00001;
|
||||||
@@ -1474,7 +1442,7 @@ void wxWindowDCImpl::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord
|
|||||||
y = YLOG2DEV(y);
|
y = YLOG2DEV(y);
|
||||||
|
|
||||||
pango_layout_set_text(m_layout, wxGTK_CONV(text), -1);
|
pango_layout_set_text(m_layout, wxGTK_CONV(text), -1);
|
||||||
m_font.GTKSetPangoAttrs(m_layout);
|
const bool setAttrs = m_font.GTKSetPangoAttrs(m_layout);
|
||||||
int oldSize = 0;
|
int oldSize = 0;
|
||||||
const bool isScaled = fabs(m_scaleY - 1.0) > 0.00001;
|
const bool isScaled = fabs(m_scaleY - 1.0) > 0.00001;
|
||||||
if (isScaled)
|
if (isScaled)
|
||||||
@@ -1527,7 +1495,7 @@ void wxWindowDCImpl::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord
|
|||||||
gdk_draw_layout_with_colors(m_gdkwindow, m_textGC, x+minX, y+minY,
|
gdk_draw_layout_with_colors(m_gdkwindow, m_textGC, x+minX, y+minY,
|
||||||
m_layout, NULL, bg_col);
|
m_layout, NULL, bg_col);
|
||||||
|
|
||||||
if (m_font.GetUnderlined() || m_font.GetStrikethrough())
|
if (setAttrs)
|
||||||
pango_layout_set_attributes(m_layout, NULL);
|
pango_layout_set_attributes(m_layout, NULL);
|
||||||
|
|
||||||
// clean up the transformation matrix
|
// clean up the transformation matrix
|
||||||
|
@@ -488,7 +488,7 @@ wxGDIRefData* wxFont::CloneGDIRefData(const wxGDIRefData* data) const
|
|||||||
return new wxFontRefData(*static_cast<const wxFontRefData*>(data));
|
return new wxFontRefData(*static_cast<const wxFontRefData*>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxFont::GTKSetPangoAttrs(PangoLayout* layout, size_t len, bool addDummyAttrs) const
|
bool wxFont::GTKSetPangoAttrs(PangoLayout* layout) const
|
||||||
{
|
{
|
||||||
if (!IsOk() || !(GetUnderlined() || GetStrikethrough()))
|
if (!IsOk() || !(GetUnderlined() || GetStrikethrough()))
|
||||||
return false;
|
return false;
|
||||||
@@ -496,43 +496,52 @@ bool wxFont::GTKSetPangoAttrs(PangoLayout* layout, size_t len, bool addDummyAttr
|
|||||||
PangoAttrList* attrs = pango_attr_list_new();
|
PangoAttrList* attrs = pango_attr_list_new();
|
||||||
PangoAttribute* a;
|
PangoAttribute* a;
|
||||||
|
|
||||||
if (GetUnderlined())
|
if (wx_pango_version_check(1,16,0))
|
||||||
{
|
{
|
||||||
a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
|
// a PangoLayout which has leading/trailing spaces with underlined font
|
||||||
if (len)
|
// is not correctly drawn by this pango version: Pango won't underline the spaces.
|
||||||
{
|
// This can be a problem; e.g. wxHTML rendering of underlined text relies on
|
||||||
a->start_index = 0;
|
// this behaviour. To workaround this problem, we use a special hack here
|
||||||
a->end_index = len;
|
// suggested by pango maintainer Behdad Esfahbod: we prepend and append two
|
||||||
}
|
// empty space characters and give them a dummy colour attribute.
|
||||||
pango_attr_list_insert(attrs, a);
|
// This will force Pango to underline the leading/trailing spaces, too.
|
||||||
|
|
||||||
// Add dummy attributes (use colour as it's invisible anyhow for 0
|
const char* text = pango_layout_get_text(layout);
|
||||||
// width spaces) to ensure that the spaces in the beginning/end of the
|
const size_t n = strlen(text);
|
||||||
// string are underlined too.
|
if ((n > 0 && text[0] == ' ') || (n > 1 && text[n - 1] == ' '))
|
||||||
if ( addDummyAttrs )
|
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( len > 2, "Must have 0-width spaces at string ends" );
|
wxCharBuffer buf(n + 6);
|
||||||
|
// copy the leading U+200C ZERO WIDTH NON-JOINER encoded in UTF8 format
|
||||||
|
memcpy(buf.data(), "\342\200\214", 3);
|
||||||
|
// copy the user string
|
||||||
|
memcpy(buf.data() + 3, text, n);
|
||||||
|
// copy the trailing U+200C ZERO WIDTH NON-JOINER encoded in UTF8 format
|
||||||
|
memcpy(buf.data() + 3 + n, "\342\200\214", 3);
|
||||||
|
|
||||||
|
pango_layout_set_text(layout, buf, n + 6);
|
||||||
|
|
||||||
|
// Add dummy attributes (use colour as it's invisible anyhow for 0
|
||||||
|
// width spaces) to ensure that the spaces in the beginning/end of the
|
||||||
|
// string are underlined too.
|
||||||
a = pango_attr_foreground_new(0x0057, 0x52A9, 0xD614);
|
a = pango_attr_foreground_new(0x0057, 0x52A9, 0xD614);
|
||||||
a->start_index = 0;
|
a->start_index = 0;
|
||||||
a->end_index = 1;
|
a->end_index = 3;
|
||||||
pango_attr_list_insert(attrs, a);
|
pango_attr_list_insert(attrs, a);
|
||||||
|
|
||||||
a = pango_attr_foreground_new(0x0057, 0x52A9, 0xD614);
|
a = pango_attr_foreground_new(0x0057, 0x52A9, 0xD614);
|
||||||
a->start_index = len - 1;
|
a->start_index = n + 3;
|
||||||
a->end_index = len;
|
a->end_index = n + 6;
|
||||||
pango_attr_list_insert(attrs, a);
|
pango_attr_list_insert(attrs, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (GetUnderlined())
|
||||||
|
{
|
||||||
|
a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
|
||||||
|
pango_attr_list_insert(attrs, a);
|
||||||
|
}
|
||||||
if (GetStrikethrough())
|
if (GetStrikethrough())
|
||||||
{
|
{
|
||||||
a = pango_attr_strikethrough_new(true);
|
a = pango_attr_strikethrough_new(true);
|
||||||
if (len)
|
|
||||||
{
|
|
||||||
a->start_index = 0;
|
|
||||||
a->end_index = len;
|
|
||||||
}
|
|
||||||
pango_attr_list_insert(attrs, a);
|
pango_attr_list_insert(attrs, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user