Beispiel #1
0
	void TextView::update(const UString& _text, IFont* _font, int _height, Align _align, VertexColourType _format, int _maxheight)
	{
		mFontHeight = _height;

		// массив дл¤ быстрой конвертации цветов
		static const char convert_colour[64] =
		{
			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,
			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
		};

		mViewSize.clear();

		RollBackPoint roll_back;
		IntSize result;
		int width = 0;
		size_t count = 0;
		mLength = 0;
		mLineInfo.clear();
		LineInfo line_info;
		int font_height = _font->getDefaultHeight();

		UString::const_iterator end = _text.end();
		UString::const_iterator index = _text.begin();

		/*if (index == end)
			return;*/

		result.height += _height;

		for (; index != end; ++index)
		{
			Char character = *index;

			// нова¤ строка
			if (character == FontCodeType::CR
				|| character == FontCodeType::NEL
				|| character == FontCodeType::LF)
			{
				if (character == FontCodeType::CR)
				{
					UString::const_iterator peeki = index;
					++peeki;
					if ((peeki != end) && (*peeki == FontCodeType::LF))
						index = peeki; // skip both as one newline
				}

				line_info.width = width;
				line_info.count = count;
				mLength += line_info.count + 1;

				result.height += _height;
				if (result.width < width)
					result.width = width;
				width = 0;
				count = 0;

				mLineInfo.push_back(line_info);
				line_info.clear();

				// отмен¤ем откат
				roll_back.clear();

				continue;
			}
			// тег
			else if (character == L'#')
			{
				// берем следующий символ
				++ index;
				if (index == end)
				{
					--index;    // это защита
					continue;
				}

				character = *index;
				// если два подр¤д, то рисуем один шарп, если нет то мен¤ем цвет
				if (character != L'#')
				{
					// парсим первый символ
					uint32 colour = convert_colour[(character-48) & 0x3F];

					// и еще п¤ть символов после шарпа
					for (char i = 0; i < 5; i++)
					{
						++ index;
						if (index == end)
						{
							--index;    // это защита
							continue;
						}
						colour <<= 4;
						colour += convert_colour[ ((*index) - 48) & 0x3F ];
					}

					// если нужно, то мен¤ем красный и синий компоненты
					texture_utility::convertColour(colour, _format);

					line_info.simbols.push_back( CharInfo(colour) );

					continue;
				}
			}

			GlyphInfo* info = _font->getGlyphInfo(character);
			if (FontCodeType::Space == character)
			{
				roll_back.set(line_info.simbols.size(), index, count, width);
			}
			else if (FontCodeType::Tab == character)
			{
				roll_back.set(line_info.simbols.size(), index, count, width);
			}

			int char_width = info->width;
			if (font_height != _height)
			{
				char_width = char_width * _height / font_height;
				if (!char_width) char_width = 1;
			}

			// перенос слов
			if (_maxheight != -1
				&& (width + char_width) > _maxheight
				&& !roll_back.empty())
			{
				// откатываем до последнего пробела
				width = roll_back.getLenght();
				count = roll_back.getCount();
				index = roll_back.getTextIter();
				line_info.simbols.erase(line_info.simbols.begin() + roll_back.getPosition(), line_info.simbols.end());

				// запоминаем место отката, как полную строку
				line_info.width = width;
				line_info.count = count;
				mLength += line_info.count + 1;

				result.height += _height;
				if (result.width < width)
					result.width = width;
				width = 0;
				count = 0;

				mLineInfo.push_back(line_info);
				line_info.clear();

				// отмен¤ем откат
				roll_back.clear();

				continue;
			}

			line_info.simbols.push_back(CharInfo(info->uvRect, char_width));
			width += char_width;
			count ++;
		}

		line_info.width = width;
		line_info.count = count;
		mLength += line_info.count;

		mLineInfo.push_back(line_info);

		if (result.width < width)
			result.width = width;

		// теперь выравниванием строки
		for (VectorLineInfo::iterator line = mLineInfo.begin(); line != mLineInfo.end(); ++line)
		{
			if (_align.isRight())
				line->offset = result.width - line->width;
			else if (_align.isHCenter())
				line->offset = (result.width - line->width) / 2;
		}

		mViewSize = result;
	}