MyGUI: MyGUI_TextView.cpp Source File

MyGUI 3.4.2

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

- File List
- Globals

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