From 7546989c4488da3bc826b37eb09df40950c19dab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Slavi=CC=81k?= Date: Wed, 19 Oct 2016 17:04:16 +0200 Subject: [PATCH] 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 "...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. --- include/wx/private/markupparserattr.h | 33 +++++++++++++++++++++++---- src/generic/markuptext.cpp | 4 ++-- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/include/wx/private/markupparserattr.h b/include/wx/private/markupparserattr.h index 998a0414a9..52bf189a65 100644 --- a/include/wx/private/markupparserattr.h +++ b/include/wx/private/markupparserattr.h @@ -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); diff --git a/src/generic/markuptext.cpp b/src/generic/markuptext.cpp index 9e2c42b06e..0a994c66dd 100644 --- a/src/generic/markuptext.cpp +++ b/src/generic/markuptext.cpp @@ -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