]> git.saurik.com Git - wxWidgets.git/blob - include/wx/private/markupparserattr.h
Fix fatal bug with deleting the old contents in wxScopedArray::reset().
[wxWidgets.git] / include / wx / private / markupparserattr.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/private/markupparserattr.h
3 // Purpose: Classes mapping markup attributes to wxFont/wxColour.
4 // Author: Vadim Zeitlin
5 // Created: 2011-02-18
6 // RCS-ID: $Id: wxhead.h,v 1.12 2010-04-22 12:44:51 zeitlin Exp $
7 // Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 #ifndef _WX_PRIVATE_MARKUPPARSERATTR_H_
12 #define _WX_PRIVATE_MARKUPPARSERATTR_H_
13
14 #include "wx/private/markupparser.h"
15
16 #include "wx/stack.h"
17
18 #include "wx/colour.h"
19 #include "wx/font.h"
20
21 // ----------------------------------------------------------------------------
22 // wxMarkupParserAttrOutput: simplified wxFont-using version of the above.
23 // ----------------------------------------------------------------------------
24
25 // This class assumes that wxFont and wxColour are used to perform all the
26 // markup tags and implements the base class virtual functions in terms of
27 // OnAttr{Start,End}() only.
28 //
29 // Notice that you still must implement OnText() inherited from the base class
30 // when deriving from this one.
31 class wxMarkupParserAttrOutput : public wxMarkupParserOutput
32 {
33 public:
34 // A simple container of font and colours.
35 struct Attr
36 {
37 Attr(const wxFont& font_,
38 const wxColour& foreground_ = wxColour(),
39 const wxColour& background_ = wxColour())
40 : font(font_), foreground(foreground_), background(background_)
41 {
42 }
43
44 wxFont font;
45 wxColour foreground,
46 background;
47 };
48
49
50 // This object must be initialized with the font and colours to use
51 // initially, i.e. the ones used before any tags in the string.
52 wxMarkupParserAttrOutput(const wxFont& font,
53 const wxColour& foreground,
54 const wxColour& background)
55 {
56 m_attrs.push(Attr(font, foreground, background));
57 }
58
59 // Indicates the change of the font and/or colours used. Any of the
60 // fields of the argument may be invalid indicating that the corresponding
61 // attribute didn't actually change.
62 virtual void OnAttrStart(const Attr& attr) = 0;
63
64 // Indicates the end of the region affected by the given attributes
65 // (the same ones that were passed to the matching OnAttrStart(), use
66 // GetAttr() to get the ones that will be used from now on).
67 virtual void OnAttrEnd(const Attr& attr) = 0;
68
69
70 // Implement all pure virtual methods inherited from the base class in
71 // terms of our own ones.
72 virtual void OnBoldStart() { DoChangeFont(&wxFont::Bold); }
73 virtual void OnBoldEnd() { DoEndAttr(); }
74
75 virtual void OnItalicStart() { DoChangeFont(&wxFont::Italic); }
76 virtual void OnItalicEnd() { DoEndAttr(); }
77
78 virtual void OnUnderlinedStart() { DoChangeFont(&wxFont::Underlined); }
79 virtual void OnUnderlinedEnd() { DoEndAttr(); }
80
81 virtual void OnStrikethroughStart() { } // TODO: No support in wxFont yet.
82 virtual void OnStrikethroughEnd() { }
83
84 virtual void OnBigStart() { DoChangeFont(&wxFont::Larger); }
85 virtual void OnBigEnd() { DoEndAttr(); }
86
87 virtual void OnSmallStart() { DoChangeFont(&wxFont::Smaller); }
88 virtual void OnSmallEnd() { DoEndAttr(); }
89
90 virtual void OnTeletypeStart()
91 {
92 wxFont font(GetFont());
93 font.SetFamily(wxFONTFAMILY_TELETYPE);
94 DoSetFont(font);
95 }
96 virtual void OnTeletypeEnd() { DoEndAttr(); }
97
98 virtual void OnSpanStart(const wxMarkupSpanAttributes& spanAttr)
99 {
100 wxFont font(GetFont());
101 if ( !spanAttr.m_fontFace.empty() )
102 font.SetFaceName(spanAttr.m_fontFace);
103
104 FontModifier<wxFontWeight>()(spanAttr.m_isBold,
105 font, &wxFont::SetWeight,
106 wxFONTWEIGHT_NORMAL, wxFONTWEIGHT_BOLD);
107
108 FontModifier<wxFontStyle>()(spanAttr.m_isItalic,
109 font, &wxFont::SetStyle,
110 wxFONTSTYLE_NORMAL, wxFONTSTYLE_ITALIC);
111
112 FontModifier<bool>()(spanAttr.m_isUnderlined,
113 font, &wxFont::SetUnderlined,
114 false, true);
115
116 // TODO: No support for strike-through yet.
117
118 switch ( spanAttr.m_sizeKind )
119 {
120 case wxMarkupSpanAttributes::Size_Unspecified:
121 break;
122
123 case wxMarkupSpanAttributes::Size_Relative:
124 if ( spanAttr.m_fontSize > 0 )
125 font.MakeLarger();
126 else
127 font.MakeSmaller();
128 break;
129
130 case wxMarkupSpanAttributes::Size_Symbolic:
131 // The values of font size intentionally coincide with the
132 // values of wxFontSymbolicSize enum elements so simply cast
133 // one to the other.
134 font.SetSymbolicSize(
135 static_cast<wxFontSymbolicSize>(spanAttr.m_fontSize)
136 );
137 break;
138
139 case wxMarkupSpanAttributes::Size_PointParts:
140 font.SetPointSize((spanAttr.m_fontSize + 1023)/1024);
141 break;
142 }
143
144
145 const Attr attr(font, spanAttr.m_fgCol, spanAttr.m_bgCol);
146 OnAttrStart(attr);
147
148 m_attrs.push(attr);
149 }
150
151 virtual void OnSpanEnd(const wxMarkupSpanAttributes& WXUNUSED(spanAttr))
152 {
153 DoEndAttr();
154 }
155
156 protected:
157 // Get the current attributes, i.e. the ones that should be used for
158 // rendering (or measuring or whatever) the text at the current position in
159 // the string.
160 //
161 // It may be called from OnAttrStart() to get the old attributes used
162 // before and from OnAttrEnd() to get the new attributes that will be used
163 // from now on but is mostly meant to be used from overridden OnText()
164 // implementations.
165 const Attr& GetAttr() const { return m_attrs.top(); }
166
167 // A shortcut for accessing the font of the current attribute.
168 const wxFont& GetFont() const { return GetAttr().font; }
169
170 private:
171 // Change only the font to the given one. Call OnAttrStart() to notify
172 // about the change and update the attributes stack.
173 void DoSetFont(const wxFont& font)
174 {
175 const Attr attr(font);
176
177 OnAttrStart(attr);
178
179 m_attrs.push(attr);
180 }
181
182 // Apply the given function to the font currently on top of the font stack,
183 // push the new font on the stack and call OnAttrStart() with it.
184 void DoChangeFont(wxFont (wxFont::*func)() const)
185 {
186 DoSetFont((GetFont().*func)());
187 }
188
189 void DoEndAttr()
190 {
191 const Attr attr(m_attrs.top());
192 m_attrs.pop();
193
194 OnAttrEnd(attr);
195 }
196
197 // A helper class used to apply the given function to a wxFont object
198 // depending on the value of an OptionalBool.
199 template <typename T>
200 struct FontModifier
201 {
202 FontModifier() { }
203
204 void operator()(wxMarkupSpanAttributes::OptionalBool isIt,
205 wxFont& font,
206 void (wxFont::*func)(T),
207 T noValue,
208 T yesValue)
209 {
210 switch ( isIt )
211 {
212 case wxMarkupSpanAttributes::Unspecified:
213 break;
214
215 case wxMarkupSpanAttributes::No:
216 (font.*func)(noValue);
217 break;
218
219 case wxMarkupSpanAttributes::Yes:
220 (font.*func)(yesValue);
221 break;
222 }
223 }
224 };
225
226
227 wxStack<Attr> m_attrs;
228
229 wxDECLARE_NO_COPY_CLASS(wxMarkupParserAttrOutput);
230 };
231
232 #endif // _WX_PRIVATE_MARKUPPARSERATTR_H_