MyGUI自动换行(修正选区)

首先谢谢这位兄台给了一个思路。

http://blog.csdn.net/cparent/article/details/8230304?reload#cpp

但是这个有点问题,选中的区域有问题。

我这里是直接使用他的类似:

[code=C/C++]

<pre class="cpp" name="code">			if (FontCodeType::Space == character)
			{
				roll_back.set(line_info.simbols.size(), index, count, width);
			}

[/code]
 

的方法来达到换行目的。在

[code=C/C++]

			if(_maxWidth != -1
				&& (width + char_fullAdvance) > _maxWidth)
[/code]

这里加上换行标示,就可以了。但是由于这时候长度已经大于了,所以这个标示应该加在当前字符的前面。

找到前一个地点加换行。
 

现在逻辑是对的,但是选中的索引还有问题。

在MyGUI_EditText.cpp里

 void EditText::doRender()

原来每行都会把索引++。这里注释掉去掉。

MyGUI_TextView.cpp

里把回车加上一个虚的符号。

[code=C/C++]

    line_info.simbols.push_back(CharInfo());

[/code]

如下:

[code=C/C++]

	void TextView::update(const UString& _text, IFont* _font, int _height, Align _align, VertexColourType _format, int _maxWidth)
	{
		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;
		float width = 0.0f;
		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 = (int)ceil(width);
				line_info.count = count;
				mLength += line_info.count + 1;

				result.height += _height;
				setMax(result.width, line_info.width);
				width = 0;
				count = 0;

				<span style="color:#ff0000;">line_info.simbols.push_back(CharInfo());
</span>				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 (info == nullptr)
				continue;

			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);
			}

			float char_width = info->width;
			float char_height = info->height;
			float char_advance = info->advance;
			float char_bearingX = info->bearingX;
			float char_bearingY = info->bearingY;

			if (_height != font_height)
			{
				float scale = (float)_height / font_height;

				char_width *= scale;
				char_height *= scale;
				char_advance *= scale;
				char_bearingX *= scale;
				char_bearingY *= scale;
			}

			float char_fullAdvance = char_bearingX + char_advance;

<span style="color:#ff0000;">			if( (_maxWidth != -1) && 
				((width + char_fullAdvance) > _maxWidth) && 
				(_maxWidth>char_fullAdvance))
			{
				UString::const_iterator peeki_front = index;
				if (peeki_front!=_text.begin())
				{
					--peeki_front;
					GlyphInfo* info_front = _font->getGlyphInfo(*peeki_front);
					if (info_front)
					{
						float char_advance_front = info_front->advance;
						float char_bearingX_front = info_front->bearingX;

						if (_height != font_height)
						{
							float scale = (float)_height / font_height;

							char_advance_front *= scale;
							char_bearingX_front *= scale;
						}

						float char_fullAdvance_front = char_bearingX_front + char_advance_front;

						line_info.simbols.push_back(CharInfo(info->uvRect, char_width, char_height, char_advance, char_bearingX, char_bearingY));

						roll_back.set(line_info.simbols.size()-1, peeki_front, count-1, width-char_fullAdvance_front);

						width += char_fullAdvance;
					}					
				}
			}
</span>
			// перенос слов
			if (_maxWidth != -1
				&& (width + char_fullAdvance) > _maxWidth
				&& !roll_back.empty())
			{
				// откатываем до последнего пробела
				width = roll_back.getWidth();
				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 = (int)ceil(width);
				line_info.count = count;
				mLength += line_info.count + 1;

				result.height += _height;
				setMax(result.width, line_info.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, char_height, char_advance, char_bearingX, char_bearingY));
			width += char_fullAdvance;
			count ++;
		}

		line_info.width = (int)ceil(width);
		line_info.count = count;
		mLength += line_info.count;

		mLineInfo.push_back(line_info);

		setMax(result.width, line_info.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;
	}

[/code]

