It can be handled in exactly the same way as underlining, so just do it instead of leaving a "TODO" comment about it.
		
			
				
	
	
		
			257 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			257 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        wx/private/markupparserattr.h
 | 
						|
// Purpose:     Classes mapping markup attributes to wxFont/wxColour.
 | 
						|
// Author:      Vadim Zeitlin
 | 
						|
// Created:     2011-02-18
 | 
						|
// Copyright:   (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
 | 
						|
// Licence:     wxWindows licence
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
#ifndef _WX_PRIVATE_MARKUPPARSERATTR_H_
 | 
						|
#define _WX_PRIVATE_MARKUPPARSERATTR_H_
 | 
						|
 | 
						|
#include "wx/private/markupparser.h"
 | 
						|
 | 
						|
#include "wx/stack.h"
 | 
						|
 | 
						|
#include "wx/colour.h"
 | 
						|
#include "wx/font.h"
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// wxMarkupParserAttrOutput: simplified wxFont-using version of the above.
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
// This class assumes that wxFont and wxColour are used to perform all the
 | 
						|
// markup tags and implements the base class virtual functions in terms of
 | 
						|
// OnAttr{Start,End}() only.
 | 
						|
//
 | 
						|
// Notice that you still must implement OnText() inherited from the base class
 | 
						|
// when deriving from this one.
 | 
						|
