Fix wxMarkupParserAttr's unwinding of colors

Fix the logic for restoring previous span's colors to account for the
possibility of spans that don't change the color, such as in "<i><span
color='red'>...</span></i>foo". Previously, "foo" would always be
rendered black, because unwinding the attributes stack would encounter
an invalid color (which has r=g=b=0) and set it, disregarding and
preexisting attributes.

Because there's code in there that checks whether the attributes are
valid, we need to keep track of both the actually specified attributes
and the currently effective ones, and use the latter for restoration.
This commit is contained in:
Václav Slavík 2016-10-19 17:04:16 +02:00 committed by Václav Slavík
parent d9df970573
commit 7546989c44
2 changed files with 30 additions and 7 deletions

View File

@ -30,19 +30,42 @@
class wxMarkupParserAttrOutput : public wxMarkupParserOutput
{
public:
// A simple container of font and colours.
// A container of font and colours with inheritance support. It holds two
// sets of attributes:
// 1. The currently specified ones from parsed tags that contain
// information on on what should change in the output; some of them
// may be invalid if only the others are affected by a change.
// 2. The _effective_ attributes that are always valid and accumulate
// all past changes as the markup is being parser; these are used
// to restore state when unwinding nested attributes.
struct Attr
{
Attr(const wxFont& font_,
Attr(const Attr *attrInEffect,
const wxFont& font_,
const wxColour& foreground_ = wxColour(),
const wxColour& background_ = wxColour())
: font(font_), foreground(foreground_), background(background_)
{
if (attrInEffect)
{
effectiveFont = font.IsOk() ? font : attrInEffect->effectiveFont;
effectiveForeground = foreground_.IsOk() ? foreground_ : attrInEffect->effectiveForeground;
effectiveBackground = background.IsOk() ? background : attrInEffect->effectiveBackground;
}
else
{
effectiveFont = font;
effectiveForeground = foreground;
effectiveBackground = background;
}
}
wxFont font;
wxColour foreground,
background;
wxFont effectiveFont;
wxColour effectiveForeground,
effectiveBackground;
};
@ -52,7 +75,7 @@ public:
const wxColour& foreground,
const wxColour& background)
{
m_attrs.push(Attr(font, foreground, background));
m_attrs.push(Attr(NULL, font, foreground, background));
}
// Indicates the change of the font and/or colours used. Any of the
@ -141,7 +164,7 @@ public:
}
const Attr attr(font, spanAttr.m_fgCol, spanAttr.m_bgCol);
const Attr attr(&m_attrs.top(), font, spanAttr.m_fgCol, spanAttr.m_bgCol);
OnAttrStart(attr);
m_attrs.push(attr);
@ -171,7 +194,7 @@ private:
// about the change and update the attributes stack.
void DoSetFont(const wxFont& font)
{
const Attr attr(font);
const Attr attr(&m_attrs.top(), font);
OnAttrStart(attr);

View File

@ -156,11 +156,11 @@ public:
// ...but we only need to restore the colours if we had changed them.
if ( attr.foreground.IsOk() )
m_dc.SetTextForeground(GetAttr().foreground);
m_dc.SetTextForeground(GetAttr().effectiveForeground);
if ( attr.background.IsOk() )
{
wxColour background = GetAttr().background;
wxColour background = GetAttr().effectiveBackground;
if ( !background.IsOk() )
{
// Invalid background colour indicates that the background