[code=C/C++]

	void EditText::doRender()
	{
		if (nullptr == mFont || !mVisible || mEmptyView)
			return;

		if (mRenderItem->getCurrentUpdate() || mTextOutDate)
			updateRawData();

		Vertex* vertex = mRenderItem->getCurrentVertexBuffer();

		const RenderTargetInfo& renderTargetInfo = mRenderItem->getRenderTarget()->getInfo();

		// колличество отрисованных вершин
		size_t vertexCount = 0;

		// текущие цвета
		uint32 colour = mCurrentColourNative;
		uint32 inverseColour = mInverseColourNative;
		uint32 selectedColour = mInvertSelect ? inverseColour : colour | 0x00FFFFFF;

		const VectorLineInfo& textViewData = mTextView.getData();

		float top = (float)(-mViewOffset.top + mCoord.top);

		FloatRect vertexRect;

		const FloatRect& selectedUVRect = mFont->getGlyphInfo(mBackgroundNormal ? FontCodeType::Selected : FontCodeType::SelectedBack)->uvRect;

		size_t index = 0;

		for (VectorLineInfo::const_iterator line = textViewData.begin(); line != textViewData.end(); ++line)
		{
			float left = (float)(line->offset - mViewOffset.left + mCoord.left);

			for (VectorCharInfo::const_iterator sim = line->simbols.begin(); sim != line->simbols.end(); ++sim)
			{
				if (sim->isColour())
				{
					colour = sim->getColour() | (colour & 0xFF000000);
					inverseColour = colour ^ 0x00FFFFFF;
					selectedColour = mInvertSelect ? inverseColour : colour | 0x00FFFFFF;
					continue;
				}

				// смещение текстуры для фона
				bool select = index >= mStartSelect && index < mEndSelect;

				float fullAdvance = sim->getBearingX() + sim->getAdvance();

				// Render the selection, if any, first.
				if (select)
				{
					vertexRect.set(left, top, left + fullAdvance, top + (float)mFontHeight);

					drawGlyph(renderTargetInfo, vertex, vertexCount, vertexRect, selectedUVRect, selectedColour);
				}

				// Render the glyph shadow, if any.
				if (mShadow)
				{
					vertexRect.left = left + sim->getBearingX() + 1.0f;
					vertexRect.top = top + sim->getBearingY() + 1.0f;
					vertexRect.right = vertexRect.left + sim->getWidth();
					vertexRect.bottom = vertexRect.top + sim->getHeight();

					drawGlyph(renderTargetInfo, vertex, vertexCount, vertexRect, sim->getUVRect(), mShadowColourNative);
				}

				// Render the glyph itself.
				vertexRect.left = left + sim->getBearingX();
				vertexRect.top = top + sim->getBearingY();
				vertexRect.right = vertexRect.left + sim->getWidth();
				vertexRect.bottom = vertexRect.top + sim->getHeight();

				drawGlyph(renderTargetInfo, vertex, vertexCount, vertexRect, sim->getUVRect(), (!select || !mInvertSelect) ? colour : inverseColour);

				left += fullAdvance;
				++index;
			}

			top += mFontHeight;
			<span style="color:#cc0000;">//++index;</span>
		}

		// Render the cursor, if any, last.
		if (mVisibleCursor)
		{
			IntPoint point = mTextView.getCursorPoint(mCursorPosition) - mViewOffset + mCoord.point();
			GlyphInfo* cursorGlyph = mFont->getGlyphInfo(static_cast<Char>(FontCodeType::Cursor));
			vertexRect.set((float)point.left, (float)point.top, (float)point.left + cursorGlyph->width, (float)(point.top + mFontHeight));

			drawGlyph(renderTargetInfo, vertex, vertexCount, vertexRect, cursorGlyph->uvRect, mCurrentColourNative | 0x00FFFFFF);
		}

		// колличество реально отрисованных вершин
		mRenderItem->setLastVertexCount(vertexCount);
	}

[/code]
MyGUI_TextViewData.h不要动


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值