Mygui中文换行问题解决方案

2016-02-19 11:53 27 1 收藏

生活已是百般艰难,为何不努力一点。下面图老师就给大家分享Mygui中文换行问题解决方案,希望可以让热爱学习的朋友们体会到设计的小小的乐趣。

【 tulaoshi.com - 编程语言 】

相信大家解决了中文输入后一定会遇到如何解决中文输入的问题,中文输入换行问题是很多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的中文自动换行问题。

来源:https://www.tulaoshi.com/n/20160219/1598983.html

延伸阅读
随着经济全球化的发展,产生了众多的跨国公司,而Java语言的出现以及网络通讯技术的飞速发展,使企业仅购买一套基于web的企业级应用软件(比如说:OA系统,ERP系统、CRM等),通过网络就能满足整个集团共同使用该软件成为可能。既减少了软件费用,又缩短了信息延迟,提高了企业运作效率。但因为应用系统是面向多个国家,多种语言的,所以在设计...
标签: 孕期
职场孕妈咪常见问题解决方案 现在的女性都比较独立,有自己的事业,很多女性在怀孕以后,出于这样那样的原因,依然无法远离工作岗位,不愿意在家里安心地养胎。这个时候在工作过程当中要注意什么,才能够更好地保护自己和保护肚子里的宝宝呢?我们一起来关注一下吧! 如果已经由医院方面确认说怀孕的话,应该将这件...
标签: 问题肌肤
角质型黑头鼻 黑头是白净肌肤的天敌,由于鼻头及其周围部分经常会有油脂分泌,若长时间清洁不到位,会使这些油脂硬化,经氧化后成为黑头。 常见肌肤问题解决方案:每周至少做1次针对鼻子的去角质工作,油性肌肤可每周2次,去角质后使用黑头导人液将黑矣粉刺自然导出(不要用手指等工具硬挤哦),洗净后拍上收敛型爽肤水收缩毛...
标签: 电脑入门
苹果电脑用bootcamp安装双系统,win7下,如果安装苹果自带的 bootcamp程序,或者bootcamp64. 则重启后将会蓝屏,报告驱动不兼容的问题。 网络上的解决思路是: 安好,重启,等待蓝屏重启。然后进入MacOSX系统,安装NTFS读取驱动paragon ntfs for mac。 然后重命名 C:/window/Systam32/driver32下的 applemtp.sys 以及 applemtn.sys 为其他...
标签: 女人 女性健康
女人最尴尬的9私处问题解决方案 现在的人们都追求健康,而大女人在追求健康的时候却忽略女人私处的健康保健。 女性最尴尬九个私处问题 1、阴道清洗有没有必要? 答:每天清洗外阴是有必要的,尤其是在月经期,用温开水适当清洗外阴,不让外界的病原体进入阴道,如非必要不要冲洗阴道,不需要用妇科洗液,维护女 性...

经验教程

483

收藏

7
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部