1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef GRAPHICS_FONT_H
24 #define GRAPHICS_FONT_H
25 
26 #include "common/str.h"
27 #include "common/ustr.h"
28 #include "common/rect.h"
29 
30 namespace Common {
31 template<class T> class Array;
32 }
33 
34 namespace Graphics {
35 
36 /**
37  * @defgroup graphics_font Fonts
38  * @ingroup graphics
39  *
40  * @brief API for representing and managing fonts on the screen.
41  *
42  * @{
43  */
44 
45 struct Surface;
46 class ManagedSurface;
47 
48 /** Text alignment modes. */
49 enum TextAlign {
50 	kTextAlignInvalid,  ///< Indicates invalid alignment.
51 	kTextAlignStart,    ///< Align the text to start of line (virtual).
52 	kTextAlignLeft,     ///< Align the text to the left.
53 	kTextAlignCenter,   ///< Center the text.
54 	kTextAlignEnd,      ///< Align the text to end of line (virtual).
55 	kTextAlignRight     ///< Align the text to the right.
56 };
57 
58 /** Word wrapping modes. */
59 enum WordWrapMode {
60 	kWordWrapDefault			= 0,		///< Default wrapping mode.
61 	kWordWrapEvenWidthLines 	= 1 << 0,	///< Make the resulting line segments close to the same width.
62 	kWordWrapOnExplicitNewLines	= 1 << 1	///< Text is wrapped on new lines. Otherwise, treats them as single whitespace.
63 };
64 
65 /**
66  * Convert virtual text alignments (start + end)
67  * to actual text alignment (left + right + center) for drawing.
68  *
69  * If actual text alignment is provided, it is returned as-is.
70  *
71  * @param alignH  The horizontal alignment to convert.
72  * @param rtl     Indicates whether this is an RTL (right-to-left) language (such as Hebrew),
73  *                or a left-to-right language (such as English).
74  */
75 TextAlign convertTextAlignH(TextAlign alignH, bool rtl);
76 
77 /**
78  * Instances of this class represent a distinct font, with a built-in renderer.
79  *
80  * @todo Maybe move the high-level methods (drawString etc.) to a separate
81  *       FontRenderer class? That way, we could have different variants... ?
82  */
83 class Font {
84 public:
Font()85 	Font() {}
~Font()86 	virtual ~Font() {}
87 
88 	/**
89 	 * Return the height of the font.
90 	 *
91 	 * @return Font height in pixels.
92 	 */
93 	virtual int getFontHeight() const = 0;
94 
95 	/**
96 	 * Return the ascent of the font.
97 	 *
98 	 * @return Font ascent in pixels. If it is unknown
99 	 * a value of -1 is returned.
100 	 */
101 	virtual int getFontAscent() const;
102 
103 	/**
104 	 * Return the maximum width of the font.
105 	 *
106 	 * @return Maximum font width in pixels.
107 	 */
108 	virtual int getMaxCharWidth() const = 0;
109 
110 	/**
111 	 * Return the width of a specific character.
112 	 *
113 	 * @param chr  The character to query the width of.
114 	 *
115 	 * @return The width of the character in pixels.
116 	 */
117 	virtual int getCharWidth(uint32 chr) const = 0;
118 
119 	/**
120 	 * Query the kerning offset between two characters.
121 	 *
122 	 * @param left   Left character. Can be 0.
123 	 * @param right  Right character. Can be 0.
124 	 *
125 	 * @return The horizontal displacement.
126 	 */
127 	virtual int getKerningOffset(uint32 left, uint32 right) const;
128 
129 	/**
130 	 * Calculate the bounding box of a character.
131 	 *
132 	 * It is assumed that the character shall be drawn at position (0, 0).
133 	 *
134 	 * The idea here is that the character might be drawn outside the
135 	 * rect (0, 0) to (getCharWidth(chr), getFontHeight()) for some fonts.
136 	 * This is common among TTF fonts.
137 	 *
138 	 * The default implementation simply returns the rect with a width
139 	 * of getCharWidth(chr) and height of getFontHeight().
140 	 *
141 	 * @param chr  The character to draw.
142 	 *
143 	 * @return The bounding box of the drawn glyph.
144 	 */
145 	virtual Common::Rect getBoundingBox(uint32 chr) const;
146 
147 	/**
148 	 * Return the bounding box of a string drawn with drawString.
149 	 *
150 	 * @param str     The drawn string.
151 	 * @param x       The x position where to start drawing.
152 	 * @param y       The y position where to start drawing.
153 	 * @param w       Width of the text area. This can be 0 to allow for
154 	 *                obtaining the whole bounding box for a string. Note that this
155 	 *                does not work with an align different than kTextAlignLeft or
156 	 *                with @p useEllipsis.
157 	 * @param align   Text alignment. This can be used to center a string
158 	 *                in the given area or to align it to the right.
159 	 * @param deltax  Offset to the x starting position of the string.
160 	 * @param useEllipsis  Try to fit the string in the area by inserting an
161 	 *                     ellipsis. Note that the default value is false for this
162 	 *                     argument, unlike for drawString.
163 	 *
164 	 * @return The actual area where the string is drawn.
165 	 */
166 	Common::Rect getBoundingBox(const Common::String &str, int x = 0, int y = 0, const int w = 0, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = false) const;
167 	/** @overload */
168 	Common::Rect getBoundingBox(const Common::U32String &str, int x = 0, int _y = 0, const int w = 0, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = false) const;
169 
170 	/**
171 	 * Draw a character at a specific point on the surface.
172 	 *
173 	 * Note that the point describes the top left edge point where to draw
174 	 * the character. This can be different from the top left edge point of the
175 	 * character's bounding box. For example, TTF fonts sometimes move
176 	 * characters like 't' by one (or more) pixels to the left to create better
177 	 * visual results. To query the actual bounding box of a character, use
178 	 * getBoundingBox.
179 	 * @see getBoundingBox
180 	 *
181 	 * The Font implementation should take care of not drawing outside of the
182 	 * specified surface.
183 	 *
184 	 * @param dst   The surface to draw on.
185 	 * @param chr   The character to draw.
186 	 * @param x     The x coordinate where to draw the character.
187 	 * @param y     The y coordinate where to draw the character.
188 	 * @param color The color of the character.
189 	 */
190 	virtual void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const = 0;
191 	virtual void drawChar(ManagedSurface *dst, uint32 chr, int x, int y, uint32 color) const;
192 
193 	/** @overload */
194 
195 	/**
196 	 * Draw the given @p str string to the given @p dst surface.
197 	 *
198 	 * @param dst     The surface on which to draw the string.
199 	 * @param str     The string to draw.
200 	 * @param x       The x position where to start drawing.
201 	 * @param y       The y position where to start drawing.
202 	 * @param w       Width of the text area.
203 	 * @param color   The color with which to draw the string.
204 	 * @param align   Text alignment. This can be used to center the string in the given area or to align it to the right.
205 	 * @param deltax  Offset to the x starting position of the string.
206 	 * @param useEllipsis  Use ellipsis if needed to fit the string in the area.
207 	 *
208 	 */
209 	void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = false) const;
210 	/** @overload */
211 	void drawString(Surface *dst, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = false) const;
212 	/** @overload */
213 	void drawString(ManagedSurface *dst, const Common::String &str, int x, int _y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = false) const;
214 	/** @overload */
215 	void drawString(ManagedSurface *dst, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = false) const;
216 
217 	/**
218 	 * Compute and return the width of the string @p str when rendered using this font.
219 	 *
220 	 * This describes the logical width of the string when drawn at (0, 0).
221 	 * This can be different from the actual bounding box of the string. Use
222 	 * getBoundingBox when you need the bounding box of a drawn string.
223 	 * @see getBoundingBox
224 	 * @see drawChar
225 	 */
226 	int getStringWidth(const Common::String &str) const;
227 	/** @overload */
228 	int getStringWidth(const Common::U32String &str) const;
229 
230 	/**
231 	 * Word-wrap a text (that can contain newline characters) so that
232 	 * no text line is wider than @p maxWidth pixels.
233 	 *
234 	 * If necessary, additional line breaks are generated, preferably between
235 	 * words, where whitespace is. The resulting lines are appended
236 	 * to the @p lines string list. This returns the maximal width of any of the new
237 	 * lines (i.e. a value that is smaller or equal to maxWidth).
238 	 *
239 	 * @param str        The string to word-wrap.
240 	 * @param maxWidth   Maximum width that a line can have.
241 	 * @param lines      The string list to which the text lines from @p str are appended.
242 	 * @param initWidth  Starting width of the first line, for partially filled lines (optional).
243 	 * @param mode		 Wrapping mode. A bitfield of @c WordWrapMode values.
244 	 *
245 	 * @return The maximal width of any of the lines added to @p lines.
246 	 */
247 	int wordWrapText(const Common::String &str, int maxWidth, Common::Array<Common::String> &lines, int initWidth = 0, uint32 mode = kWordWrapOnExplicitNewLines) const;
248 	/** @overload */
249 	int wordWrapText(const Common::U32String &str, int maxWidth, Common::Array<Common::U32String> &lines, int initWidth = 0, uint32 mode = kWordWrapOnExplicitNewLines) const;
250 };
251 /** @} */
252 } // End of namespace Graphics
253 
254 #endif
255