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 | |
17 | #include "supertux/info_box_line.hpp" |
18 | |
19 | #include "supertux/textscroller_screen.hpp" |
20 | #include "supertux/resources.hpp" |
21 | #include "supertux/colorscheme.hpp" |
22 | #include "video/drawing_context.hpp" |
23 | #include "video/font.hpp" |
24 | #include "video/surface.hpp" |
25 | |
26 | static const float ITEMS_SPACE = 4; |
27 | |
28 | namespace { |
29 | |
30 | FontPtr get_font_by_format_char(char format_char) { |
31 | switch (format_char) |
32 | { |
33 | case ' ': |
34 | return Resources::small_font; |
35 | case '-': |
36 | return Resources::big_font; |
37 | case '\t': |
38 | case '*': |
39 | case '#': |
40 | case '!': |
41 | return Resources::normal_font; |
42 | default: |
43 | return Resources::normal_font; |
44 | //log_warning << "Unknown format_char: '" << format_char << "'" << std::endl; |
45 | } |
46 | } |
47 | |
48 | Color get_color_by_format_char(char format_char) { |
49 | switch (format_char) |
50 | { |
51 | case ' ': |
52 | return ColorScheme::Text::small_color; |
53 | case '-': |
54 | return ColorScheme::Text::heading_color; |
55 | case '*': |
56 | return ColorScheme::Text::reference_color; |
57 | case '\t': |
58 | case '#': |
59 | case '!': |
60 | return ColorScheme::Text::normal_color; |
61 | default: |
62 | return ColorScheme::Text::normal_color; |
63 | //log_warning << "Unknown format_char: '" << format_char << "'" << std::endl; |
64 | } |
65 | } |
66 | |
67 | InfoBoxLine::LineType get_linetype_by_format_char(char format_char) { |
68 | switch (format_char) |
69 | { |
70 | case ' ': |
71 | return InfoBoxLine::SMALL; |
72 | |
73 | case '\t': |
74 | return InfoBoxLine::NORMAL; |
75 | case '-': |
76 | return InfoBoxLine::HEADING; |
77 | case '*': |
78 | return InfoBoxLine::REFERENCE; |
79 | case '#': |
80 | return InfoBoxLine::NORMAL_LEFT; |
81 | case '!': |
82 | return InfoBoxLine::IMAGE; |
83 | default: |
84 | return InfoBoxLine::SMALL; |
85 | //log_warning << "Unknown format_char: '" << format_char << "'" << std::endl; |
86 | } |
87 | } |
88 | |
89 | } // namespace |
90 | |
91 | InfoBoxLine::InfoBoxLine(char format_char, const std::string& text_) : |
92 | lineType(get_linetype_by_format_char(format_char)), |
93 | font(get_font_by_format_char(format_char)), |
94 | color(get_color_by_format_char(format_char)), |
95 | text(text_), |
96 | image() |
97 | { |
98 | if (lineType == IMAGE) |
99 | { |
100 | image = Surface::from_file(text); |
101 | } |
102 | } |
103 | |
104 | std::vector<std::unique_ptr<InfoBoxLine> > |
105 | InfoBoxLine::split(const std::string& text, float width) |
106 | { |
107 | std::vector<std::unique_ptr<InfoBoxLine> > lines; |
108 | |
109 | std::string::size_type i = 0; |
110 | std::string::size_type l; |
111 | char format_char = '#'; |
112 | while (i < text.size()) { |
113 | // take care of empty lines - represent them as blank lines of normal text |
114 | if (text[i] == '\n') { |
115 | lines.emplace_back(new InfoBoxLine('\t', "" )); |
116 | i++; |
117 | continue; |
118 | } |
119 | |
120 | // extract the format_char |
121 | if (is_valid_format_char(text[i])) |
122 | { |
123 | format_char = text[i]; |
124 | i++; |
125 | } |
126 | else |
127 | { |
128 | format_char = '#'; |
129 | } |
130 | if (i >= text.size()) break; |
131 | |
132 | // extract one line |
133 | l = text.find('\n', i); |
134 | if (l == std::string::npos) l=text.size(); |
135 | std::string s = text.substr(i, l-i); |
136 | i = l+1; |
137 | |
138 | // if we are dealing with an image, just store the line |
139 | if (format_char == '!') { |
140 | lines.emplace_back(new InfoBoxLine(format_char, s)); |
141 | continue; |
142 | } |
143 | |
144 | // append wrapped parts of line into list |
145 | std::string overflow; |
146 | do { |
147 | FontPtr font = get_font_by_format_char(format_char); |
148 | std::string s2 = s; |
149 | if (font) s2 = font->wrap_to_width(s2, width, &overflow); |
150 | lines.emplace_back(new InfoBoxLine(format_char, s2)); |
151 | s = overflow; |
152 | } while (s.length() > 0); |
153 | } |
154 | |
155 | return lines; |
156 | } |
157 | |
158 | void |
159 | InfoBoxLine::draw(DrawingContext& context, const Rectf& bbox, int layer) |
160 | { |
161 | Vector position = bbox.p1(); |
162 | switch (lineType) { |
163 | case IMAGE: |
164 | context.color().draw_surface(image, Vector( (bbox.get_left() + bbox.get_right() - static_cast<float>(image->get_width())) / 2.0f, position.y), layer); |
165 | break; |
166 | case NORMAL_LEFT: |
167 | context.color().draw_text(font, text, Vector(position.x, position.y), ALIGN_LEFT, layer, color); |
168 | break; |
169 | default: |
170 | context.color().draw_text(font, text, Vector((bbox.get_left() + bbox.get_right()) / 2, position.y), ALIGN_CENTER, layer, color); |
171 | break; |
172 | } |
173 | } |
174 | |
175 | float |
176 | InfoBoxLine::get_height() const |
177 | { |
178 | switch (lineType) { |
179 | case IMAGE: |
180 | return static_cast<float>(image->get_height()) + ITEMS_SPACE; |
181 | case NORMAL_LEFT: |
182 | return font->get_height() + ITEMS_SPACE; |
183 | default: |
184 | return font->get_height() + ITEMS_SPACE; |
185 | } |
186 | } |
187 | |
188 | /* EOF */ |
189 | |