class wxMarkupParserAttrOutput : public wxMarkupParserOutput
 | 
						|
{
 | 
						|
public:
 | 
						|
    // 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 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;
 | 
						|
    };
 | 
						|
 | 
						|
 | 
						|
    // This object must be initialized with the font and colours to use
 | 
						|
    // initially, i.e. the ones used before any tags in the string.
 | 
						|
    wxMarkupParserAttrOutput(const wxFont& font,
 | 
						|
                             const wxColour& foreground,
 | 
						|
                             const wxColour& background)
 | 
						|
    {
 | 
						|
        m_attrs.push(Attr(NULL, font, foreground, background));
 | 
						|
    }
 | 
						|
 | 
						|
    // Indicates the change of the font and/or colours used. Any of the
 | 
						|
    // fields of the argument may be invalid indicating that the corresponding
 | 
						|
    // attribute didn't actually change.
 | 
						|
    virtual void OnAttrStart(const Attr& attr) = 0;
 | 
						|
 | 
						|
    // Indicates the end of the region affected by the given attributes
 | 
						|
    // (the same ones that were passed to the matching OnAttrStart(), use
 | 
						|
    // GetAttr() to get the ones that will be used from now on).
 | 
						|
    virtual void OnAttrEnd(const Attr& attr) = 0;
 | 
						|
 | 
						|
 | 
						|
    // Implement all pure virtual methods inherited from the base class in
 | 
						|
    // terms of our own ones.
 | 
						|
    virtual void OnBoldStart() wxOVERRIDE { DoChangeFont(&wxFont::Bold); }
 | 
						|
    virtual void OnBoldEnd() wxOVERRIDE { DoEndAttr(); }
 | 
						|
 | 
						|
    virtual void OnItalicStart() wxOVERRIDE { DoChangeFont(&wxFont::Italic); }
 | 
						|
    virtual void OnItalicEnd() wxOVERRIDE { DoEndAttr(); }
 | 
						|
 | 
						|
    virtual void OnUnderlinedStart() wxOVERRIDE { DoChangeFont(&wxFont::Underlined); }
 | 
						|
    virtual void OnUnderlinedEnd() wxOVERRIDE { DoEndAttr(); }
 | 
						|
 | 
						|
    virtual void OnStrikethroughStart() wxOVERRIDE { DoChangeFont(&wxFont::Strikethrough); }
 | 
						|
    virtual void OnStrikethroughEnd() wxOVERRIDE { DoEndAttr(); }
 | 
						|
 | 
						|
    virtual void OnBigStart() wxOVERRIDE { DoChangeFont(&wxFont::Larger); }
 | 
						|
    virtual void OnBigEnd() wxOVERRIDE { DoEndAttr(); }
 | 
						|
 | 
						|
    virtual void OnSmallStart() wxOVERRIDE { DoChangeFont(&wxFont::Smaller); }
 | 
						|
    virtual void OnSmallEnd() wxOVERRIDE { DoEndAttr(); }
 | 
						|
 | 
						|
    virtual void OnTeletypeStart() wxOVERRIDE
 | 
						|
    {
 | 
						|
        wxFont font(GetFont());
 | 
						|
        font.SetFamily(wxFONTFAMILY_TELETYPE);
 | 
						|
        DoSetFont(font);
 | 
						|
    }
 | 
						|
    virtual void OnTeletypeEnd() wxOVERRIDE { DoEndAttr(); }
 | 
						|
 | 
						|
    virtual void OnSpanStart(const wxMarkupSpanAttributes& spanAttr) wxOVERRIDE
 | 
						|
    {
 | 
						|
        wxFont font(GetFont());
 | 
						|
        if ( !spanAttr.m_fontFace.empty() )
 | 
						|
            font.SetFaceName(spanAttr.m_fontFace);
 | 
						|
 | 
						|
        FontModifier<wxFontWeight>()(spanAttr.m_isBold,
 | 
						|
                                     font, &wxFont::SetWeight,
 | 
						|
                                     wxFONTWEIGHT_NORMAL, wxFONTWEIGHT_BOLD);
 | 
						|
 | 
						|
        FontModifier<wxFontStyle>()(spanAttr.m_isItalic,
 | 
						|
                                    font, &wxFont::SetStyle,
 | 
						|
                                    wxFONTSTYLE_NORMAL, wxFONTSTYLE_ITALIC);
 | 
						|
 | 
						|
        FontModifier<bool>()(spanAttr.m_isUnderlined,
 | 
						|
                             font, &wxFont::SetUnderlined,
 | 
						|
                             false, true);
 | 
						|
 | 
						|
        FontModifier<bool>()(spanAttr.m_isStrikethrough,
 | 
						|
                             font, &wxFont::SetStrikethrough,
 | 
						|
                             false, true);
 | 
						|
 | 
						|
        switch ( spanAttr.m_sizeKind )
 | 
						|
        {
 | 
						|
            case wxMarkupSpanAttributes::Size_Unspecified:
 | 
						|
                break;
 | 
						|
 | 
						|
            case wxMarkupSpanAttributes::Size_Relative:
 | 
						|
                if ( spanAttr.m_fontSize > 0 )
 | 
						|
                    font.MakeLarger();
 | 
						|
                else
 | 
						|
                    font.MakeSmaller();
 | 
						|
                break;
 | 
						|
 | 
						|
            case wxMarkupSpanAttributes::Size_Symbolic:
 | 
						|
                // The values of font size intentionally coincide with the
 | 
						|
                // values of wxFontSymbolicSize enum elements so simply cast
 | 
						|
                // one to the other.
 | 
						|
                font.SetSymbolicSize(
 | 
						|
                    static_cast<wxFontSymbolicSize>(spanAttr.m_fontSize)
 | 
						|
                );
 | 
						|
                break;
 | 
						|
 | 
						|
            case wxMarkupSpanAttributes::Size_PointParts:
 | 
						|
                font.SetFractionalPointSize(spanAttr.m_fontSize/1024.);
 | 
						|
                break;
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        const Attr attr(&m_attrs.top(), font, spanAttr.m_fgCol, spanAttr.m_bgCol);
 | 
						|
        OnAttrStart(attr);
 | 
						|
 | 
						|
        m_attrs.push(attr);
 | 
						|
    }
 | 
						|
 | 
						|
    virtual void OnSpanEnd(const wxMarkupSpanAttributes& WXUNUSED(spanAttr)) wxOVERRIDE
 | 
						|
    {
 | 
						|
        DoEndAttr();
 | 
						|
    }
 | 
						|
 | 
						|
protected:
 | 
						|
    // Get the current attributes, i.e. the ones that should be used for
 | 
						|
    // rendering (or measuring or whatever) the text at the current position in
 | 
						|
    // the string.
 | 
						|
    //
 | 
						|
    // It may be called from OnAttrStart() to get the old attributes used
 | 
						|
    // before and from OnAttrEnd() to get the new attributes that will be used
 | 
						|
    // from now on but is mostly meant to be used from overridden OnText()
 | 
						|
    // implementations.
 | 
						|
    const Attr& GetAttr() const { return m_attrs.top(); }
 | 
						|
 | 
						|
    // A shortcut for accessing the font of the current attribute.
 | 
						|
    const wxFont& GetFont() const { return GetAttr().font; }
 | 
						|
 | 
						|
private:
 | 
						|
    // Change only the font to the given one. Call OnAttrStart() to notify
 | 
						|
    // about the change and update the attributes stack.
 | 
						|
    void DoSetFont(const wxFont& font)
 | 
						|
    {
 | 
						|
        const Attr attr(&m_attrs.top(), font);
 | 
						|
 | 
						|
        OnAttrStart(attr);
 | 
						|
 | 
						|
        m_attrs.push(attr);
 | 
						|
    }
 | 
						|
 | 
						|
    // Apply the given function to the font currently on top of the font stack,
 | 
						|
    // push the new font on the stack and call OnAttrStart() with it.
 | 
						|
    void DoChangeFont(wxFont (wxFont::*func)() const)
 | 
						|
    {
 | 
						|
        DoSetFont((GetFont().*func)());
 | 
						|
    }
 | 
						|
 | 
						|
    void DoEndAttr()
 | 
						|
    {
 | 
						|
        const Attr attr(m_attrs.top());
 | 
						|
        m_attrs.pop();
 | 
						|
 | 
						|
        OnAttrEnd(attr);
 | 
						|
    }
 | 
						|
 | 
						|
    // A helper class used to apply the given function to a wxFont object
 | 
						|
    // depending on the value of an OptionalBool.
 | 
						|
    template <typename T>
 | 
						|
    struct FontModifier
 | 
						|
    {
 | 
						|
        FontModifier() { }
 | 
						|
 | 
						|
        void operator()(wxMarkupSpanAttributes::OptionalBool isIt,
 | 
						|
                        wxFont& font,
 | 
						|
                        void (wxFont::*func)(T),
 | 
						|
                        T noValue,
 | 
						|
                        T yesValue)
 | 
						|
        {
 | 
						|
            switch ( isIt )
 | 
						|
            {
 | 
						|
                case wxMarkupSpanAttributes::Unspecified:
 | 
						|
                    break;
 | 
						|
 | 
						|
                case wxMarkupSpanAttributes::No:
 | 
						|
                    (font.*func)(noValue);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case wxMarkupSpanAttributes::Yes:
 | 
						|
                    (font.*func)(yesValue);
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    };
 | 
						|
 | 
						|
 | 
						|
    wxStack<Attr> m_attrs;
 | 
						|
 | 
						|
    wxDECLARE_NO_COPY_CLASS(wxMarkupParserAttrOutput);
 | 
						|
};
 | 
						|
 | 
						|
#endif // _WX_PRIVATE_MARKUPPARSERATTR_H_
 |