Initial commit, includes Lua with broken Luabind as a backup for branching purposes
[terrastrategy.git] / src / gui / plaintext.cpp
blobe515c762e83e846f77686848aca95a3f4aea51bb
1 //
2 // Copyright (C) 2008 by Martin Moracek
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 2 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.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 /**
20 * @file plaintext.cpp
22 * blahblah
25 #include <wctype.h>
26 #include <algorithm>
27 #include <vector>
29 #include "gui/font/font.h"
30 #include "gui/plaintext.h"
32 #include "memory/mmgr.h"
34 namespace tre {
37 * PlainText class
39 PlainText::PlainText()
40 : style_(Font::defTextSize, fsRegular, Vector4f(1.0f, 1.0f, 1.0f, 1.0f))
44 PlainText::~PlainText()
48 void PlainText::SetStyle(const TextStyle & style)
50 style_ = style;
52 RedrawText(true);
55 void PlainText::SetText(const std::string & text)
57 std::wstring tmp_str;
59 tmp_str.resize(text.size());
60 std::copy(text.begin(), text.end(), tmp_str.begin());
62 SetText(tmp_str);
65 void PlainText::SetText(const std::wstring & text)
67 text_.assign(text);
69 RedrawText(true);
72 void PlainText::ClearText(void)
74 SetText(L"");
77 void PlainText::RedrawText(bool reset)
79 if(!font_)
80 return;
82 font_->SetSize(style_.size * scaleFactor_.y);
83 font_->SetAntialias(antialias_);
85 if(reset) {
86 glyphs_.resize(text_.size());
88 std::wstring::iterator ptr = text_.begin();
89 GlyphVector::iterator ptr2 = glyphs_.begin();
90 while(ptr != text_.end()) {
91 // not all whitespace characters have glyphs
92 *ptr2 = font_->GetGlyph(iswspace(*ptr) && *ptr != '\n' ?
93 ' ' : *ptr, style_.fstyle);
94 ++ptr, ++ptr2;
98 DEBUG_ASSERT(glyphs_.size() == text_.size());
100 GLineVector lines;
101 GlyphLine ln;
102 int x_off = 0;
103 uint max_width = 0;
105 FaceInfo info(font_->GetFaceInfo(style_.fstyle));
107 ln.offset = 0;
108 ln.baseline = info.ascender;
109 ln.height = info.height;
111 for(uint i = 0; i < text_.size(); ++i) {
112 if(text_[i] == L'\n') {
113 ln.width = ln.glyphs.empty() ? 0 : ln.glyphs.back().offset
114 + ln.glyphs.back().glyph->width;
115 if(ln.width > max_width)
116 max_width = ln.width;
117 lines.push_back(ln);
119 ln.glyphs.resize(0);
120 ln.offset += info.height;
121 x_off = 0;
122 continue;
125 // ignore missing glyphs and errors
126 if(!glyphs_[i])
127 continue;
129 if(!ln.glyphs.empty())
130 x_off += font_->GetKerning(text_[i - 1], text_[i], style_.fstyle);
132 ln.glyphs.push_back(GlyphPrep(glyphs_[i], &style_, x_off));
133 x_off += glyphs_[i]->advance_x;
135 // finish the current line
136 if(!ln.glyphs.empty()) {
137 ln.width = ln.glyphs.empty() ? 0 : ln.glyphs.back().offset
138 + ln.glyphs.back().glyph->width;
139 if(ln.width > max_width)
140 max_width = ln.width;
141 lines.push_back(ln);
143 WriteText(lines, max_width, lines.empty() ?
144 0 : lines.back().offset + info.height);
147 void PlainText::WriteText(const GLineVector & lines, uint width, uint height)
149 int x_off, y_off;
151 // vertical alignment
152 if(valign_ == vaMiddle && bounds_.y * scaleFactor_.y > height) {
153 y_off = (bounds_.y * scaleFactor_.y - height) / 2;
154 } else if(valign_ == vaBottom && bounds_.y * scaleFactor_.y > height) {
155 y_off = bounds_.y * scaleFactor_.y - height;
156 } else {
157 y_off = 0;
160 // haStretch not supported for plain text
161 switch(halign_) {
162 case haRight:
163 if(bounds_.x == 0)
164 x_off = -static_cast<int>(width);
165 else
166 x_off = static_cast<int>(bounds_.x * scaleFactor_.x - width);
167 break;
168 case haCenter:
169 if(bounds_.x == 0)
170 x_off = -static_cast<int>(width) / 2;
171 else
172 x_off = static_cast<int>(bounds_.x * scaleFactor_.x - width) / 2;
173 break;
174 default:
175 x_off = 0;
176 break;
179 textRect_.Set(x_off, y_off, x_off + height, y_off + width);
181 for(GLineVector::const_iterator pos = lines.begin();
182 pos != lines.end(); ++pos) {
183 for(GlyphPrepVector::const_iterator pos2 = pos->glyphs.begin();
184 pos2 != pos->glyphs.end(); ++pos2) {
185 MeshPage & page = GetPageByTexture(pos2->glyph->texture);
186 page.prep.push_back(std::make_pair(&(*pos2),
187 Vector2i(x_off + pos2->offset, y_off + pos->offset + pos->baseline)));
191 // automatically fills mesh pages and discard unused ones
192 // also resets geometry batches
193 ResetPages();