2 // Copyright (C) 2008 by Martin Moracek
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.
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
29 #include "gui/font/font.h"
30 #include "gui/plaintext.h"
32 #include "memory/mmgr.h"
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
)
55 void PlainText::SetText(const std::string
& text
)
59 tmp_str
.resize(text
.size());
60 std::copy(text
.begin(), text
.end(), tmp_str
.begin());
65 void PlainText::SetText(const std::wstring
& text
)
72 void PlainText::ClearText(void)
77 void PlainText::RedrawText(bool reset
)
82 font_
->SetSize(style_
.size
* scaleFactor_
.y
);
83 font_
->SetAntialias(antialias_
);
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
);
98 DEBUG_ASSERT(glyphs_
.size() == text_
.size());
105 FaceInfo
info(font_
->GetFaceInfo(style_
.fstyle
));
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
;
120 ln
.offset
+= info
.height
;
125 // ignore missing glyphs and errors
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
;
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
)
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
;
160 // haStretch not supported for plain text
164 x_off
= -static_cast<int>(width
);
166 x_off
= static_cast<int>(bounds_
.x
* scaleFactor_
.x
- width
);
170 x_off
= -static_cast<int>(width
) / 2;
172 x_off
= static_cast<int>(bounds_
.x
* scaleFactor_
.x
- width
) / 2;
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