The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
marked-up_text.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by David White <[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 /**
16  * @file
17  * Support for simple markup in text (fonts, colors, images).
18  * E.g. "@Victory" will be shown in green.
19  */
20 
21 #define GETTEXT_DOMAIN "wesnoth-lib"
22 
23 #include "global.hpp"
24 
25 #include "font.hpp"
26 #include "gettext.hpp"
27 #include "marked-up_text.hpp"
30 #include "video.hpp"
31 #include "wml_exception.hpp"
32 #include "preferences.hpp"
33 
34 namespace font {
35 
36 // NOTE: if you add more markup characters below, you'll need to update
37 // the list in campaign_server.cpp (illegal_markup_chars) to blacklist
38 // them for add-on names and titles.
39 
40 const char LARGE_TEXT='*', SMALL_TEXT='`',
44  GOOD_TEXT='@', BAD_TEXT='#',
45  GREEN_TEXT='@', RED_TEXT='#',
46  COLOR_TEXT='<', IMAGE='&';
47 
48 const std::string weapon = "<245,230,193>",
49  weapon_details = "<166,146,117>",
50  unit_type = "<245,230,193>",
51  race = "<166,146,117>";
52 
53 const SDL_Color
54  weapon_color = { 245, 230, 193, SDL_ALPHA_OPAQUE },
55  good_dmg_color = { 130, 240, 50, SDL_ALPHA_OPAQUE },
56  bad_dmg_color = { 250, 140, 80, SDL_ALPHA_OPAQUE },
57  weapon_details_color = { 166, 146, 117, SDL_ALPHA_OPAQUE },
58  inactive_details_color = { 146, 146, 146, SDL_ALPHA_OPAQUE },
59  inactive_ability_color = { 146, 146, 146, SDL_ALPHA_OPAQUE },
60  unit_type_color = { 245, 230, 193, SDL_ALPHA_OPAQUE },
61  race_color = { 166, 146, 117, SDL_ALPHA_OPAQUE };
62 
64 
65 std::string::const_iterator parse_markup(std::string::const_iterator i1,
66  std::string::const_iterator i2,
67  int* font_size,
68  SDL_Color* color, int* style)
69 {
70  while(i1 != i2) {
71  switch(*i1) {
72  case '\\':
73  // This must either be a quoted special character or a
74  // quoted backslash - either way, remove leading backslash
75  break;
76  case BAD_TEXT:
77  if (color) *color = BAD_COLOR;
78  break;
79  case GOOD_TEXT:
80  if (color) *color = GOOD_COLOR;
81  break;
82  case NORMAL_TEXT:
83  if (color) *color = NORMAL_COLOR;
84  break;
85  case BLACK_TEXT:
86  if (color) *color = BLACK_COLOR;
87  break;
88  case GRAY_TEXT:
89  if (color) *color = GRAY_COLOR;
90  break;
91  case LARGE_TEXT:
92  if (font_size) *font_size += 2;
93  break;
94  case SMALL_TEXT:
95  if (font_size) *font_size -= 2;
96  break;
97  case BOLD_TEXT:
98  if (style) *style |= TTF_STYLE_BOLD;
99  break;
100  case NULL_MARKUP:
101  return i1+1;
102  case COLOR_TEXT:
103  {
104  std::string::const_iterator start = i1;
105  // Very primitive parsing for rgb value
106  // should look like <213,14,151>
107  ++i1;
108  Uint8 red=0, green=0, blue=0, temp=0;
109  while (i1 != i2 && *i1 >= '0' && *i1<='9') {
110  temp*=10;
111  temp += lexical_cast<int, char>(*i1);
112  ++i1;
113  }
114  red=temp;
115  temp=0;
116  if (i1 != i2 && ',' == (*i1)) {
117  ++i1;
118  while(i1 != i2 && *i1 >= '0' && *i1<='9'){
119  temp*=10;
120  temp += lexical_cast<int, char>(*i1);
121  ++i1;
122  }
123  green=temp;
124  temp=0;
125  }
126  if (i1 != i2 && ',' == (*i1)) {
127  ++i1;
128  while(i1 != i2 && *i1 >= '0' && *i1<='9'){
129  temp*=10;
130  temp += lexical_cast<int, char>(*i1);
131  ++i1;
132  }
133  }
134  blue=temp;
135  if (i1 != i2 && '>' == (*i1)) {
136  SDL_Color temp_color = {red, green, blue, 0};
137  if (color) *color = temp_color;
138  } else {
139  // stop parsing and do not consume any chars
140  return start;
141  }
142  if (i1 == i2) return i1;
143  break;
144  }
145  default:
146  return i1;
147  }
148  ++i1;
149  }
150  return i1;
151 }
152 
154  std::vector<std::string> lines = utils::split(text, '\n', 0);
156  for(line = lines.begin(); line != lines.end(); ++line) {
157  std::string::const_iterator i1 = line->begin(),
158  i2 = line->end();
159  *line = std::string(parse_markup(i1,i2,nullptr,nullptr,nullptr),i2);
160  }
161  return utils::join(lines, "\n");
162 }
163 
164 std::string color2markup(const SDL_Color &color)
165 {
166  std::stringstream markup;
167  // The RGB of SDL_Color are Uint8, we need to cast them to int.
168  // Without cast, it gives their char equivalent.
169  markup << "<"
170  << static_cast<int>(color.r) << ","
171  << static_cast<int>(color.g) << ","
172  << static_cast<int>(color.b) << ">";
173  return markup.str();
174 }
175 
176 std::string color2hexa(const SDL_Color &color)
177 {
178  char buf[7];
179  sprintf(buf, "%02x%02x%02x", color.r, color.g, color.b);
180  return buf;
181 }
182 
183 std::string span_color(const SDL_Color &color)
184 {
185  return "<span foreground=\"#" + font::color2hexa(color) + "\">";
186 }
187 
188 SDL_Rect text_area(const std::string& text, int size, int style)
189 {
190  const SDL_Rect area = {0,0,10000,10000};
191  return draw_text(nullptr, area, size, font::NORMAL_COLOR, text, 0, 0, false, style);
192 }
193 
194 SDL_Rect draw_text(surface& dst, const SDL_Rect& area, int size,
195  const SDL_Color& color, const std::string& txt,
196  int x, int y, bool use_tooltips, int style)
197 {
198  // Make sure there's always at least a space,
199  // so we can ensure that we can return a rectangle for height
200  static const std::string blank_text(" ");
201  const std::string& text = txt.empty() ? blank_text : txt;
202 
203  SDL_Rect res;
204  res.x = x;
205  res.y = y;
206  res.w = 0;
207  res.h = 0;
208 
209  std::string::const_iterator i1 = text.begin();
210  std::string::const_iterator i2 = std::find(i1,text.end(),'\n');
211  for(;;) {
212  SDL_Color col = color;
213  int sz = size;
214  int text_style = style;
215 
216  i1 = parse_markup(i1,i2,&sz,&col,&text_style);
217 
218  if(i1 != i2) {
219  std::string new_string = utils::unescape(std::string(i1, i2));
220 
221  const SDL_Rect rect = draw_text_line(dst, area, sz, col, new_string, x, y, use_tooltips, text_style);
222  if(rect.w > res.w) {
223  res.w = rect.w;
224  }
225 
226  res.h += rect.h;
227  y += rect.h;
228  }
229 
230  if(i2 == text.end()) {
231  break;
232  }
233 
234  i1 = i2+1;
235  i2 = std::find(i1,text.end(),'\n');
236  }
237 
238  return res;
239 }
240 
241 SDL_Rect draw_text(CVideo* gui, const SDL_Rect& area, int size,
242  const SDL_Color& color, const std::string& txt,
243  int x, int y, bool use_tooltips, int style)
244 {
245  surface null_surf = surface(nullptr);
246 
247  return draw_text(gui != nullptr ? gui->getSurface() : null_surf, area, size, color, txt, x, y, use_tooltips, style);
248 }
249 
250 bool is_format_char(char c)
251 {
252  switch(c) {
253  case LARGE_TEXT:
254  case SMALL_TEXT:
255  case GOOD_TEXT:
256  case BAD_TEXT:
257  case NORMAL_TEXT:
258  case BLACK_TEXT:
259  case GRAY_TEXT:
260  case BOLD_TEXT:
261  case NULL_MARKUP:
262  return true;
263  default:
264  return false;
265  }
266 }
267 
268 bool is_cjk_char(const ucs4::char_t ch)
269 {
270  /**
271  * You can check these range at http://unicode.org/charts/
272  * see the "East Asian Scripts" part.
273  * Notice that not all characters in that part is still in use today, so don't list them all here.
274  * Below are characters that I guess may be used in wesnoth translations.
275  */
276 
277  //FIXME add range from Japanese-specific and Korean-specific section if you know the characters are used today.
278 
279  if (ch < 0x2e80) return false; // shortcut for common non-CJK
280 
281  return
282  //Han Ideographs: all except Supplement
283  (ch >= 0x4e00 && ch < 0x9fcf) ||
284  (ch >= 0x3400 && ch < 0x4dbf) ||
285  (ch >= 0x20000 && ch < 0x2a6df) ||
286  (ch >= 0xf900 && ch < 0xfaff) ||
287  (ch >= 0x3190 && ch < 0x319f) ||
288 
289  //Radicals: all except Ideographic Description
290  (ch >= 0x2e80 && ch < 0x2eff) ||
291  (ch >= 0x2f00 && ch < 0x2fdf) ||
292  (ch >= 0x31c0 && ch < 0x31ef) ||
293 
294  //Chinese-specific: Bopomofo and Bopomofo Extended
295  (ch >= 0x3104 && ch < 0x312e) ||
296  (ch >= 0x31a0 && ch < 0x31bb) ||
297 
298  //Yi-specific: Yi Radicals, Yi Syllables
299  (ch >= 0xa490 && ch < 0xa4c7) ||
300  (ch >= 0xa000 && ch < 0xa48d) ||
301 
302  //Japanese-specific: Hiragana, Katakana, Kana Supplement
303  (ch >= 0x3040 && ch <= 0x309f) ||
304  (ch >= 0x30a0 && ch <= 0x30ff) ||
305  (ch >= 0x1b000 && ch <= 0x1b001) ||
306 
307  //Ainu-specific: Katakana Phonetic Extensions
308  (ch >= 0x31f0 && ch <= 0x31ff) ||
309 
310  //Korean-specific: Hangul Syllables, Hangul Jamo, Hangul Jamo Extended-A, Hangul Jamo Extended-B
311  (ch >= 0xac00 && ch < 0xd7af) ||
312  (ch >= 0x1100 && ch <= 0x11ff) ||
313  (ch >= 0xa960 && ch <= 0xa97c) ||
314  (ch >= 0xd7b0 && ch <= 0xd7fb) ||
315 
316  //CJK Symbols and Punctuation
317  (ch >= 0x3000 && ch < 0x303f) ||
318 
319  //Halfwidth and Fullwidth Forms
320  (ch >= 0xff00 && ch < 0xffef);
321 }
322 static void cut_word(std::string& line, std::string& word, int font_size, int style, int max_width)
323 {
324  std::string tmp = line;
325  utf8::iterator tc(word);
326  bool first = true;
327  font_size = preferences::font_scaled(font_size);
328 
329  for(;tc != utf8::iterator::end(word); ++tc) {
330  tmp.append(tc.substr().first, tc.substr().second);
331  SDL_Rect tsize = line_size(tmp, font_size, style);
332  if(tsize.w > max_width) {
333  const std::string& w = word;
334  if(line.empty() && first) {
335  line += std::string(w.begin(), tc.substr().second);
336  word = std::string(tc.substr().second, w.end());
337  } else {
338  line += std::string(w.begin(), tc.substr().first);
339  word = std::string(tc.substr().first, w.end());
340  }
341  break;
342  }
343  first = false;
344  }
345 }
346 
347 namespace {
348 
349 /*
350  * According to Kinsoku-Shori, Japanese rules about line-breaking:
351  *
352  * * the following characters cannot begin a line (so we will never break before them):
353  * 、。,.)〕]}〉》」』】’”ゝゞヽヾ々?!:;ぁぃぅぇぉゃゅょゎァィゥェォャュョヮっヵッヶ・…ー
354  *
355  * * the following characters cannot end a line (so we will never break after them):
356  * (〔[{〈《「『【‘“
357  *
358  * Unicode range that concerns word wrap for Chinese:
359  * 全角ASCII、全角中英文标点 (Fullwidth Character for ASCII, English punctuations and part of Chinese punctuations)
360  * http://www.unicode.org/charts/PDF/UFF00.pdf
361  * CJK 标点符号 (CJK punctuations)
362  * http://www.unicode.org/charts/PDF/U3000.pdf
363  */
364 inline bool no_break_after(const ucs4::char_t ch)
365 {
366  return
367  /**
368  * don't break after these Japanese characters
369  */
370  ch == 0x2018 || ch == 0x201c || ch == 0x3008 || ch == 0x300a || ch == 0x300c ||
371  ch == 0x300e || ch == 0x3010 || ch == 0x3014 || ch == 0xff08 || ch == 0xff3b ||
372  ch == 0xff5b ||
373 
374  /**
375  * FIXME don't break after these Korean characters
376  */
377 
378  /**
379  * don't break after these Chinese characters
380  * contains left side of different kinds of brackets and quotes
381  */
382  ch == 0x3016 || ch == 0x301a || ch == 0x301d;
383 }
384 
385 inline bool no_break_before(const ucs4::char_t ch)
386 {
387  return
388  /**
389  * don't break before these Japanese characters
390  */
391  ch == 0x2019 || ch == 0x201d || ch == 0x2026 || ch == 0x3001 || ch == 0x3002 ||
392  ch == 0x3005 || ch == 0x3009 || ch == 0x300b || ch == 0x300d || ch == 0x300f ||
393  ch == 0x3011 || ch == 0x3015 || ch == 0x3041 || ch == 0x3043 || ch == 0x3045 ||
394  ch == 0x3047 || ch == 0x3049 || ch == 0x3063 || ch == 0x3083 || ch == 0x3085 ||
395  ch == 0x3087 || ch == 0x308e || ch == 0x309d || ch == 0x309e || ch == 0x30a1 ||
396  ch == 0x30a3 || ch == 0x30a5 || ch == 0x30a7 || ch == 0x30a9 || ch == 0x30c3 ||
397  ch == 0x30e3 || ch == 0x30e5 || ch == 0x30e7 || ch == 0x30ee || ch == 0x30f5 ||
398  ch == 0x30f6 || ch == 0x30fb || ch == 0x30fc || ch == 0x30fd || ch == 0x30fe ||
399  ch == 0xff01 || ch == 0xff09 || ch == 0xff0c || ch == 0xff0e || ch == 0xff1a ||
400  ch == 0xff1b || ch == 0xff1f || ch == 0xff3d || ch == 0xff5d ||
401 
402  // Small katakana used in Ainu:
403  ch == 0x31f0 || ch == 0x31f1 || ch == 0x31f2 || ch == 0x31f3 || ch == 0x31f4 ||
404  ch == 0x31f5 || ch == 0x31f6 || ch == 0x31f7 || ch == 0x31f8 || ch == 0x31f9 ||
405  ch == 0x31fa || ch == 0x31fb || ch == 0x31fc || ch == 0x31fd || ch == 0x31fe ||
406  ch == 0x31ff ||
407 
408  /**
409  * FIXME don't break before these Korean characters
410  */
411 
412  /**
413  * don't break before these Chinese characters
414  * contains
415  * many Chinese punctuations that should not start a line
416  * and right side of different kinds of brackets, quotes
417  */
418  ch == 0x301c || ch == 0xff0d || ch == 0xff64 || ch == 0xff65 || ch == 0x3017 ||
419  ch == 0x301b || ch == 0x301e;
420 }
421 
422 inline bool break_before(const ucs4::char_t ch)
423 {
424  if(no_break_before(ch))
425  return false;
426 
427  return is_cjk_char(ch);
428 }
429 
430 inline bool break_after(const ucs4::char_t ch)
431 {
432  if(no_break_after(ch))
433  return false;
434 
435  return is_cjk_char(ch);
436 }
437 
438 } // end of anon namespace
439 
440 std::string word_wrap_text(const std::string& unwrapped_text, int font_size,
441  int max_width, int max_height, int max_lines, bool partial_line)
442 {
443  VALIDATE(max_width > 0, _("The maximum text width is less than 1."));
444 
445  utf8::iterator ch(unwrapped_text);
446  std::string current_word;
447  std::string current_line;
448  size_t line_width = 0;
449  size_t current_height = 0;
450  bool line_break = false;
451  bool first = true;
452  bool start_of_line = true;
453  std::string wrapped_text;
454  std::string format_string;
455  SDL_Color color;
456  int font_sz = font_size;
457  int style = TTF_STYLE_NORMAL;
458  utf8::iterator end = utf8::iterator::end(unwrapped_text);
459 
460  while(1) {
461  if(start_of_line) {
462  line_width = 0;
463  format_string.clear();
464  while(ch != end && *ch < static_cast<ucs4::char_t>(0x100)
465  && is_format_char(*ch) && !ch.next_is_end()) {
466 
467  format_string.append(ch.substr().first, ch.substr().second);
468  ++ch;
469  }
470  // We need to parse the special format characters
471  // to give the proper font_size and style to line_size()
472  font_sz = font_size;
473  style = TTF_STYLE_NORMAL;
474  parse_markup(format_string.begin(),format_string.end(),&font_sz,&color,&style);
475  current_line.clear();
476  start_of_line = false;
477  }
478 
479  // If there is no current word, get one
480  if(current_word.empty() && ch == end) {
481  break;
482  } else if(current_word.empty()) {
483  if(*ch == ' ' || *ch == '\n') {
484  current_word = *ch;
485  ++ch;
486  } else {
487  ucs4::char_t previous = 0;
488  for(;ch != utf8::iterator::end(unwrapped_text) &&
489  *ch != ' ' && *ch != '\n'; ++ch) {
490 
491  if(!current_word.empty() &&
492  break_before(*ch) &&
493  !no_break_after(previous))
494  break;
495 
496  if(!current_word.empty() &&
497  break_after(previous) &&
498  !no_break_before(*ch))
499  break;
500 
501  current_word.append(ch.substr().first, ch.substr().second);
502 
503  previous = *ch;
504  }
505  }
506  }
507 
508  if(current_word == "\n") {
509  line_break = true;
510  current_word.clear();
511  start_of_line = true;
512  } else {
513 
514  const size_t word_width = line_size(current_word, preferences::font_scaled(font_sz), style).w;
515 
516  line_width += word_width;
517 
518  if(static_cast<long>(line_width) > max_width) {
519  if (!partial_line && static_cast<long>(word_width) > max_width) {
520  cut_word(current_line,
521  current_word, font_sz, style, max_width);
522  }
523  if(current_word == " ")
524  current_word = "";
525  line_break = true;
526  } else {
527  current_line += current_word;
528  current_word = "";
529  }
530  }
531 
532  if(line_break || (current_word.empty() && ch == end)) {
533  SDL_Rect size = line_size(current_line, preferences::font_scaled(font_sz), style);
534  if(max_height > 0 && current_height + size.h >= size_t(max_height)) {
535  return wrapped_text;
536  }
537 
538  if(!first) {
539  wrapped_text += '\n';
540  }
541 
542  wrapped_text += format_string + current_line;
543  current_line.clear();
544  line_width = 0;
545  current_height += size.h;
546  line_break = false;
547  first = false;
548 
549  if(--max_lines == 0) {
550  return wrapped_text;
551  }
552  }
553  }
554  return wrapped_text;
555 }
556 
557 SDL_Rect draw_wrapped_text(CVideo* gui, const SDL_Rect& area, int font_size,
558  const SDL_Color& color, const std::string& text,
559  int x, int y, int max_width)
560 {
561  std::string wrapped_text = word_wrap_text(text, font_size, max_width);
562  return font::draw_text(gui, area, font_size, color, wrapped_text, x, y, false);
563 }
564 
565 #ifdef SDL_GPU
566 sdl::timage draw_text_to_texture(const SDL_Rect &area, int size, const SDL_Color &color, const std::string &text, bool use_tooltips, int style)
567 {
568  SDL_Rect rect = text_area(text, size, style);
569  surface surf = SDL_CreateRGBSurface(SDL_SWSURFACE, rect.w, rect.h, 32,
570  0xff000000,
571  0x00ff0000,
572  0x0000ff00,
573  0x000000ff);
574  SDL_FillRect(surf, nullptr, 0x000000ff);
575  draw_text(surf, area, size, color, text, 0, 0, use_tooltips, style);
576 
577  return sdl::timage(surf);
578 }
579 #endif
580 
581 } // end namespace font
582 
const char COLOR_TEXT
const SDL_Color good_dmg_color
SDL_Rect text_area(const std::string &text, int size, int style)
Calculate the size of a text (in pixels) if it were to be drawn.
static void cut_word(std::string &line, std::string &word, int font_size, int style, int max_width)
const SDL_Color unit_type_color
std::string color2hexa(const SDL_Color &color)
Creates the hexadecimal string of a color, such as "#ffff00" for yellow.
const std::string weapon_details_sep
const std::string race
Graphical text output.
const SDL_Color BLACK_COLOR
Definition: font.cpp:569
const GLfloat * c
Definition: glew.h:12741
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
const char IMAGE
Definition: video.hpp:58
SDL_Rect line_size(const std::string &line, int font_size, int style)
Determine the size of a line of text given a certain font size.
Definition: font.cpp:974
General purpose widgets.
const char LARGE_TEXT
Standard markups for color, size, font, images.
std::string unescape(const std::string &str)
Remove all escape characters (backslash)
std::string word_wrap_text(const std::string &unwrapped_text, int font_size, int max_width, int max_height, int max_lines, bool partial_line)
Wrap text.
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1220
To lexical_cast(From value)
Lexical cast converts one type to another.
const SDL_Color NORMAL_COLOR
Definition: font.cpp:564
-file util.hpp
const char BLACK_TEXT
surface & getSurface()
Definition: dummy_video.cpp:22
std::string span_color(const SDL_Color &color)
Creates pango markup of a color.
const SDL_Color inactive_details_color
const SDL_Color GOOD_COLOR
Definition: font.cpp:567
const SDL_Color bad_dmg_color
const char GRAY_TEXT
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
GLuint GLuint end
Definition: glew.h:1221
const char BAD_TEXT
GLclampf GLclampf blue
Definition: glew.h:1488
#define VALIDATE(cond, message)
The macro to use for the validation of WML.
const char GREEN_TEXT
const SDL_Color BAD_COLOR
Definition: font.cpp:568
GLclampf green
Definition: glew.h:1488
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1858
GLenum GLenum dst
Definition: glew.h:2392
const SDL_Color race_color
GLuint start
Definition: glew.h:1221
int font_scaled(int size)
GLenum GLuint GLsizei const char * buf
Definition: glew.h:2498
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
const SDL_Color weapon_details_color
surf
Definition: filter.cpp:143
GLuint color
Definition: glew.h:5801
std::string join(T const &v, const std::string &s=",")
Generates a new string joining container items in a list.
std::string color2markup(const SDL_Color &color)
Create string of color-markup, such as "<255,255,0>" for yellow.
std::string::const_iterator parse_markup(std::string::const_iterator i1, std::string::const_iterator i2, int *font_size, SDL_Color *color, int *style)
Parses the markup-tags at the front of a string.
bool is_format_char(char c)
Determine if char is one of the special chars used as markup.
SDL_Rect draw_text(surface &dst, const SDL_Rect &area, int size, const SDL_Color &color, const std::string &txt, int x, int y, bool use_tooltips, int style)
Function to draw text on a surface.
GLuint res
Definition: glew.h:9258
const char NULL_MARKUP
const std::string weapon_details
SDL_Rect draw_wrapped_text(CVideo *gui, const SDL_Rect &area, int font_size, const SDL_Color &color, const std::string &text, int x, int y, int max_width)
Draw text on the screen, fit text to maximum width, no markup, no tooltips.
boost::uint32_t char_t
bool is_cjk_char(const ucs4::char_t ch)
Determine if a ucs4::char_t is a CJK character.
GLint GLint GLint GLint GLint x
Definition: glew.h:1220
static iterator_base end(const string_type &str)
const GLfloat * tc
Definition: glew.h:12749
GLsizeiptr size
Definition: glew.h:1649
SDL_Rect draw_text_line(surface &gui_surface, const SDL_Rect &area, int size, const SDL_Color &color, const std::string &text, int x, int y, bool use_tooltips, int style)
Definition: font.cpp:892
const char RED_TEXT
const SDL_Color weapon_color
const std::string weapon_numbers_sep
std::string del_tags(const std::string &text)
Copy string, but without tags at the beginning.
bool find(E event, F functor)
Tests whether an event handler is available.
const char SMALL_TEXT
const std::pair< typename string_type::const_iterator, typename string_type::const_iterator > & substr() const
const char GOOD_TEXT
const SDL_Color GRAY_COLOR
Definition: font.cpp:565
GLint * first
Definition: glew.h:1496
const char BOLD_TEXT
std::vector< std::string > split(std::string const &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
const std::string weapon
const SDL_Color inactive_ability_color
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
const int font_size
GLsizei const GLcharARB ** string
Definition: glew.h:4503
int line_width(const std::string &line, int font_size, int style)
Determine the width of a line of text given a certain font size.
Definition: font.cpp:969
const char NORMAL_TEXT