Gamedev Framework (gf)  0.1.0
A C++11 framework for 2D games
Text.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016 Julien Bernard
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software
15  * in a product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  * 2. Altered source versions must be plainly marked as such, and must not be
18  * misrepresented as being the original software.
19  * 3. This notice may not be removed or altered from any source distribution.
20  *
21  * Part of this file comes from SFML, with the same license:
22  * Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
23  */
24 #ifndef GF_TEXT_H
25 #define GF_TEXT_H
26 
27 #include <string>
28 
29 #include "Portability.h"
30 #include "Transformable.h"
31 #include "Vector.h"
32 #include "VertexArray.h"
33 #include "VertexBuffer.h"
34 
35 namespace gf {
36 #ifndef DOXYGEN_SHOULD_SKIP_THIS
37 inline namespace v1 {
38 #endif
39 
40  class Font;
41 
42  /**
43  * @brief Graphical text that can be drawn to a render target
44  *
45  * gf::Text is a drawable class that allows to easily display
46  * some text with custom style and color on a render target.
47  *
48  * It inherits all the functions from gf::Transformable:
49  * position, rotation, scale, origin. It also adds text-specific
50  * properties such as the font to use, the character size, the
51  * global color and the text to display of course.
52  * It also provides convenience functions to calculate the
53  * graphical size of the text.
54  *
55  * gf::Text works in combination with the gf::Font class, which
56  * loads and provides the glyphs (visual characters) of a given font.
57  *
58  * The separation of gf::Font and gf::Text allows more flexibility
59  * and better performances: indeed a gf::Font is a heavy resource,
60  * and any operation on it is slow (often too slow for real-time
61  * applications). On the other side, a gf::Text is a lightweight
62  * object which can combine the glyphs data and metrics of a gf::Font
63  * to display any text on a render target.
64  *
65  * It is important to note that the gf::Text instance doesn't
66  * copy the font that it uses, it only keeps a reference to it.
67  * Thus, a gf::Font must not be destructed while it is
68  * used by a gf::Text (i.e. never write a function that
69  * uses a local gf::Font instance for creating a text).
70  *
71  * Usage example:
72  *
73  * ~~~{.cc}
74  * // Declare and load a font
75  * gf::Font font;
76  * font.loadFromFile("arial.ttf");
77  *
78  * // Create a text
79  * gf::Text text("hello", font);
80  * text.setCharacterSize(30);
81  * text.setColor(gf::Color::Red);
82  *
83  * // Draw it
84  * rendered.draw(text);
85  * ~~~
86  *
87  * @sa gf::Font
88  */
89  class GF_API Text : public Transformable {
90  public:
91  /**
92  * @brief The alignement of the text
93  */
94  enum class Alignment {
95  None, ///< No alignement
96  Left, ///< Left alignement
97  Right, ///< Right alignement
98  Center, ///< Centered alignment
99  Justify, ///< Justified alignment
100  };
101 
102  /**
103  * @brief Default constructor
104  *
105  * Creates an empty text.
106  */
107  Text();
108 
109  /**
110  * @brief Construct the text from a string, font and size
111  *
112  * @param string Text assigned to the string in UTF-8 format
113  * @param font Font used to draw the string
114  * @param characterSize Base size of characters, in pixels
115  */
116  Text(std::string string, Font& font, unsigned characterSize = 30);
117 
118  /**
119  * @brief Set the text's string
120  *
121  * The text string is in UTF-8 format.
122  * A text's string is empty by default.
123  *
124  * @param string New string in UTF-8 format
125  *
126  * @sa getString()
127  */
128  void setString(std::string string);
129 
130  /**
131  * @brief Get the text's string
132  *
133  * The text string is in UTF-8 format.
134  *
135  * @return Text's string
136  *
137  * @sa setString()
138  */
139  const std::string& getString() const {
140  return m_string;
141  }
142 
143  /**
144  * @brief Set the character size
145  *
146  * The default size is 30.
147  *
148  * @param characterSize New character size, in pixels
149  *
150  * @sa getCharacterSize()
151  */
152  void setCharacterSize(unsigned characterSize);
153 
154  /**
155  * @brief Get the character size
156  *
157  * @return Size of the characters, in pixels
158  *
159  * @sa setCharacterSize()
160  */
161  unsigned getCharacterSize() const {
162  return m_characterSize;
163  }
164 
165  /**
166  * @brief Set the text's font
167  *
168  * The `font` argument refers to a font that must
169  * exist as long as the text uses it. Indeed, the text
170  * doesn't store its own copy of the font, but rather keeps
171  * a pointer to the one that you passed to this function.
172  * If the font is destroyed and the text tries to
173  * use it, the behavior is undefined.
174  *
175  * @param font New font
176  *
177  * @sa getFont()
178  */
179  void setFont(Font& font);
180 
181  /**
182  * @brief Get the text's font
183  *
184  * If the text has no font attached, a `nullptr` pointer is returned.
185  * The returned pointer is const, which means that you
186  * cannot modify the font when you get it from this function.
187  *
188  * @return Pointer to the text's font
189  *
190  * @sa setFont()
191  */
192  const Font *getFont() const {
193  return m_font;
194  }
195 
196  /**
197  * @brief Set the fill color of the text
198  *
199  * By default, the text's fill color is opaque black.
200  * Setting the fill color to a transparent color with an outline
201  * will cause the outline to be displayed in the fill area of the text.
202  *
203  * @param color New fill color of the text
204  *
205  * @sa getColor()
206  */
207  void setColor(const Color4f& color);
208 
209  /**
210  * @brief Get the fill color of the text
211  *
212  * @return Fill color of the text
213  *
214  * @sa setColor()
215  */
216  const Color4f& getColor() const {
217  return m_color;
218  }
219 
220  /**
221  * @brief Set the outline color of the text
222  *
223  * By default, the text's outline color is opaque black.
224  *
225  * @param color New outline color of the text
226  *
227  * @sa getOutlineColor()
228  */
229  void setOutlineColor(const Color4f& color);
230 
231  /**
232  * @brief Get the outline color of the text
233  *
234  * @return Outline color of the text
235  *
236  * @sa setOutlineColor()
237  */
238  const Color4f& getOutlineColor() const {
239  return m_outlineColor;
240  }
241 
242  /**
243  * @brief Set the thickness of the text's outline
244  *
245  * By default, the outline thickness is 0.
246  *
247  * @param thickness New outline thickness, in pixels
248  *
249  * @sa getOutlineThickness()
250  */
251  void setOutlineThickness(float thickness);
252 
253  /**
254  * @brief Get the outline thickness of the text
255  *
256  * @return Outline thickness of the text, in pixels
257  *
258  * @sa setOutlineThickness()
259  */
261  return m_outlineThickness;
262  }
263 
264  /**
265  * @brief Set the paragraph width for aligned text
266  *
267  * By default, the paragraph width is 0.
268  *
269  * @param paragraphWidth New paragraph width in pixels
270  * @sa getParagraphWidth()
271  */
272  void setParagraphWidth(float paragraphWidth);
273 
274  /**
275  * @brief Get the paragraph width
276  *
277  * @return Paragraph width in pixels
278  * @sa setParagraphWidth()
279  */
280  float getParagraphWidth() const {
281  return m_paragraphWidth;
282  }
283 
284  /**
285  * @brief Set the alignement of the text
286  *
287  * By default, the text is not aligned.
288  *
289  * @param align New alignement
290  * @sa getAlignment()
291  */
292  void setAlignment(Alignment align);
293 
294  /**
295  * @brief Get the alignment of the text
296  *
297  * @return Current alignment of the text
298  * @sa setAlignment()
299  */
301  return m_align;
302  }
303 
304  /**
305  * @brief Get the local bounding rectangle of the entity
306  *
307  * The returned rectangle is in local coordinates, which means
308  * that it ignores the transformations (translation, rotation,
309  * scale, ...) that are applied to the entity.
310  * In other words, this function returns the bounds of the
311  * entity in the entity's coordinate system.
312  *
313  * @return Local bounding rectangle of the entity
314  */
316  return m_bounds;
317  }
318 
319  /**
320  * @brief Set the anchor origin of the entity
321  *
322  * Compute the origin of the entity based on the local bounds and
323  * the specified anchor. Internally, this function calls
324  * `Transformable::setOrigin()`.
325  *
326  * @param anchor The anchor of the entity
327  * @sa getLocalBounds(), Transformable::setOrigin()
328  */
329  void setAnchor(Anchor anchor);
330 
331  /**
332  * @brief Create a buffer with the current geometry
333  *
334  * The geometry is uploaded in the graphics memory so that it's faster
335  * to draw.
336  *
337  * @return A buffer with the current geometry
338  */
340 
341  /**
342  * @brief Create a buffer with the current outline geometry
343  *
344  * The geometry is uploaded in the graphics memory so that it's faster
345  * to draw.
346  *
347  * @return A buffer with the current outline geometry
348  */
350 
351  virtual void draw(RenderTarget& target, RenderStates states) override;
352 
353  private:
354  void updateGeometry();
355 
356  private:
357  struct Line {
358  std::vector<std::u32string> words;
359  float indent = 0.0f;
360  float spacing = 0.0f;
361  };
362 
363  struct Paragraph {
364  std::vector<Line> lines;
365  };
366 
367  float getWordWidth(const std::u32string& word);
368 
369  std::vector<Paragraph> makeParagraphs(const std::string& str, float spaceWidth);
370 
371  private:
372  std::string m_string;
373  Font *m_font;
374  unsigned m_characterSize;
375  Color4f m_color;
376  VertexArray m_vertices;
377  RectF m_bounds;
378 
379  Color4f m_outlineColor;
380  float m_outlineThickness;
381  VertexArray m_outlineVertices;
382 
383  float m_paragraphWidth;
384  Alignment m_align;
385  };
386 
387 #ifndef DOXYGEN_SHOULD_SKIP_THIS
388 }
389 #endif
390 }
391 
392 #endif // GF_TEXT_H
Decomposed transform defined by a position, a rotation and a scale.
Definition: Transformable.h:109
void setAnchor(Anchor anchor)
Set the anchor origin of the entity.
float getOutlineThickness()
Get the outline thickness of the text.
Definition: Text.h:260
void setColor(const Color4f &color)
Set the fill color of the text.
void setFont(Font &font)
Set the text's font.
A set of primitives.
Definition: VertexArray.h:65
Text()
Default constructor.
Base class for all render targets (window, texture, ...)
Definition: RenderTarget.h:65
Define the states used for drawing to a RenderTarget.
Definition: RenderStates.h:81
const Color4f & getColor() const
Get the fill color of the text.
Definition: Text.h:216
unsigned getCharacterSize() const
Get the character size.
Definition: Text.h:161
virtual void draw(RenderTarget &target, RenderStates states) override
Draw the object to a render target.
Data in the graphics memory.
Definition: VertexBuffer.h:70
void setOutlineThickness(float thickness)
Set the thickness of the text's outline.
RectF getLocalBounds() const
Get the local bounding rectangle of the entity.
Definition: Text.h:315
Left alignement.
void setOutlineColor(const Color4f &color)
Set the outline color of the text.
void setAlignment(Alignment align)
Set the alignement of the text.
Alignment getAlignment() const
Get the alignment of the text.
Definition: Text.h:300
Graphical text that can be drawn to a render target.
Definition: Text.h:89
Centered alignment.
VertexBuffer commitGeometry() const
Create a buffer with the current geometry.
Rect< float > RectF
A float rectangle.
Definition: Rect.h:306
const std::string & getString() const
Get the text's string.
Definition: Text.h:139
void setParagraphWidth(float paragraphWidth)
Set the paragraph width for aligned text.
Definition: Action.h:34
void setString(std::string string)
Set the text's string.
Text(std::string string, Font &font, unsigned characterSize=30)
Construct the text from a string, font and size.
A character font.
Definition: Font.h:130
float getParagraphWidth() const
Get the paragraph width.
Definition: Text.h:280
Justified alignment.
const Color4f & getOutlineColor() const
Get the outline color of the text.
Definition: Text.h:238
Vector< float, 4 > Color4f
A float color vector with 4 components.
Definition: Vector.h:855
Anchor
The origin anchor of the transformable object.
Definition: Transformable.h:45
const Font * getFont() const
Get the text's font.
Definition: Text.h:192
#define GF_API
Definition: Portability.h:35
VertexBuffer commitOutlineGeometry() const
Create a buffer with the current outline geometry.
void setCharacterSize(unsigned characterSize)
Set the character size.
Right alignement.
Alignment
The alignement of the text.
Definition: Text.h:94