text.hpp

Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:00 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs