Mygui中文换行问题解决方案

伟大的大伟521

伟大的大伟521

2016-02-19 11:53

生活已是百般艰难,为何不努力一点。下面图老师就给大家分享Mygui中文换行问题解决方案,希望可以让热爱学习的朋友们体会到设计的小小的乐趣。
相信大家解决了中文输入后一定会遇到如何解决中文输入的问题,中文输入换行问题是很多gui框架都存在的一个问题,这里不废话了,大家打开mygui的引擎层中的widget的textview 的头文件和源文件将其替换为:
代码如下:

/*!
@file
@author Albert Semenov
@date 09/2009
*/
#ifndef __MYGUI_TEXT_VIEW_DATA_H__
#define __MYGUI_TEXT_VIEW_DATA_H__
#include "MyGUI_Prerequest.h"
namespace MyGUI
{
class CharInfo
{
public:
CharInfo() :
mIsColour(false)
{
mMetrics.mWidth = 0.0f;
mMetrics.mHeight = 0.0f;
mMetrics.mAdvance = 0.0f;
mMetrics.mBearingX = 0.0f;
mMetrics.mBearingY = 0.0f;
}
CharInfo(
const FloatRect& _rect,
float _width,
float _height,
float _advance,
float _bearingX,
float _bearingY) :
mIsColour(false),
mUVRect(_rect)
{
mMetrics.mWidth = _width;
mMetrics.mHeight = _height;
mMetrics.mAdvance = _advance;
mMetrics.mBearingX = _bearingX;
mMetrics.mBearingY = _bearingY;
}
CharInfo(uint32 _colour) :
mIsColour(true),
mColour(_colour)
{ }
bool isColour() const
{
return mIsColour;
}
float getWidth() const
{
return mMetrics.mWidth;
}
float getHeight() const
{
return mMetrics.mHeight;
}
float getAdvance() const
{
return mMetrics.mAdvance;
}
float getBearingX() const
{
return mMetrics.mBearingX;
}
float getBearingY() const
{
return mMetrics.mBearingY;
}
const FloatRect& getUVRect() const
{
return mUVRect;
}
uint32 getColour() const
{
return mColour;
}
private:
bool mIsColour;
FloatRect mUVRect;
struct Metrics
{
float mWidth;
float mHeight;
float mAdvance;
float mBearingX;
float mBearingY;
};
union
{
Metrics mMetrics;
uint32 mColour;
};
};
typedef std::vectorCharInfo VectorCharInfo;
//struct LineInfo
//{
// LineInfo() :
// width(0),
// offset(0),
// count(0)
// {
// }
// void clear()
// {
// width = 0;
// count = 0;
// simbols.clear();
// offset = 0;
// }
// int width;
// int offset;
// size_t count;
// VectorCharInfo simbols;
//};
struct LineInfo
{
LineInfo() :
width(0),
offset(0),
count(0),
offcount(0)
{
}
void clear()
{
offcount = 0;
width = 0;
count = 0;
simbols.clear();
offset = 0;
}
int offcount;
int width;
int offset;
size_t count;
VectorCharInfo simbols;
};
typedef std::vectorLineInfo VectorLineInfo;
} // namespace MyGUI
#endif // __MYGUI_TEXT_VIEW_DATA_H__

上面是头文件,下面是源文件:
代码如下:

/*!
@file
@author Albert Semenov
@date 09/2010
*/
/*
This file is part of MyGUI.
MyGUI is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
MyGUI is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with MyGUI. If not, see http://www.gnu.org/licenses/.
*/
#include "MyGUI_Precompiled.h"
#include "MyGUI_TextView.h"
namespace MyGUI
{
namespace
{
templatetypename T
void setMin(T& _var, const T& _newValue)
{
if (_newValue _var)
_var = _newValue;
}
templatetypename T
void setMax(T& _var, const T& _newValue)
{
if (_var _newValue)
_var = _newValue;
}
}
class RollBackPoint
{
public:
RollBackPoint() :
position(0),
count(0),
width(0),
rollback(false)
{
}
void set(size_t _position, UString::const_iterator& _space_point, size_t _count, float _width)
{
position = _position;
space_point = _space_point;
count = _count;
width = _width;
rollback = true;
}
void clear()
{
rollback = false;
}
bool empty() const
{
return !rollback;
}
float getWidth() const
{
MYGUI_DEBUG_ASSERT(rollback, "rollback point not valid");
return width;
}
size_t getCount() const
{
MYGUI_DEBUG_ASSERT(rollback, "rollback point not valid");
return count;
}
size_t getPosition() const
{
MYGUI_DEBUG_ASSERT(rollback, "rollback point not valid");
return position;
}
UString::const_iterator getTextIter() const
{
MYGUI_DEBUG_ASSERT(rollback, "rollback point not valid");
return space_point;
}
private:
size_t position;
UString::const_iterator space_point;
size_t count;
float width;
bool rollback;
};
TextView::TextView() :
mLength(0),
mFontHeight(0)
{
}
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;
mLength += line_info.offcount;
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;
}
// тег
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;
// перенос слов
if (_maxWidth != -1
&& (width + char_fullAdvance) _maxWidth
/*&& !roll_back.empty()*/)
{
--index;
// откатываем до последнего пробела
/*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();*/
// запоминаем место отката, как полную строку
line_info.width = (int)ceil(width);
line_info.count = count;
line_info.offcount = 0;
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;
}
size_t TextView::getCursorPosition(const IntPoint& _value)
{
const int height = mFontHeight;
size_t result = 0;
int top = 0;
for (VectorLineInfo::const_iterator line = mLineInfo.begin(); line != mLineInfo.end(); ++line)
{
// это последняя строка
bool lastline = !(line + 1 != mLineInfo.end());
// наша строчка
if (top + height _value.top || lastline)
{
top += height;
float left = (float)line-offset;
int count = 0;
// ищем символ
for (VectorCharInfo::const_iterator sim = line-simbols.begin(); sim != line-simbols.end(); ++sim)
{
if (sim-isColour())
continue;
float fullAdvance = sim-getAdvance() + sim-getBearingX();
if (left + fullAdvance / 2.0f _value.left)
{
break;
}
left += fullAdvance;
count ++;
}
result += count;
break;
}
if (!lastline)
{
top += height;
result += line-count + line-offcount;

}
}
return result;
}
IntPoint TextView::getCursorPoint(size_t _position)
{
setMin(_position, mLength);
size_t position = 0;
int top = 0;
float left = 0.0f;
for (VectorLineInfo::const_iterator line = mLineInfo.begin(); line != mLineInfo.end(); ++line)
{
left = (float)line-offset;
if (position + line-count = _position)
{
for (VectorCharInfo::const_iterator sim = line-simbols.begin(); sim != line-simbols.end(); ++sim)
{
if (sim-isColour())
continue;
if (position == _position)
break;
position ++;
left += sim-getBearingX() + sim-getAdvance();
}
break;
}
position += line-count + line-offcount;

top += mFontHeight;
}
return IntPoint((int)left, top);
}
const IntSize& TextView::getViewSize() const
{
return mViewSize;
}
size_t TextView::getTextLength() const
{
return mLength;
}
const VectorLineInfo& TextView::getData() const
{
return mLineInfo;
}
} // namespace MyGUI

修改了这两个以后,然后将edit控件改为多行支持和自动换行,这样就实现了mygui的中文自动换行问题。
展开更多 50%)
分享

猜你喜欢

Mygui中文换行问题解决方案

编程语言 网络编程
Mygui中文换行问题解决方案

JSP中文问题解决方案

Java JAVA基础
JSP中文问题解决方案

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

ajax中文乱码问题解决方案

Web开发
ajax中文乱码问题解决方案

jsp中文问题解决方案(完整版)

Web开发
jsp中文问题解决方案(完整版)

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

popupwindow焦点问题解决方案

编程语言 网络编程
popupwindow焦点问题解决方案

html编辑器的回车换行问题解决方案

Html CSS布局 Div+CSS XHTML
html编辑器的回车换行问题解决方案

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

C++类URL编码和解码使用技巧

C++类URL编码和解码使用技巧

PPT配色技巧揭秘

PPT配色技巧揭秘
下拉加载更多内容 ↓