The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
text.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2016 by Mark de Wever <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #ifndef TEXT_HPP_INCLUDED
16 #define TEXT_HPP_INCLUDED
17 
18 #include "font_options.hpp"
19 #include "sdl/utils.hpp"
21 
22 #include <boost/noncopyable.hpp>
23 
24 #include <pango/pango.h>
25 #include <pango/pangocairo.h>
26 
27 #include <string>
28 
29 #include "sdl/image.hpp"
30 
31 #ifdef SDL_GPU
32 #include "sdl/gpu.hpp"
33 #include "sdl/image.hpp"
34 #endif
35 
36 struct language_def;
37 
38 namespace gui2 {
39  struct tpoint;
40 } // namespace gui2;
41 
42 namespace font {
43 
44 /**
45  * Escapes the markup characters in a text.
46  *
47  * The markups escaped are the ones used in the pango markup. The special
48  * characters are: @verbatim <>'"& @endverbatim
49  * The escaping is the same as for HTML.
50  *
51  * @param text The text to escape.
52  *
53  * @returns The escaped text.
54  */
56 
57 
58 // add background color and also font markup.
59 
60 /**
61  * Text class.
62  *
63  * This class stores the text to draw and uses pango with the cairo backend to
64  * render the text. See http://pango.org for more info.
65  */
66 class ttext
67  : private boost::noncopyable
68 {
69 public:
70 
71  ttext();
72 
73  ~ttext();
74 
75  /**
76  * Returns the rendered text.
77  *
78  * Before rendering it tests whether a redraw is needed and if so it first
79  * redraws the surface before returning it.
80  */
81  surface render() const;
82 
83 #ifdef SDL_GPU
84  /**
85  * Returns the rendered text as a texture.
86  *
87  * Before rendering it tests whether a redraw is needed and if so it first
88  * redraws the texture before returning it.
89  */
90  sdl::timage render_as_texture() const;
91 #endif
92 
93  /** Returns the width needed for the text. */
94  int get_width() const;
95 
96  /** Returns the height needed for the text. */
97  int get_height() const;
98 
99  /** Returns the size needed for the text. */
100  gui2::tpoint get_size() const;
101 
102  /** Has the text been truncated? */
103  bool is_truncated() const;
104 
105  /**
106  * Inserts UTF-8 text.
107  *
108  * @param offset The position to insert the text.
109  * @param text The UTF-8 text to insert.
110  *
111  * @returns The number of characters inserted.
112  */
113  unsigned insert_text(const unsigned offset, const std::string& text);
114 
115  /**
116  * Inserts a unicode char.
117  *
118  * @param offset The position to insert the char.
119  * @param unicode The character to insert.
120  *
121  * @returns True upon success, false otherwise.
122  */
123  bool insert_unicode(const unsigned offset, ucs4::char_t unicode);
124 
125  /**
126  * Inserts unicode text.
127  *
128  * @param offset The position to insert the text.
129  * @param unicode Vector with characters to insert.
130  *
131  * @returns The number of characters inserted.
132  */
133  unsigned insert_unicode(
134  const unsigned offset, const ucs4::string& unicode);
135 
136  /***** ***** ***** ***** Font flags ***** ***** ***** *****/
137 
138  /**
139  * The flags have the same values as the ones in SDL_TTF so it's easy to mix
140  * them for now. To avoid including SDL_TTF in the header they're only
141  * declared here. Once SDL_TTF is removed they can be moved in the header.
142  */
143 
144  static const unsigned STYLE_NORMAL; /**< Normal text. */
145  static const unsigned STYLE_BOLD; /**< Bold text. */
146  static const unsigned STYLE_ITALIC; /**< Italicized text. */
147  static const unsigned STYLE_UNDERLINE; /**< Underlined text. */
148 
149  /***** ***** ***** ***** Query details ***** ***** ***** *****/
150 
151  /**
152  * Gets the location for the cursor.
153  *
154  * @param column The column offset of the cursor.
155  * @param line The line offset of the cursor.
156  *
157  * @returns The position of the top of the cursor. It the
158  * requested location is out of range 0,0 is
159  * returned.
160  */
162  const unsigned column, const unsigned line = 0) const;
163 
164  /**
165  * Gets the largest collection of characters, including the token at position,
166  * and not including any characters from the delimiters set.
167  *
168  * @param position The pixel position in the text area.
169  *
170  * @returns The token containing position, and none of the
171  * delimiter characters. If position is out of bounds,
172  * it returns the empty string.
173  */
174  std::string get_token(const gui2::tpoint & position, const char * delimiters = " \n\r\t") const;
175 
176  /**
177  * Checks if position points to a character in a link in the text, returns it
178  * if so, empty string otherwise. Link-awareness must be enabled to get results.
179  * @param position The pixel position in the text area.
180  *
181  * @returns The link if one is found, the empty string otherwise.
182  */
183  std::string get_link(const gui2::tpoint & position) const;
184 
185  /**
186  * Gets the column of line of the character at the position.
187  *
188  * @param position The pixel position in the text area.
189  *
190  * @returns A point with the x value the column and the y
191  * value the line of the character found (or last
192  * character if not found.
193  */
194  gui2::tpoint get_column_line(const gui2::tpoint& position) const;
195 
196  /**
197  * Gets the length of the text in characters.
198  *
199  * The text set is UTF-8 so the length of the string might not be the length
200  * of the text.
201  */
202  size_t get_length() const { return length_; }
203 
204  /**
205  * Sets the text to render.
206  *
207  * @param text The text to render.
208  * @param markedup Should the text be rendered with pango
209  * markup. If the markup is invalid it's
210  * rendered as text without markup.
211  *
212  * @returns The status, if rendered as markup and the
213  * markup contains errors, false is returned
214  * else true.
215  */
216  bool set_text(const std::string& text, const bool markedup);
217 
218  /***** ***** ***** ***** Setters / getters ***** ***** ***** *****/
219 
220  const std::string& text() const { return text_; }
221 
223 
224  ttext& set_font_size(const unsigned font_size);
225 
226  ttext& set_font_style(const unsigned font_style);
227 
228  ttext& set_foreground_color(const Uint32 color);
229 
230  ttext& set_foreground_color(const SDL_Color color);
231 
233 
234  ttext& set_characters_per_line(const unsigned characters_per_line);
235 
236  ttext& set_maximum_height(int height, bool multiline);
237 
238  ttext& set_ellipse_mode(const PangoEllipsizeMode ellipse_mode);
239 
240  ttext &set_alignment(const PangoAlignment alignment);
241 
242  ttext& set_maximum_length(const size_t maximum_length);
243 
244  bool link_aware() const { return link_aware_; }
245 
246  ttext& set_link_aware(bool b);
247 
249 private:
250 
251  /***** ***** ***** ***** Pango variables ***** ***** ***** *****/
252  PangoContext* context_;
253  PangoLayout* layout_;
254  mutable PangoRectangle rect_;
255 
256  /** The surface to render upon used as a cache. */
257  mutable surface surface_;
258 
259 #ifdef SDL_GPU
260  mutable sdl::timage texture_;
261 #endif
262 
263  /** The text to draw (stored as UTF-8). */
265 
266  /** Is the text markedup if so the markedup render routines need to be used. */
268 
269  /** Are hyperlinks in the text marked-up, and will get_link return them. */
271 
272  /** The color to render links in. */
274 
275  /** The font family class used. */
277 
278  /** The font size to draw. */
279  unsigned font_size_;
280 
281  /** The style of the font, this is an orred mask of the font flags. */
282  unsigned font_style_;
283 
284  /** The foreground color. */
286 
287  /**
288  * The maximum width of the text.
289  *
290  * Values less or equal to 0 mean no maximum and are internally stored as
291  * -1, since that's the value pango uses for it.
292  *
293  * See @ref characters_per_line_.
294  */
296 
297  /**
298  * The number of characters per line.
299  *
300  * This can be used as an alternative of @ref maximum_width_. The user can
301  * select a number of characters on a line for wrapping. When the value is
302  * non-zero it determines the maximum width based on the average character
303  * width.
304  *
305  * If both @ref maximum_width_ and @ref characters_per_line_ are set the
306  * minimum of the two will be the maximum.
307  *
308  * @note Long lines are often harder to read, setting this value can
309  * automatically wrap on a number of characters regardless of the font
310  * size. Often 66 characters is considered the optimal value for a one
311  * column text.
312  */
314 
315  /**
316  * The maximum height of the text.
317  *
318  * Values less or equal to 0 mean no maximum and are internally stored as
319  * -1, since that's the value pango uses for it.
320  */
322 
323  /** The way too long text is shown depends on this mode. */
324  PangoEllipsizeMode ellipse_mode_;
325 
326  /** The alignment of the text. */
327  PangoAlignment alignment_;
328 
329  /** The maximum length of the text. */
331 
332  /**
333  * The text has two dirty states:
334  * - The setting of the state and the size calculations.
335  * - The rendering of the surface.
336  */
337 
338  /** The dirty state of the calculations. */
339  mutable bool calculation_dirty_;
340 
341  /** Length of the text. */
342  mutable size_t length_;
343 
344  /**
345  * Recalculates the text.
346  *
347  * When the text is recalculated the surface is dirtied.
348  *
349  * @param force Recalculate even if not dirty?
350  */
351  void recalculate(const bool force = false) const;
352 
353  /** The dirty state of the surface. */
354  mutable bool surface_dirty_;
355 
356  /**
357  * Renders the text.
358  *
359  * It will do a recalculation first so no need to call both.
360  *
361  * @param force Render even if not dirty? This parameter is
362  * also send to recalculate().
363  */
364  void rerender(const bool force = false) const;
365 
366  /**
367  * Buffer to store the image on.
368  *
369  * We use a cairo surface to draw on this buffer and then use the buffer as
370  * data source for the SDL_Surface. This means the buffer needs to be stored
371  * in the object.
372  */
373  mutable unsigned char* surface_buffer_;
374 
375  /**
376  * Creates a new buffer.
377  *
378  * If needed frees the other surface and then creates a new buffer and
379  * initializes the entire buffer with values 0.
380  *
381  * NOTE eventhough we're clearly modifying function we don't change the
382  * state of the object. The const is needed so other functions can also be
383  * marked const (those also don't change the state of the object.
384  *
385  * @param size The required size of the buffer.
386  */
387  void create_surface_buffer(const size_t size) const;
388 
389  /**
390  * Sets the markup'ed text.
391  *
392  * It tries to set the text as markup. If the markup is invalid it will try
393  * a bit harder to recover from the errors and still set the markup.
394  *
395  * @param text The text to set as markup.
396  *
397  * @returns Whether the markup was set or an
398  * unrecoverable error occurred and the text is
399  * set as plain text with an error message.
400  */
401  bool set_markup(const std::string& text);
402 
403  bool set_markup_helper(const std::string & text);
404 
405  std::string handle_token(const std::string & token) const;
406 };
407 
408 } // namespace font
409 
410 #endif
411 
Uint32 foreground_color_
The foreground color.
Definition: text.hpp:285
void create_surface_buffer(const size_t size) const
Creates a new buffer.
Definition: text.cpp:804
std::vector< char_t > string
ttext & set_alignment(const PangoAlignment alignment)
Definition: text.cpp:524
family_class
Font classes for get_font_families().
ttext & set_link_aware(bool b)
Definition: text.cpp:546
void recalculate(const bool force=false) const
Recalculates the text.
Definition: text.cpp:609
const std::string & text() const
Definition: text.hpp:220
Graphical text output.
ttext & set_font_style(const unsigned font_style)
Definition: text.cpp:418
ttext & set_maximum_length(const size_t maximum_length)
Definition: text.cpp:533
bool calculation_dirty_
The text has two dirty states:
Definition: text.hpp:339
unsigned insert_text(const unsigned offset, const std::string &text)
Inserts UTF-8 text.
Definition: text.cpp:204
bool is_truncated() const
Has the text been truncated?
Definition: text.cpp:197
ttext & set_font_size(const unsigned font_size)
Definition: text.cpp:406
PangoLayout * layout_
Definition: text.hpp:253
gui2::tpoint get_column_line(const gui2::tpoint &position) const
Gets the column of line of the character at the position.
Definition: text.cpp:326
bool markedup_text_
Is the text markedup if so the markedup render routines need to be used.
Definition: text.hpp:267
ttext & set_maximum_width(int width)
Definition: text.cpp:446
ttext & set_link_color(const std::string &color)
Definition: text.cpp:556
bool surface_dirty_
The dirty state of the surface.
Definition: text.hpp:354
PangoAlignment alignment_
The alignment of the text.
Definition: text.hpp:327
A class inherited from ttext_box that displays its input as stars.
Definition: field-fwd.hpp:23
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
GLintptr offset
Definition: glew.h:1650
std::string link_color_
The color to render links in.
Definition: text.hpp:273
unsigned characters_per_line_
The number of characters per line.
Definition: text.hpp:313
int get_height() const
Returns the height needed for the text.
Definition: text.cpp:185
bool set_markup(const std::string &text)
Sets the markup'ed text.
Definition: text.cpp:816
std::string get_link(const gui2::tpoint &position) const
Checks if position points to a character in a link in the text, returns it if so, empty string otherw...
Definition: text.cpp:311
bool link_aware() const
Definition: text.hpp:244
ttext & set_maximum_height(int height, bool multiline)
Definition: text.cpp:491
size_t get_length() const
Gets the length of the text in characters.
Definition: text.hpp:202
gui2::tpoint get_size() const
Returns the size needed for the text.
Definition: text.cpp:190
font::family_class font_class_
The font family class used.
Definition: text.hpp:276
static const unsigned STYLE_BOLD
Bold text.
Definition: text.hpp:145
gui2::tpoint get_cursor_position(const unsigned column, const unsigned line=0) const
Gets the location for the cursor.
Definition: text.cpp:235
int maximum_height_
The maximum height of the text.
Definition: text.hpp:321
ttext & set_characters_per_line(const unsigned characters_per_line)
Definition: text.cpp:479
void rerender(const bool force=false) const
Renders the text.
Definition: text.cpp:745
bool link_aware_
Are hyperlinks in the text marked-up, and will get_link return them.
Definition: text.hpp:270
static const unsigned STYLE_ITALIC
Italicized text.
Definition: text.hpp:146
unsigned font_style_
The style of the font, this is an orred mask of the font flags.
Definition: text.hpp:282
PangoRectangle rect_
Definition: text.hpp:254
GLuint color
Definition: glew.h:5801
static const unsigned STYLE_NORMAL
The flags have the same values as the ones in SDL_TTF so it's easy to mix them for now...
Definition: text.hpp:144
GLenum GLenum GLvoid GLvoid * column
Definition: glew.h:3805
std::string escape_text(const std::string &text)
Escapes the markup characters in a text.
Definition: text.cpp:75
std::string get_token(const gui2::tpoint &position, const char *delimiters=" \n\r\t") const
Gets the largest collection of characters, including the token at position, and not including any cha...
Definition: text.cpp:279
surface render() const
Returns the rendered text.
Definition: text.cpp:166
std::string handle_token(const std::string &token) const
Definition: text.cpp:847
surface surface_
The surface to render upon used as a cache.
Definition: text.hpp:257
Contains a wrapper class for the GPU_Image class.
boost::uint32_t char_t
Holds a 2D point.
Definition: point.hpp:24
bool insert_unicode(const unsigned offset, ucs4::char_t unicode)
Inserts a unicode char.
Definition: text.cpp:224
PangoContext * context_
Definition: text.hpp:252
GLint GLint GLint GLint GLint GLint GLsizei GLsizei height
Definition: glew.h:1220
unsigned char * surface_buffer_
Buffer to store the image on.
Definition: text.hpp:373
GLsizeiptr size
Definition: glew.h:1649
unsigned font_size_
The font size to draw.
Definition: text.hpp:279
ttext & set_family_class(font::family_class fclass)
Definition: text.cpp:395
int get_width() const
Returns the width needed for the text.
Definition: text.cpp:180
int maximum_width_
The maximum width of the text.
Definition: text.hpp:295
bool set_text(const std::string &text, const bool markedup)
Sets the text to render.
Definition: text.cpp:360
GLint GLint GLint GLint GLint GLint GLsizei width
Definition: glew.h:1220
PangoEllipsizeMode ellipse_mode_
The way too long text is shown depends on this mode.
Definition: text.hpp:324
std::string text_
The text to draw (stored as UTF-8).
Definition: text.hpp:264
bool set_markup_helper(const std::string &text)
Definition: text.cpp:856
const int font_size
size_t maximum_length_
The maximum length of the text.
Definition: text.hpp:330
static const unsigned STYLE_UNDERLINE
Underlined text.
Definition: text.hpp:147
GLsizei const GLcharARB ** string
Definition: glew.h:4503
Text class.
Definition: text.hpp:66
size_t length_
Length of the text.
Definition: text.hpp:342
ttext & set_ellipse_mode(const PangoEllipsizeMode ellipse_mode)
Definition: text.cpp:510
ttext & set_foreground_color(const Uint32 color)
Definition: text.cpp:429