MyGUI: MyGUI_TextView.cpp Source File

MyGUI 3.4.3

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