Mygui Chinese newline problem solution

  • 2020-04-01 21:30:37
  • OfStack

I believe that after you solve the Chinese input will encounter how to solve the Chinese input problem, the Chinese input line feed problem is a problem that many GUI frameworks exist, here is no nonsense, we open the mygui engine layer widget textview header file and source file to replace it:
 
/*! 
@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::vector<CharInfo> 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::vector<LineInfo> VectorLineInfo; 
} // namespace MyGUI 
#endif // __MYGUI_TEXT_VIEW_DATA_H__ 

Above is the header file, below is the source file:
 
/*! 
@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 
{ 
template<typename T> 
void setMin(T& _var, const T& _newValue) 
{ 
if (_newValue < _var) 
_var = _newValue; 
} 
template<typename 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; 
//  м а с с  и  kind guide   д л second   б ы с т р о й   Seem о н kind guide е р т а ц  и   и    ц kind guide е т о kind guide  
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(); 
 
result.height += _height; 
for (; index != end; ++index) 
{ 
Char character = *index; 
//  н о kind guide а second   с т р о seem а  
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(); 
//  о т м е н second е м   о т seem а т  
roll_back.clear(); 
continue; 
} 
//  т е f  
else if (character == L'#') 
{ 
//  б е р е м   с л е д ю щ  и  й   с  и  м kind guide о л  
++ index; 
if (index == end) 
{ 
--index; //  э т о   з а щ  и  т а  
continue; 
} 
character = *index; 
//  е с л  и    д kind guide а   п о д р second д ,  т о   р  и  с е м   о д  и  н   ш а р п ,  е с л  и    н е т   т о   м е н second е м   ц kind guide е т  
if (character != L'#') 
{ 
//  п а р с  и  м   п е р kind guide ы й   с  и  м kind guide о л  
uint32 colour = convert_colour[(character - 48) & 0x3F]; 
//  и   е щ е   п second т ь   с  и  м kind guide о л о kind guide   п о с л е   ш а р п а  
for (char i = 0; i < 5; i++) 
{ 
++ index; 
if (index == end) 
{ 
--index; //  э т о   з а щ  и  т а  
continue; 
} 
colour <<= 4; 
colour += convert_colour[ ((*index) - 48) & 0x3F ]; 
} 
//  е с л  и    н ж н о ,  т о   м е н second е м   Seem р а с н ы й   и   с  и  н  и  й   Seem о м п о н е н т ы  
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; 
//  п е р е н о с   с л о kind guide  
if (_maxWidth != -1 
&& (width + char_fullAdvance) > _maxWidth 
) 
{ 
--index; 
//  о т seem а т ы kind guide а е м   д о   п о с л е д н е f о   п р о б е л а  
 

//  з а п о м  и  н а е м   м е с т о   о т seem а т а ,  Seem а seem   п о л н ю   с т р о seem  
 
//  з а п о м  и  н а е м   м е с т о   о т seem а т а ,  Seem а seem   п о л н ю   с т р о seem  
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(); 
//  о т м е н second е м   о т seem а т  
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); 
//  т е п е р ь   Kind guide ы р а kind guide н  и  kind guide а н  и  е м   с т р о seem  и   
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) 
{ 
//  э т о   п о с л е д н second second   с т р о seem а  
bool lastline = !(line + 1 != mLineInfo.end()); 
//  н а ш а   с т р о discusses some related problems seem а  
if (top + height > _value.top || lastline) 
{ 
top += height; 
float left = (float)line->offset; 
int count = 0; 
//   и  щ е м   с  и  м kind guide о л  
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 

With these two modified, then change the edit control to multi-line support and line wrap, thus implementing mygui's Chinese line wrap problem.

Related articles: