Line data Source code
1 : /* Copyright (C) 2022 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifndef INCLUDED_GUITEXT
19 : #define INCLUDED_GUITEXT
20 :
21 : #include "gui/CGUISprite.h"
22 : #include "gui/SettingTypes/CGUIColor.h"
23 : #include "gui/SettingTypes/EAlign.h"
24 : #include "maths/Rect.h"
25 : #include "maths/Size2D.h"
26 : #include "maths/Vector2D.h"
27 : #include "ps/CStrIntern.h"
28 :
29 : #include <array>
30 : #include <list>
31 : #include <vector>
32 :
33 : class CCanvas2D;
34 : class CGUI;
35 : class CGUIString;
36 : class IGUIObject;
37 : struct SGenerateTextImage;
38 :
39 : using SGenerateTextImages = std::array<std::vector<SGenerateTextImage>, 2>;
40 :
41 : /**
42 : * An CGUIText object is a parsed string, divided into
43 : * text-rendering components. Each component, being a
44 : * call to the Renderer. For instance, if you by tags
45 : * change the color, then the GUI will have to make
46 : * individual calls saying it want that color on the
47 : * text.
48 : *
49 : * For instance:
50 : * "Hello [b]there[/b] bunny!"
51 : *
52 : * That without word-wrapping would mean 3 components.
53 : * i.e. 3 calls to CRenderer. One drawing "Hello",
54 : * one drawing "there" in bold, and one drawing "bunny!".
55 : */
56 196 : class CGUIText
57 : {
58 : public:
59 : /**
60 : * A sprite call to the CRenderer
61 : */
62 0 : struct SSpriteCall
63 : {
64 : // The CGUISpriteInstance makes this uncopyable to avoid invalidating its draw cache
65 : NONCOPYABLE(SSpriteCall);
66 0 : MOVABLE(SSpriteCall);
67 :
68 0 : SSpriteCall() {}
69 :
70 : /**
71 : * Size and position of sprite
72 : */
73 : CRect m_Area;
74 :
75 : /**
76 : * Sprite from global GUI sprite database.
77 : */
78 : CGUISpriteInstance m_Sprite;
79 : };
80 :
81 : /**
82 : * A text call to the CRenderer
83 : */
84 4705 : struct STextCall
85 : {
86 : NONCOPYABLE(STextCall);
87 2770 : MOVABLE(STextCall);
88 :
89 1935 : STextCall() :
90 : m_UseCustomColor(false),
91 : m_Bold(false), m_Italic(false), m_Underlined(false),
92 1935 : m_pSpriteCall(nullptr) {}
93 :
94 : /**
95 : * Position
96 : */
97 : CVector2D m_Pos;
98 :
99 : /**
100 : * Size
101 : */
102 : CSize2D m_Size;
103 :
104 : /**
105 : * The string that is suppose to be rendered.
106 : */
107 : CStrW m_String;
108 :
109 : /**
110 : * Use custom color? If true then m_Color is used,
111 : * else the color inputted will be used.
112 : */
113 : bool m_UseCustomColor;
114 :
115 : /**
116 : * Color setup
117 : */
118 : CGUIColor m_Color;
119 :
120 : /**
121 : * Font name
122 : */
123 : CStrIntern m_Font;
124 :
125 : /**
126 : * Settings
127 : */
128 : bool m_Bold, m_Italic, m_Underlined;
129 :
130 : /**
131 : * Tooltip text
132 : */
133 : CStrW m_Tooltip;
134 :
135 : /**
136 : * *IF* an icon, then this is not nullptr.
137 : */
138 : std::list<SSpriteCall>::pointer m_pSpriteCall;
139 : };
140 :
141 : // The SSpriteCall CGUISpriteInstance makes this uncopyable to avoid invalidating its draw cache.
142 : // Also take advantage of exchanging the containers directly with move semantics.
143 : NONCOPYABLE(CGUIText);
144 0 : MOVABLE(CGUIText);
145 :
146 : /**
147 : * Generates empty text.
148 : */
149 5 : CGUIText() = default;
150 :
151 : /**
152 : * Generate a CGUIText object from the inputted string.
153 : * The function will break down the string and its
154 : * tags to calculate exactly which rendering queries
155 : * will be sent to the Renderer. Also, horizontal alignment
156 : * is taken into acount in this method but NOT vertical alignment.
157 : *
158 : * @param string Text to generate CGUIText object from.
159 : * @param font Default font, notice both Default color and default font
160 : * can be changed by tags.
161 : * @param width Width, 0 if no word-wrapping.
162 : * @param bufferZone Space between text and edge, and space between text and images.
163 : * @param align Horizontal alignment (left / center / right).
164 : * @param pObject Optional parameter for error output. Used *only* if error parsing fails,
165 : * and we need to be able to output which object the error occurred in to aid the user.
166 : */
167 : CGUIText(const CGUI& pGUI, const CGUIString& string, const CStrW& fontW, const float width, const float bufferZone, const EAlign align, const IGUIObject* pObject);
168 :
169 : /**
170 : * Draw this CGUIText object
171 : */
172 : void Draw(CGUI& pGUI, CCanvas2D& canvas, const CGUIColor& DefaultColor, const CVector2D& pos, CRect clipping) const;
173 :
174 43 : const CSize2D& GetSize() const { return m_Size; }
175 :
176 : const std::list<SSpriteCall>& GetSpriteCalls() const { return m_SpriteCalls; }
177 :
178 897 : const std::vector<STextCall>& GetTextCalls() const { return m_TextCalls; }
179 :
180 : // Helper functions of the constructor
181 : bool ProcessLine(
182 : const CGUI& pGUI,
183 : const CGUIString& string,
184 : const CStrIntern& font,
185 : const IGUIObject* pObject,
186 : const SGenerateTextImages& images,
187 : const EAlign align,
188 : const float prelimLineHeight,
189 : const float width,
190 : const float bufferZone,
191 : bool& firstLine,
192 : float& y,
193 : int& i,
194 : int& from);
195 :
196 : void SetupSpriteCalls(
197 : const CGUI& pGUI,
198 : const std::array<std::vector<CStr>, 2>& feedbackImages,
199 : const float y,
200 : const float width,
201 : const float bufferZone,
202 : const int i,
203 : const int posLastImage,
204 : SGenerateTextImages& images);
205 :
206 : float GetLineOffset(
207 : const EAlign align,
208 : const float widthRangeFrom,
209 : const float widthRangeTo,
210 : const CSize2D& lineSize) const;
211 :
212 : void ComputeLineRange(
213 : const SGenerateTextImages& images,
214 : const float y,
215 : const float width,
216 : const float prelimLineHeight,
217 : float& widthRangeFrom,
218 : float& widthRangeTo) const;
219 :
220 : void ComputeLineSize(
221 : const CGUI& pGUI,
222 : const CGUIString& string,
223 : const CStrIntern& font,
224 : const bool firstLine,
225 : const float width,
226 : const float widthRangeFrom,
227 : const float widthRangeTo,
228 : const int i,
229 : const int tempFrom,
230 : CSize2D& lineSize) const;
231 :
232 : bool AssembleCalls(
233 : const CGUI& pGUI,
234 : const CGUIString& string,
235 : const CStrIntern& font,
236 : const IGUIObject* pObject,
237 : const bool firstLine,
238 : const float width,
239 : const float widthRangeTo,
240 : const float dx,
241 : const float y,
242 : const int tempFrom,
243 : const int i,
244 : int& from);
245 :
246 : /**
247 : * List of TextCalls, for instance "Hello", "there!"
248 : */
249 : std::vector<STextCall> m_TextCalls;
250 :
251 : /**
252 : * List of sprites, or "icons" that should be rendered
253 : * along with the text.
254 : */
255 : std::list<SSpriteCall> m_SpriteCalls; // list for consistent mem addresses
256 : // so that we can point to elements.
257 : /**
258 : * Width and height of the whole output, used when setting up
259 : * scrollbars and such.
260 : */
261 : CSize2D m_Size;
262 : };
263 :
264 : struct SGenerateTextImage
265 : {
266 : // The image's starting location in Y
267 : float m_YFrom;
268 :
269 : // The image's end location in Y
270 : float m_YTo;
271 :
272 : // The image width in other words
273 : float m_Indentation;
274 :
275 : void SetupSpriteCall(
276 : const bool left, CGUIText::SSpriteCall& spriteCall, const float width, const float y,
277 : const CSize2D& size, const CStr& textureName, const float bufferZone);
278 : };
279 :
280 : #endif // INCLUDED_GUITEXT
|