MyGUI 3.2.0

- Main Page
- Related Pages
- Namespaces
- Data Structures
- Files
- Examples

- File List
- Globals

MyGUI_TextView.cpp
Go to the documentation of this file.
1
6 /*
7 This file is part of MyGUI.
8
9 MyGUI is free software: you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 MyGUI is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
21 */
22 #include "MyGUI_Precompiled.h"
23 #include "MyGUI_TextView.h"
24
25 namespace MyGUI
26 {
27
28 namespace
29 {
30
31 template<typename T>
32 void setMin(T& _var, const T& _newValue)
33 {
34 if (_newValue < _var)
35 _var = _newValue;
36 }
37
38 template<typename T>
39 void setMax(T& _var, const T& _newValue)
40 {
41 if (_var < _newValue)
42 _var = _newValue;
43 }
44
45 }
46
47 class RollBackPoint
48 {
49 public:
50 RollBackPoint() :
51 position(0),
52 count(0),
53 width(0),
54 rollback(false)
55 {
56 }
57
58 void set(size_t _position, UString::const_iterator& _space_point, size_t _count, float _width)
59 {
60 position = _position;
61 space_point = _space_point;
62 count = _count;
63 width = _width;
64 rollback = true;
65 }
66
67 void clear()
68 {
69 rollback = false;
70 }
71
72 bool empty() const
73 {
74 return !rollback;
75 }
76
77 float getWidth() const
78 {
79 MYGUI_DEBUG_ASSERT(rollback, "rollback point not valid");
80 return width;
81 }
82
83 size_t getCount() const
84 {
85 MYGUI_DEBUG_ASSERT(rollback, "rollback point not valid");
86 return count;
87 }
88
89 size_t getPosition() const
90 {
91 MYGUI_DEBUG_ASSERT(rollback, "rollback point not valid");
92 return position;
93 }
94
95 UString::const_iterator getTextIter() const
96 {
97 MYGUI_DEBUG_ASSERT(rollback, "rollback point not valid");
98 return space_point;
99 }
100
101 private:
102 size_t position;
103 UString::const_iterator space_point;
104 size_t count;
105 float width;
106 bool rollback;
107 };
108
109 TextView::TextView() :
110 mLength(0),
111 mFontHeight(0)
112 {
113 }
114
115 void TextView::update(const UString& _text, IFont* _font, int _height, Align _align, VertexColourType _format, int _maxWidth)
116 {
117 mFontHeight = _height;
118
119 // массив для быстрой конвертации цветов
120 static const char convert_colour[64] =
121 {
122 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
123 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
124 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
125 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0
126 };
127
128 mViewSize.clear();
129
130 RollBackPoint roll_back;
131 IntSize result;
132 float width = 0.0f;
133 size_t count = 0;
134 mLength = 0;
135 mLineInfo.clear();
136 LineInfo line_info;
137 int font_height = _font->getDefaultHeight();
138
139 UString::const_iterator end = _text.end();
140 UString::const_iterator index = _text.begin();
141
142 /*if (index == end)
143 return;*/
144
145 result.height += _height;
146
147 for (; index != end; ++index)
148 {
149 Char character = *index;
150
151 // новая строка
152 if (character == FontCodeType::CR
153 || character == FontCodeType::NEL
154 || character == FontCodeType::LF)
155 {
156 if (character == FontCodeType::CR)
157 {
158 UString::const_iterator peeki = index;
159 ++peeki;
160 if ((peeki != end) && (*peeki == FontCodeType::LF))
161 index = peeki; // skip both as one newline
162 }
163
164 line_info.width = (int)ceil(width);
165 line_info.count = count;
166 mLength += line_info.count + 1;
167
168 result.height += _height;
169 setMax(result.width, line_info.width);
170 width = 0;
171 count = 0;
172
173 mLineInfo.push_back(line_info);
174 line_info.clear();
175
176 // отменяем откат
177 roll_back.clear();
178
179 continue;
180 }
181 // тег
182 else if (character == L'#')
183 {
184 // берем следующий символ
185 ++ index;
186 if (index == end)
187 {
188 --index; // это защита
189 continue;
190 }
191
192 character = *index;
193 // если два подряд, то рисуем один шарп, если нет то меняем цвет
194 if (character != L'#')
195 {
196 // парсим первый символ
197 uint32 colour = convert_colour[(character - 48) & 0x3F];
198
199 // и еще пять символов после шарпа
200 for (char i = 0; i < 5; i++)
201 {
202 ++ index;
203 if (index == end)
204 {
205 --index; // это защита
206 continue;
207 }
208 colour <<= 4;
209 colour += convert_colour[ ((*index) - 48) & 0x3F ];
210 }
211
212 // если нужно, то меняем красный и синий компоненты
213 texture_utility::convertColour(colour, _format);
214
215 line_info.simbols.push_back( CharInfo(colour) );
216
217 continue;
218 }
219 }
220
221 GlyphInfo* info = _font->getGlyphInfo(character);
222
223 if (info == nullptr)
224 continue;
225
226 if (FontCodeType::Space == character)
227 {
228 roll_back.set(line_info.simbols.size(), index, count, width);
229 }
230 else if (FontCodeType::Tab == character)
231 {
232 roll_back.set(line_info.simbols.size(), index, count, width);
233 }
234
235 float char_width = info->width;
236 float char_height = info->height;
237 float char_advance = info->advance;
238 float char_bearingX = info->bearingX;
239 float char_bearingY = info->bearingY;
240
241 if (_height != font_height)
242 {
243 float scale = (float)_height / font_height;
244
245 char_width *= scale;
246 char_height *= scale;
247 char_advance *= scale;
248 char_bearingX *= scale;
249 char_bearingY *= scale;
250 }
251
252 float char_fullAdvance = char_bearingX + char_advance;
253
254 // перенос слов
255 if (_maxWidth != -1
256 && (width + char_fullAdvance) > _maxWidth
257 && !roll_back.empty())
258 {
259 // откатываем до последнего пробела
260 width = roll_back.getWidth();
261 count = roll_back.getCount();
262 index = roll_back.getTextIter();
263 line_info.simbols.erase(line_info.simbols.begin() + roll_back.getPosition(), line_info.simbols.end());
264
265 // запоминаем место отката, как полную строку
266 line_info.width = (int)ceil(width);
267 line_info.count = count;
268 mLength += line_info.count + 1;
269
270 result.height += _height;
271 setMax(result.width, line_info.width);
272 width = 0;
273 count = 0;
274
275 mLineInfo.push_back(line_info);
276 line_info.clear();
277
278 // отменяем откат
279 roll_back.clear();
280
281 continue;
282 }
283
284 line_info.simbols.push_back(CharInfo(info->uvRect, char_width, char_height, char_advance, char_bearingX, char_bearingY));
285 width += char_fullAdvance;
286 count ++;
287 }
288
289 line_info.width = (int)ceil(width);
290 line_info.count = count;
291 mLength += line_info.count;
292
293 mLineInfo.push_back(line_info);
294
295 setMax(result.width, line_info.width);
296
297 // теперь выравниванием строки
298 for (VectorLineInfo::iterator line = mLineInfo.begin(); line != mLineInfo.end(); ++line)
299 {
300 if (_align.isRight())
301 line->offset = result.width - line->width;
302 else if (_align.isHCenter())
303 line->offset = (result.width - line->width) / 2;
304 }
305
306 mViewSize = result;
307 }
308
309 size_t TextView::getCursorPosition(const IntPoint& _value)
310 {
311 const int height = mFontHeight;
312 size_t result = 0;
313 int top = 0;
314
315 for (VectorLineInfo::const_iterator line = mLineInfo.begin(); line != mLineInfo.end(); ++line)
316 {
317 // это последняя строка
318 bool lastline = !(line + 1 != mLineInfo.end());
319
320 // наша строчка
321 if (top + height > _value.top || lastline)
322 {
323 top += height;
324 float left = (float)line->offset;
325 int count = 0;
326
327 // ищем символ
328 for (VectorCharInfo::const_iterator sim = line->simbols.begin(); sim != line->simbols.end(); ++sim)
329 {
330 if (sim->isColour())
331 continue;
332
333 float fullAdvance = sim->getAdvance() + sim->getBearingX();
334 if (left + fullAdvance / 2.0f > _value.left)
335 {
336 break;
337 }
338 left += fullAdvance;
339 count ++;
340 }
341
342 result += count;
343 break;
344 }
345
346 if (!lastline)
347 {
348 top += height;
349 result += line->count + 1;
350 }
351 }
352
353 return result;
354 }
355
356 IntPoint TextView::getCursorPoint(size_t _position)
357 {
358 setMin(_position, mLength);
359
360 size_t position = 0;
361 int top = 0;
362 float left = 0.0f;
363 for (VectorLineInfo::const_iterator line = mLineInfo.begin(); line != mLineInfo.end(); ++line)
364 {
365 left = (float)line->offset;
366 if (position + line->count >= _position)
367 {
368 for (VectorCharInfo::const_iterator sim = line->simbols.begin(); sim != line->simbols.end(); ++sim)
369 {
370 if (sim->isColour())
371 continue;
372
373 if (position == _position)
374 break;
375
376 position ++;
377 left += sim->getBearingX() + sim->getAdvance();
378 }
379 break;
380 }
381 position += line->count + 1;
382 top += mFontHeight;
383 }
384
385 return IntPoint((int)left, top);
386 }
387
388 const IntSize& TextView::getViewSize() const
389 {
390 return mViewSize;
391 }
392
393 size_t TextView::getTextLength() const
394 {
395 return mLength;
396 }
397
398 const VectorLineInfo& TextView::getData() const
399 {
400 return mLineInfo;
401 }
402
403 } // namespace MyGUI
MyGUI::TextView::getTextLength
size_t getTextLength() const
Definition: MyGUI_TextView.cpp:393
MyGUI::TextView::getViewSize
const IntSize & getViewSize() const
Definition: MyGUI_TextView.cpp:388
MyGUI::uint32
unsigned int uint32
Definition: MyGUI_Types.h:63
MyGUI::types::TPoint< int >
MyGUI::GlyphInfo::advance
float advance
Definition: MyGUI_FontData.h:76
MyGUI_Precompiled.h
MyGUI::texture_utility::convertColour
__inline void convertColour(uint32 &_colour, VertexColourType _format)
Definition: MyGUI_TextureUtility.h:38
MyGUI::types::TSize< int >
MyGUI::VectorLineInfo
std::vector< LineInfo > VectorLineInfo
Definition: MyGUI_TextViewData.h:136
MyGUI::TextView::getData
const VectorLineInfo & getData() const
Definition: MyGUI_TextView.cpp:398
MyGUI::LineInfo::simbols
VectorCharInfo simbols
Definition: MyGUI_TextViewData.h:133
MyGUI::TextView::TextView
TextView()
Definition: MyGUI_TextView.cpp:109
MyGUI::GlyphInfo::bearingX
float bearingX
Definition: MyGUI_FontData.h:77
MyGUI::UString::const_iterator
_const_fwd_iterator const_iterator
const iterator
Definition: MyGUI_UString.h:435
MyGUI::UString::_const_fwd_iterator
const forward iterator for UString
Definition: MyGUI_UString.h:290
MyGUI::FontCodeType::CR
Definition: MyGUI_FontData.h:37
MyGUI::Align::isHCenter
bool isHCenter() const
Definition: MyGUI_Align.h:59
MyGUI::types::TPoint::top
T top
Definition: MyGUI_TPoint.h:36
MyGUI::FontCodeType::Tab
Definition: MyGUI_FontData.h:35
MyGUI::types::TSize::clear
void clear()
Definition: MyGUI_TSize.h:105
MyGUI::UString::begin
iterator begin()
returns an iterator to the first element of the string
Definition: MyGUI_UString.cpp:802
MyGUI::CharInfo
Definition: MyGUI_TextViewData.h:14
MyGUI::VertexColourType
Definition: MyGUI_RenderFormat.h:30
MyGUI::GlyphInfo::uvRect
FloatRect uvRect
Definition: MyGUI_FontData.h:79
MyGUI::IFont
Definition: MyGUI_IFont.h:35
MyGUI_TextView.h
MyGUI::types::TPoint::left
T left
Definition: MyGUI_TPoint.h:35
MyGUI::types::TSize::width
T width
Definition: MyGUI_TSize.h:35
MyGUI::FontCodeType::Space
Definition: MyGUI_FontData.h:38
MyGUI::Align::isRight
bool isRight() const
Definition: MyGUI_Align.h:79
MyGUI::Char
unsigned int Char
Definition: MyGUI_Types.h:66
MyGUI::LineInfo::width
int width
Definition: MyGUI_TextViewData.h:130
MyGUI::GlyphInfo::width
float width
Definition: MyGUI_FontData.h:74
MyGUI::TextView::getCursorPosition
size_t getCursorPosition(const IntPoint &_value)
Definition: MyGUI_TextView.cpp:309
MyGUI::GlyphInfo
Definition: MyGUI_FontData.h:53
MyGUI::GlyphInfo::height
float height
Definition: MyGUI_FontData.h:75
MyGUI::LineInfo::clear
void clear()
Definition: MyGUI_TextViewData.h:122
MyGUI::UString
A UTF-16 string with implicit conversion to/from std::string and std::wstring.
Definition: MyGUI_UString.h:169
MyGUI::TextView::getCursorPoint
IntPoint getCursorPoint(size_t _position)
Definition: MyGUI_TextView.cpp:356
MYGUI_DEBUG_ASSERT
#define MYGUI_DEBUG_ASSERT(exp, dest)
Definition: MyGUI_Diagnostic.h:83
MyGUI::IFont::getDefaultHeight
virtual int getDefaultHeight()=0
MyGUI::Align
Definition: MyGUI_Align.h:34
MyGUI::UString::end
iterator end()
returns an iterator just past the end of the string
Definition: MyGUI_UString.cpp:818
MyGUI::GlyphInfo::bearingY
float bearingY
Definition: MyGUI_FontData.h:78
MyGUI::types::TSize::height
T height
Definition: MyGUI_TSize.h:36
MyGUI::FontCodeType::NEL
Definition: MyGUI_FontData.h:39
MyGUI::LineInfo
Definition: MyGUI_TextViewData.h:113
MyGUI::IFont::getGlyphInfo
virtual GlyphInfo * getGlyphInfo(Char _id)=0
MyGUI::LineInfo::count
size_t count
Definition: MyGUI_TextViewData.h:132
MyGUI::TextView::update
void update(const UString &_text, IFont *_font, int _height, Align _align, VertexColourType _format, int _maxWidth=-1)
Definition: MyGUI_TextView.cpp:115
MyGUI::FontCodeType::LF
Definition: MyGUI_FontData.h:36
MyGUI::IntPoint
types::TPoint< int > IntPoint
Definition: MyGUI_Types.h:41