00001 /* $Id: text.hpp 54037 2012-04-30 19:37:20Z mordante $ */ 00002 /* 00003 Copyright (C) 2008 - 2012 by Mark de Wever <koraq@xs4all.nl> 00004 Part of the Battle for Wesnoth Project http://www.wesnoth.org/ 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY. 00012 00013 See the COPYING file for more details. 00014 */ 00015 00016 #ifndef TEXT_HPP_INCLUDED 00017 #define TEXT_HPP_INCLUDED 00018 00019 #include "sdl_utils.hpp" 00020 00021 #include <boost/noncopyable.hpp> 00022 00023 #include <pango/pango.h> 00024 #include <pango/pangocairo.h> 00025 00026 #include <string> 00027 00028 struct language_def; 00029 00030 namespace gui2 { 00031 struct tpoint; 00032 } // namespace gui2; 00033 00034 namespace font { 00035 00036 /** 00037 * Escapses the markup characters in a text. 00038 * 00039 * The markups escaped are the ones used in the pango markup. The special 00040 * characters are @code <>'"&@endcode. They escaping is the same as for HTML. 00041 * 00042 * @param text The text to escape. 00043 * 00044 * @returns The escaped text. 00045 */ 00046 std::string escape_text(const std::string& text); 00047 00048 00049 // add background color and also font markup. 00050 00051 /** 00052 * Text class. 00053 * 00054 * This class stores the text to draw and uses pango with the cairo backend to 00055 * render the text. See http://pango.org for more info. 00056 */ 00057 class ttext 00058 : private boost::noncopyable 00059 { 00060 public: 00061 00062 ttext(); 00063 00064 ~ttext(); 00065 00066 /** 00067 * Returns the rendered text. 00068 * 00069 * Before rendering it tests whether a redraw is needed and if so it first 00070 * redraws the surface before returning it. 00071 */ 00072 surface render() const; 00073 00074 /** Returns the width needed for the text. */ 00075 int get_width() const; 00076 00077 /** Returns the height needed for the text. */ 00078 int get_height() const; 00079 00080 /** Returns the size needed for the text. */ 00081 gui2::tpoint get_size() const; 00082 00083 /** Has the text been truncated? */ 00084 bool is_truncated() const; 00085 00086 /** 00087 * Inserts utf 8 text. 00088 * 00089 * @param offset The position to insert the text. 00090 * @param text The utf-8 text to insert. 00091 * 00092 * @returns The number of characters inserted. 00093 */ 00094 unsigned insert_text(const unsigned offset, const std::string& text); 00095 00096 /** 00097 * Inserts a unicode char. 00098 * 00099 * @param offset The position to insert the char. 00100 * @param unicode The character to insert. 00101 * 00102 * @returns True upon success, false otherwise. 00103 */ 00104 bool insert_unicode(const unsigned offset, const wchar_t unicode); 00105 00106 /** 00107 * Inserts unicode text. 00108 * 00109 * @param offset The position to insert the text. 00110 * @param unicode Vector with characters to insert. 00111 * 00112 * @returns The number of characters inserted. 00113 */ 00114 unsigned insert_unicode( 00115 const unsigned offset, const std::vector<wchar_t>& unicode); 00116 00117 /***** ***** ***** ***** Font flags ***** ***** ***** *****/ 00118 00119 /** 00120 * The flags have the same values as the ones in SDL_TTF so it's easy to mix 00121 * them for now. To avoid including SDL_TTF in the header they're only 00122 * declared here. Once SDL_TTF is removed they can be moved in the header. 00123 */ 00124 00125 static const unsigned STYLE_NORMAL; /**< Normal text. */ 00126 static const unsigned STYLE_BOLD; /**< Bold text. */ 00127 static const unsigned STYLE_ITALIC; /**< Italicized text. */ 00128 static const unsigned STYLE_UNDERLINE; /**< Underlined text. */ 00129 00130 /***** ***** ***** ***** Query details ***** ***** ***** *****/ 00131 00132 /** 00133 * Gets the location for the cursor. 00134 * 00135 * @param column The column offset of the cursor. 00136 * @param line The line offset of the cursor. 00137 * 00138 * @returns The position of the top of the cursor. It the 00139 * requested location is out of range 0,0 is 00140 * returned. 00141 */ 00142 gui2::tpoint get_cursor_position( 00143 const unsigned column, const unsigned line = 0) const; 00144 00145 /** 00146 * Gets the column of line of the character at the position. 00147 * 00148 * @param position The pixel position in the text area. 00149 * 00150 * @returns A point with the x value the column and the y 00151 * value the line of the character found (or last 00152 * character if not found. 00153 */ 00154 gui2::tpoint get_column_line(const gui2::tpoint& position) const; 00155 00156 /** 00157 * Gets the length of the text in characters. 00158 * 00159 * The text set is utf-8 so the length of the string might not be the length 00160 * of the text. 00161 */ 00162 size_t get_length() const { return length_; } 00163 00164 /** 00165 * Sets the text to render. 00166 * 00167 * @param text The text to render. 00168 * @param markedup Should the text be rendered with pango 00169 * markup. If the markup is invalid it's 00170 * rendered as text without markup. 00171 * 00172 * @returns The status, if rendered as markup and the 00173 * markup contains errors, false is returned 00174 * else true. 00175 */ 00176 bool set_text(const std::string& text, const bool markedup); 00177 00178 /***** ***** ***** ***** Setters / getters ***** ***** ***** *****/ 00179 00180 const std::string& text() const { return text_; } 00181 00182 ttext& set_font_size(const unsigned font_size); 00183 00184 ttext& set_font_style(const unsigned font_style); 00185 00186 ttext& set_foreground_color(const Uint32 color); 00187 00188 ttext& set_maximum_width(int width); 00189 00190 ttext& set_characters_per_line(const unsigned characters_per_line); 00191 00192 ttext& set_maximum_height(int height, bool multiline = true); 00193 00194 ttext& set_ellipse_mode(const PangoEllipsizeMode ellipse_mode); 00195 00196 ttext &set_alignment(const PangoAlignment alignment); 00197 00198 ttext& set_maximum_length(const size_t maximum_length); 00199 00200 private: 00201 00202 /***** ***** ***** ***** Pango variables ***** ***** ***** *****/ 00203 PangoContext* context_; 00204 PangoLayout* layout_; 00205 mutable PangoRectangle rect_; 00206 00207 /** The surface to render upon used as a cache. */ 00208 mutable surface surface_; 00209 00210 /** The text to draw (stored as utf-8). */ 00211 std::string text_; 00212 00213 /** Is the text markedup if so the markedup render routines need to be used. */ 00214 bool markedup_text_; 00215 00216 /** The font size to draw. */ 00217 unsigned font_size_; 00218 00219 /** The style of the font, this is an orred mask of the font flags. */ 00220 unsigned font_style_; 00221 00222 /** The foreground color. */ 00223 Uint32 foreground_color_; 00224 00225 /** 00226 * The maximum width of the text. 00227 * 00228 * Values less or equal to 0 mean no maximum and are internally stored as 00229 * -1, since that's the value pango uses for it. 00230 * 00231 * @see @ref characters_per_line_. 00232 */ 00233 int maximum_width_; 00234 00235 /** 00236 * The number of characters per line. 00237 * 00238 * This can be used as an alternative of @ref maximum_width_. The user can 00239 * select a number of characters on a line for wrapping. When the value is 00240 * non-zero it determines the maximum width based on the average character 00241 * width. 00242 * 00243 * If both @ref maximum_width_ and @ref characters_per_line_ are set the 00244 * minimum of the two will be the maximum. 00245 * 00246 * @note Long lines are often harder to read, setting this value can 00247 * automatically wrap on a number of characters regardless of the font 00248 * size. Often 66 characters is considered the optimal value for a one 00249 * column text. 00250 */ 00251 unsigned characters_per_line_; 00252 00253 /** 00254 * The maximum height of the text. 00255 * 00256 * Values less or equal to 0 mean no maximum and are internally stored as 00257 * -1, since that's the value pango uses for it. 00258 */ 00259 int maximum_height_; 00260 00261 /** The way too long text is shown depends on this mode. */ 00262 PangoEllipsizeMode ellipse_mode_; 00263 00264 /** The alinment of the text. */ 00265 PangoAlignment alignment_; 00266 00267 /** The maximum length of the text. */ 00268 size_t maximum_length_; 00269 00270 /** 00271 * The text has two dirty states: 00272 * - The setting of the state and the size calculations. 00273 * - The rendering of the surface. 00274 */ 00275 00276 /** The dirty state of the calculations. */ 00277 mutable bool calculation_dirty_; 00278 00279 /** Length of the text. */ 00280 mutable size_t length_; 00281 00282 /** 00283 * Recalculates the text. 00284 * 00285 * When the text is recalculated the surface is dirtied. 00286 * 00287 * @param force Recalculate even if not dirty? 00288 */ 00289 void recalculate(const bool force = false) const; 00290 00291 /** The dirty state of the surface. */ 00292 mutable bool surface_dirty_; 00293 00294 /** 00295 * Renders the text. 00296 * 00297 * It will do a recalculation first so no need to call both. 00298 * 00299 * @param force Render even if not dirty? This parameter is 00300 * also send to recalculate(). 00301 */ 00302 void rerender(const bool force = false) const; 00303 00304 /** 00305 * Buffer to store the image on. 00306 * 00307 * We use a cairo surface to draw on this buffer and then use the buffer as 00308 * data source for the SDL_Surface. This means the buffer needs to be stored 00309 * in the object. 00310 */ 00311 mutable unsigned char* surface_buffer_; 00312 00313 /** 00314 * Creates a new buffer. 00315 * 00316 * If needed frees the other surface and then creates a new buffer and 00317 * initializes the entire buffer with values 0. 00318 * 00319 * NOTE eventhough we're clearly modifying function we don't change the 00320 * state of the object. The const is needed so other functions can also be 00321 * marked const (those also don't change the state of the object. 00322 * 00323 * @param size The required size of the buffer. 00324 */ 00325 void create_surface_buffer(const size_t size) const; 00326 00327 /** 00328 * Sets the markup'ed text. 00329 * 00330 * It tries to set the text as markup. If the markup is invalid it will try 00331 * a bit harder to recover from the errors and still set the markup. 00332 * 00333 * @param text The text to set as markup. 00334 * 00335 * @returns Whether the markup was set or an 00336 * unrecoverable error occurred and the text is 00337 * set as plain text with an error message. 00338 */ 00339 bool set_markup(const std::string& text); 00340 00341 }; 00342 00343 } // namespace font 00344 00345 #endif 00346
| Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:00 for The Battle for Wesnoth | Gna! | Forum | Wiki | CIA | devdocs |