info_box_line.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // SuperTux
  2. // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. #include "supertux/info_box_line.hpp"
  17. #include "supertux/textscroller_screen.hpp"
  18. #include "supertux/resources.hpp"
  19. #include "supertux/colorscheme.hpp"
  20. #include "video/drawing_context.hpp"
  21. #include "video/font.hpp"
  22. #include "video/surface.hpp"
  23. static const float ITEMS_SPACE = 4;
  24. namespace {
  25. FontPtr get_font_by_format_char(char format_char) {
  26. switch (format_char)
  27. {
  28. case ' ':
  29. return Resources::small_font;
  30. case '-':
  31. return Resources::big_font;
  32. case '\t':
  33. case '*':
  34. case '#':
  35. case '!':
  36. return Resources::normal_font;
  37. default:
  38. return Resources::normal_font;
  39. //log_warning << "Unknown format_char: '" << format_char << "'" << std::endl;
  40. }
  41. }
  42. Color get_color_by_format_char(char format_char) {
  43. switch (format_char)
  44. {
  45. case ' ':
  46. return ColorScheme::Text::small_color;
  47. case '-':
  48. return ColorScheme::Text::heading_color;
  49. case '*':
  50. return ColorScheme::Text::reference_color;
  51. case '\t':
  52. case '#':
  53. case '!':
  54. return ColorScheme::Text::normal_color;
  55. default:
  56. return ColorScheme::Text::normal_color;
  57. //log_warning << "Unknown format_char: '" << format_char << "'" << std::endl;
  58. }
  59. }
  60. InfoBoxLine::LineType get_linetype_by_format_char(char format_char) {
  61. switch (format_char)
  62. {
  63. case ' ':
  64. return InfoBoxLine::SMALL;
  65. case '\t':
  66. return InfoBoxLine::NORMAL;
  67. case '-':
  68. return InfoBoxLine::HEADING;
  69. case '*':
  70. return InfoBoxLine::REFERENCE;
  71. case '#':
  72. return InfoBoxLine::NORMAL_LEFT;
  73. case '!':
  74. return InfoBoxLine::IMAGE;
  75. default:
  76. return InfoBoxLine::SMALL;
  77. //log_warning << "Unknown format_char: '" << format_char << "'" << std::endl;
  78. }
  79. }
  80. } // namespace
  81. InfoBoxLine::InfoBoxLine(char format_char, const std::string& text_) :
  82. lineType(get_linetype_by_format_char(format_char)),
  83. font(get_font_by_format_char(format_char)),
  84. color(get_color_by_format_char(format_char)),
  85. text(text_),
  86. image()
  87. {
  88. if (lineType == IMAGE)
  89. {
  90. image = Surface::from_file(text);
  91. }
  92. }
  93. std::vector<std::unique_ptr<InfoBoxLine> >
  94. InfoBoxLine::split(const std::string& text, float width)
  95. {
  96. std::vector<std::unique_ptr<InfoBoxLine> > lines;
  97. std::string::size_type i = 0;
  98. std::string::size_type l;
  99. char format_char = '#';
  100. while (i < text.size()) {
  101. // take care of empty lines - represent them as blank lines of normal text
  102. if (text[i] == '\n') {
  103. lines.emplace_back(new InfoBoxLine('\t', ""));
  104. i++;
  105. continue;
  106. }
  107. // extract the format_char
  108. if (is_valid_format_char(text[i]))
  109. {
  110. format_char = text[i];
  111. i++;
  112. }
  113. else
  114. {
  115. format_char = '#';
  116. }
  117. if (i >= text.size()) break;
  118. // extract one line
  119. l = text.find('\n', i);
  120. if (l == std::string::npos) l=text.size();
  121. std::string s = text.substr(i, l-i);
  122. i = l+1;
  123. // if we are dealing with an image, just store the line
  124. if (format_char == '!') {
  125. lines.emplace_back(new InfoBoxLine(format_char, s));
  126. continue;
  127. }
  128. // append wrapped parts of line into list
  129. std::string overflow;
  130. do {
  131. FontPtr font = get_font_by_format_char(format_char);
  132. std::string s2 = s;
  133. if (font) s2 = font->wrap_to_width(s2, width, &overflow);
  134. lines.emplace_back(new InfoBoxLine(format_char, s2));
  135. s = overflow;
  136. } while (s.length() > 0);
  137. }
  138. return lines;
  139. }
  140. void
  141. InfoBoxLine::draw(DrawingContext& context, const Rectf& bbox, int layer, LineAlignment alignment)
  142. {
  143. Vector position = bbox.p1();
  144. switch (lineType) {
  145. case IMAGE:
  146. context.color().draw_surface(image, Vector(((bbox.get_left() + bbox.get_right() - static_cast<float>(image->get_width())) * 0.5f)
  147. + (static_cast<float>(image->get_width()) * (alignment == LineAlignment::LEFT ? 0.5f : alignment == LineAlignment::RIGHT ? -0.5f : 0.f)), position.y), layer);
  148. break;
  149. case NORMAL_LEFT:
  150. context.color().draw_text(font, text, Vector(position.x, position.y), ALIGN_LEFT, layer, color);
  151. break;
  152. default:
  153. context.color().draw_text(font, text, Vector((bbox.get_left() + bbox.get_right()) / 2.f, position.y),
  154. alignment == LineAlignment::LEFT ? ALIGN_LEFT :
  155. alignment == LineAlignment::RIGHT ? ALIGN_RIGHT : ALIGN_CENTER, layer, color);
  156. break;
  157. }
  158. }
  159. float
  160. InfoBoxLine::get_height() const
  161. {
  162. switch (lineType) {
  163. case IMAGE:
  164. return static_cast<float>(image->get_height()) + ITEMS_SPACE;
  165. case NORMAL_LEFT:
  166. return font->get_height() + ITEMS_SPACE;
  167. default:
  168. return font->get_height() + ITEMS_SPACE;
  169. }
  170. }
  171. /* EOF */