xoreos  0.0.5
text.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos 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 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos 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 xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include "src/events/requests.h"
26 
27 #include "src/graphics/font.h"
28 
31 
32 namespace Graphics {
33 
34 namespace Aurora {
35 
36 Text::Text(const FontHandle &font, const Common::UString &str,
37  float r, float g, float b, float a, float halign, float valign) :
38  Graphics::GUIElement(Graphics::GUIElement::kGUIElementFront),
39  _r(r), _g(g), _b(b), _a(a), _font(font), _x(0.0f), _y(0.0f), _halign(halign),_valign(valign),
40  _disableColorTokens(false) {
41 
42  set(str);
43 
44  _distance = -FLT_MAX;
45 }
46 
47 Text::Text(const FontHandle &font, float w, float h, const Common::UString &str,
48  float r, float g, float b, float a, float halign, float valign) :
49  Graphics::GUIElement(Graphics::GUIElement::kGUIElementFront), _r(r), _g(g), _b(b), _a(a),
50  _font(font), _x(0.0f), _y(0.0f), _halign(halign),_valign(valign),
51  _disableColorTokens(false) {
52 
53  _width = roundf(w);
54  _height = roundf(h);
55 
56  setText(str);
57 
58  _distance = -FLT_MAX;
59 }
60 
61 Text::Text(Graphics::GUIElement::GUIElementType type, const FontHandle &font, float w, float h, const Common::UString &str,
62  float r, float g, float b, float a, float halign, float valign) :
63  Graphics::GUIElement(type), _r(r), _g(g), _b(b), _a(a),
64  _font(font), _x(0.0f), _y(0.0f), _halign(halign),_valign(valign),
65  _disableColorTokens(false) {
66 
67  _width = roundf(w);
68  _height = roundf(h);
69 
70  setText(str);
71 
72  _distance = -FLT_MAX;
73 }
74 
76  hide();
77 }
78 
79 void Text::disableColorTokens(bool disabled) {
80  _disableColorTokens = disabled;
81 }
82 
83 void Text::set(const Common::UString &str, float maxWidth, float maxHeight) {
85 
87  parseColors(str, _str, _colors);
88  else
89  _str = str;
90 
91  Font &font = _font.getFont();
92 
93  font.buildChars(str);
94 
95  _lineCount = font.getLineCount(_str, maxWidth, maxHeight);
96 
97  _height = font.getHeight(_str, maxWidth, maxHeight);
98  _width = font.getWidth (_str, maxWidth);
99 
101 }
102 
103 void Text::setText(const Common::UString &str) {
105 
106  if (!_disableColorTokens)
107  parseColors(str, _str, _colors);
108  else
109  _str = str;
110 
111  Font &font = _font.getFont();
112 
113  font.buildChars(str);
114 
116 
118 }
119 
120 void Text::getColor(float& r, float& g, float& b, float& a) const {
121  r = _r;
122  g = _g;
123  b = _b;
124  a = _a;
125 }
126 
127 void Text::setColor(float r, float g, float b, float a) {
129 
130  _r = r;
131  _g = g;
132  _b = b;
133  _a = a;
134 
136 }
137 
139  setColor(1.0f, 1.0f, 1.0f, 1.0f);
140 }
141 
143  return _halign;
144 }
145 
146 void Text::setHorizontalAlign(float halign) {
147  _halign = halign;
148 }
149 
150 float Text::getVerticalAlign() const {
151  return _valign;
152 }
153 
154 void Text::setVerticalAlign(float valign) {
155  _valign = valign;
156 }
157 
158 const Common::UString &Text::get() const {
159  return _str;
160 }
161 
163  return _font.getName();
164 }
165 
166 void Text::getPosition(float &x, float &y, float &z) const {
167  x = _x;
168  y = _y;
169  z = _distance;
170 }
171 
172 void Text::setPosition(float x, float y, float z) {
174 
175  _x = roundf(x);
176  _y = roundf(y);
177 
178  _distance = z;
179  resort();
180 
182 }
183 
184 void Text::setSize(float width, float height) {
186 
187  _width = roundf(width);
188  _height = roundf(height);
189 
191 
193 }
194 
195 bool Text::empty() {
196  return _str.empty();
197 }
198 
199 float Text::getHeight(const Common::UString &text) const {
200  return _font.getFont().getHeight(text, _width);
201 }
202 
203 size_t Text::getLineCount() const {
204  return _lineCount;
205 }
206 
207 float Text::getWidth() const {
208  return _width;
209 }
210 
211 float Text::getHeight() const {
212  return _height;
213 }
214 
216 }
217 
219  // Text objects should always be transparent
220  if (pass == kRenderPassOpaque)
221  return;
222 
223  Font &font = _font.getFont();
224  float lineHeight = font.getHeight() + font.getLineSpacing();
225 
226  glTranslatef(_x, _y, 0.0f);
227 
228  glColor4f(_r, _g, _b, _a);
229 
230  std::vector<Common::UString> lines;
231  font.split(_str, lines, _width, _height, false);
232 
233  float blockSize = lines.size() * lineHeight;
234 
235  // Move position to the top
236  glTranslatef(0.0f, roundf(((_height - blockSize) * _valign) + blockSize - lineHeight), 0.0f);
237 
238  size_t position = 0;
239 
240  ColorPositions::const_iterator color = _colors.begin();
241 
242  // Draw lines
243  for (std::vector<Common::UString>::iterator l = lines.begin(); l != lines.end(); ++l) {
244  // Save the current position
245  glPushMatrix();
246 
247  drawLine(*l, color, position);
248 
249  // Restore position to the start of the line
250  glPopMatrix();
251 
252  // Move to the next line
253  glTranslatef(0.0f, -lineHeight, 0.0f);
254 
255  // \n character
256  position++;
257  }
258 
259  glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
260 }
261 
262 bool Text::isIn(float x, float y) const {
263  if ((x < _x) || (y < _y))
264  return false;
265 
266  if ((x > (_x + _width)) || (y > (_y + _height)))
267  return false;
268 
269  return true;
270 }
271 
272 void Text::renderImmediate(const glm::mat4 &parentTransform)
273 {
274  Font &font = _font.getFont();
275  float lineHeight = font.getHeight() + font.getLineSpacing();
276 
277  std::vector<Common::UString> lines;
278  font.split(_str, lines, _width, _height, false);
279 
280  float blockSize = lines.size() * lineHeight;
281 
282  // Move position to the top
283  size_t position = 0;
284 
285  ColorPositions::const_iterator color = _colors.begin();
286 
287  _font.getFont().renderBind(parentTransform);
288  float x = _x;
289  float y = _y + roundf(((_height - blockSize) * _valign) + blockSize - lineHeight);
290  // Draw lines
291  for (std::vector<Common::UString>::iterator l = lines.begin(); l != lines.end(); ++l) {
292  float saved_x = x;
293  float saved_y = y;
294  drawLineImmediate(*l, color, position, x, y);
295  x = saved_x;
296  y = saved_y - lineHeight;
297  // \n character
298  position++;
299  }
301 }
302 
304  ColorPositions &colors) {
305 
306  parsed.clear();
307  colors.clear();
308 
309  ColorPosition color;
310 
311  // Split by text tokens. They will have a strictly interleaving plain/token order
312  std::vector<Common::UString> tokens;
314 
315  bool plain = false;
316  for (std::vector<Common::UString>::iterator t = tokens.begin(); t != tokens.end(); ++t) {
317  plain = !plain;
318 
319  if (plain) {
320  // Plain text, add it verbatim
321 
322  parsed += *t;
323  continue;
324  }
325 
326  if ((t->size() == 11) && t->beginsWith("<c") && t->endsWith(">")) {
327  // Color start token
328 
329  uint8 colorValue[4];
330 
332 
333  // Skip "<c"
334  ++it;
335  ++it;
336 
337  for (int i = 0; i < 8; i++, ++it) {
338  uint32 c = *it;
339 
340  // Convert the hex values into true nibble values
341  if ((c >= '0') && (c <= '9'))
342  c = c - '0';
343  else if ((c >= 'A') && (c <= 'F'))
344  c = (c - 'A') + 10;
345  else if ((c >= 'f') && (c <= 'f'))
346  c = (c - 'a') + 10;
347  else
348  c = 15;
349 
350  // Merge two nibbles into one color value byte
351  uint8 &value = colorValue[i / 2];
352  bool high = (i % 2) == 0;
353 
354  if (high)
355  value = c << 4;
356  else
357  value |= c;
358  }
359 
360  // Add the color change
361 
362  color.position = parsed.size();
363  color.defaultColor = false;
364 
365  color.r = colorValue[0] / 255.0f;
366  color.g = colorValue[1] / 255.0f;
367  color.b = colorValue[2] / 255.0f;
368  color.a = colorValue[3] / 255.0f;
369 
370  colors.push_back(color);
371 
372  } else if (*t == "</c>") {
373  // Color end token, add a "uncolor" / default color change
374 
375  color.position = parsed.size();
376  color.defaultColor = true;
377 
378  colors.push_back(color);
379 
380  } else
381  // Ignore non-color tokens
382  parsed += *t;
383 
384  }
385 }
386 
387 void Text::setFont(const Common::UString &fnt) {
388  _font = FontMan.get(fnt);
389 }
390 
392  ColorPositions::const_iterator color,
393  size_t position) {
394 
395  Font &font = _font.getFont();
396 
397  // Horizontal Align
398  glTranslatef(roundf((_width - font.getLineWidth(line)) * _halign), 0.0f, 0.0f);
399 
400  // Draw line
401  for (Common::UString::iterator s = line.begin(); s != line.end(); ++s, position++) {
402  // If we have color changes, apply them
403  while ((color != _colors.end()) && (color->position <= position)) {
404  if (color->defaultColor)
405  glColor4f(_r, _g, _b, _a);
406  else
407  glColor4f(color->r, color->g, color->b, color->a);
408 
409  ++color;
410  }
411 
412  font.draw(*s);
413  }
414 
415 }
416 
418  ColorPositions::const_iterator color,
419  size_t position,
420  float &x,
421  float &y) {
422 
423  Font &font = _font.getFont();
424 
425  // Horizontal Align
426  x += round((_width - font.getLineWidth(line)) * _halign);
427 
428  // Draw line
429  float rgba[] = { _r, _g, _b, _a };
430  for (Common::UString::iterator s = line.begin(); s != line.end(); ++s, position++) {
431  // If we have color changes, apply them
432  while ((color != _colors.end()) && (color->position <= position)) {
433  if (color->defaultColor) {
434  rgba[0] = _r;
435  rgba[1] = _g;
436  rgba[2] = _b;
437  rgba[3] = _a;
438  } else {
439  rgba[0] = color->r;
440  rgba[1] = color->g;
441  rgba[2] = color->b;
442  rgba[3] = color->a;
443  }
444 
445  ++color;
446  }
447  font.render(*s, x, y, rgba);
448  }
449 }
450 
451 } // End of namespace Aurora
452 
453 } // End of namespace Graphics
float getHorizontalAlign() const
Definition: text.cpp:142
ColorPositions _colors
Definition: text.h:110
Inter-thread request events.
float getWidth() const
Definition: text.cpp:207
virtual void hide()
Hide the object.
Definition: renderable.cpp:123
A class holding an UTF-8 string.
Definition: ustring.h:48
virtual void draw(uint32 c) const =0
Draw this character.
double _distance
The distance of the object from the viewer.
Definition: renderable.h:101
bool _disableColorTokens
Definition: text.h:112
uint8_t uint8
Definition: types.h:200
float getLineWidth(const Common::UString &text) const
Return the width of this string.
Definition: font.cpp:257
virtual float getLineSpacing() const
Return the size of space between lines.
Definition: font.cpp:39
A handle to a font.
Definition: fonthandle.h:52
A text object.
size_t getLineCount(const Common::UString &text, float maxWidth=0.0f, float maxHeight=0.0f) const
Return the number of lines this text spans.
Definition: font.cpp:43
void disableColorTokens(bool disabled)
Disable parsing <c color tokens into actual coloring.
Definition: text.cpp:79
float split(const Common::UString &line, std::vector< Common::UString > &lines, float maxWidth=0.0f, float maxHeight=0.0f, bool trim=true) const
Definition: font.cpp:69
void drawLineImmediate(const Common::UString &line, ColorPositions::const_iterator color, size_t position, float &x, float &y)
Definition: text.cpp:417
void setText(const Common::UString &str)
Definition: text.cpp:103
iterator begin() const
Definition: ustring.cpp:253
const Common::UString & getFont() const
Definition: text.cpp:162
size_t getLineCount() const
Definition: text.cpp:203
float getHeight() const
Definition: text.cpp:211
void set(const Common::UString &str, float maxWidth=0.0f, float maxHeight=0.0f)
Definition: text.cpp:83
Text(const FontHandle &font, const Common::UString &str, float r=1.0f, float g=1.0f, float b=1.0f, float a=1.0f, float halign=kHAlignLeft, float valign=kVAlignTop)
Definition: text.cpp:36
The Aurora font manager.
void drawLine(const Common::UString &line, ColorPositions::const_iterator color, size_t position)
Definition: text.cpp:391
void getColor(float &r, float &g, float &b, float &a) const
Definition: text.cpp:120
void getPosition(float &x, float &y, float &z) const
Definition: text.cpp:166
utf8::iterator< std::string::const_iterator > iterator
Definition: ustring.h:50
RenderPass
Definition: types.h:97
void setPosition(float x, float y, float z=-FLT_MAX)
Definition: text.cpp:172
FontHandle _font
Definition: text.h:96
std::vector< ColorPosition > ColorPositions
Definition: types.h:114
void parseColors(const Common::UString &str, Common::UString &parsed, ColorPositions &colors)
Definition: text.cpp:303
static void splitTextTokens(const UString &text, std::vector< UString > &tokens)
Definition: ustring.cpp:645
bool isIn(float x, float y) const
Is that point within the object?
Definition: text.cpp:262
const Common::UString & get() const
Definition: text.cpp:158
bool empty() const
Is the string empty?
Definition: ustring.cpp:245
An abstract font.
Definition: font.h:39
void setHorizontalAlign(float halign)
Definition: text.cpp:146
void renderImmediate(const glm::mat4 &parentTransform)
For shader based systems, don&#39;t sort anything, render this right_now.
Definition: text.cpp:272
void render(RenderPass pass)
Render the object.
Definition: text.cpp:218
An element of the GUI.
Definition: guielement.h:33
void setVerticalAlign(float valign)
Definition: text.cpp:154
size_t size() const
Return the size of the string, in characters.
Definition: ustring.cpp:241
void calculateDistance()
Calculate the object&#39;s distance.
Definition: text.cpp:215
uint32_t uint32
Definition: types.h:204
Common::UString _str
Definition: text.h:109
const Common::UString & getName() const
Definition: fonthandle.cpp:71
virtual void renderBind(const glm::mat4 &transform) const
Definition: font.h:68
#define pass
Definition: fft.cpp:257
iterator end() const
Definition: ustring.cpp:257
void setSize(float width, float height)
Definition: text.cpp:184
virtual void buildChars(const Common::UString &str)
Build all necessary characters to display this string.
Definition: font.cpp:66
float getVerticalAlign() const
Definition: text.cpp:150
virtual float getHeight() const =0
Return the height of a character.
void clear()
Clear the string&#39;s contents.
Definition: ustring.cpp:236
void setFont(const Common::UString &fnt)
Change the font of the text.
Definition: text.cpp:387
A font.
#define FLT_MAX
Definition: maths.h:47
virtual float getWidth(uint32 c) const =0
Return the width of a character.
Only render opaque parts.
Definition: types.h:98
void setColor(float r, float g, float b, float a)
Definition: text.cpp:127
#define FontMan
Shortcut for accessing the font manager.
Definition: fontman.h:105
virtual void renderUnbind() const
Definition: font.h:70
virtual void render(uint32 c, float &x, float &y, float *rgba) const
Definition: font.h:69