給BGE加上了富文本顯示功能
相關代碼如下:
void GLTextRenderer::render(const Color& color,const String& string,const FloatRect& area,bool isMultiLine,
Horizontal hAlignment,Vertical vAlignment,bool rich)
{
if(typeFace_ != 0 && !rich)
{
typeFace_->setColor(color);
if(isMultiLine)
{
renderMultiline(color,string,area,hAlignment);
}
else
{
Vector2f position(typeFace_->penX(string,area,hAlignment),baseLineY(area,vAlignment));
typeFace_->render(string,position);
}
}
else if(typeFace_)
{
if(!isMultiLine)
{
auto cmdlist = parseString(string);
Vector2f position(typeFace_->penX(string,area,hAlignment),baseLineY(area,vAlignment));
typeFace_->render(String(),position,cmdlist);
}
else
{
auto cmdlist = parseString(string);
renderMultiline(color,cmdlist,area,hAlignment);
}
}
}
這里的parseString用于解析類似html的問題
函數實現如下:
std::list<textRenderCmdUnit> TextRenderer::parseString(const String& content)
{
String text(content);
std::list<textRenderCmdUnit> cmdList;
String current;
auto list = text.split('<');
for(int i=0;i<list.size();i++)
{
current = list[i];
if(current.startWith(L"/>"))
{
textRenderCmdUnit unit;
unit.undo = true;
cmdList.push_back(unit);
String remain = current.substr(2);
if(!remain.empty())
{
unit.text = remain;
unit.undo = false;
cmdList.push_back(unit);
}
}
else if(current.find('>') != String::InvalidPos)
{
textRenderCmdUnit unit;
unit.tag = current.substr(0,current.find('>'));
unit.undo = false;
cmdList.push_back(unit);
int32_t find = current.find('>');
if(find < current.size()-1)
{
unit.tag.clear();
unit.text = current.substr(find+1);
cmdList.push_back(unit);
}
}
else
{
textRenderCmdUnit unit;
unit.text = current;
unit.undo = false;
cmdList.push_back(unit);
}
}
return cmdList;
}
以下用于渲染富文本
void TypeFace::render(const FloatRect& area,const std::list<textRenderCmdUnit>& queue,Horizontal hAlignment,float vpos)
{
const float availableWidth = area.width_ - 2.0f;
textRenderCmdUnit unit;
String line,lineRemain;
String tag;
std::queue<String> cmdStack;
float y = vpos;
float x = penX(String(),area,hAlignment);
auto itr = queue.begin();
while(itr != queue.end())
{
unit = *itr;
if(unit.undo)
{
if(!cmdStack.empty())
{
tag = cmdStack.front();
cmdStack.pop();
if(tag == "bold")
bold_ = false;
else if(tag == "italic")
italic_ = false;
else if(tag == "underline")
underline_ = false;
else
applyColor(tag);
}
}
else if(!unit.tag.empty())
{
tag = unit.tag;
cmdStack.push(tag);
if(tag == "bold")
bold_ = true;
else if(tag == "italic")
italic_ = true;
else if(tag == "underline")
underline_ = true;
else
applyColor(tag);
}
else
{
line += unit.text;
while(true)
{
size_t pos = hitCharacterIndex(line,availableWidth-x);
if(pos == 0)
{
x = penX(String(),area,hAlignment);
y += lineHeight();
continue;
}
if(pos == String::InvalidPos)
pos = line.size();
String current = line.substr(0,pos);
lineRemain = line.substr(pos);
line = current;
auto linefeed = line.get().find_first_of('\n');
if(linefeed != std::basic_string<uint32_t>::npos)
{
line = line.substr(0,linefeed);
lineRemain = line.substr(linefeed+1) + lineRemain;
}
render(line,Vector2f(x,y),std::list<textRenderCmdUnit>());
x += width(line);
if(linefeed != String::InvalidPos)
{
x = penX(String(),area,hAlignment);
y += lineHeight();
}
line = lineRemain;
if(lineRemain.empty())
break;
}
}
itr ++;
}
}
以下渲染單色文本
void TypeFace::renderGlyphs(const std::list<textRenderCmdUnit>& cmd)
{
Vector2f position(0.0f,0.0f);
size_t leftChar = 0;
textRenderCmdUnit unit;
String tag;
std::queue<String> cmdStack;
std::list<textRenderCmdUnit>::const_iterator itr = cmd.begin();
while(itr != cmd.end())
{
unit = *itr;
if(unit.tag.empty() && !unit.undo)
{
position = renderGlyphs(unit.text,position);
}
else if(!unit.tag.empty())
{
tag = unit.tag;
cmdStack.push(tag);
if(tag == "bold")
bold_ = true;
else if(tag == "italic")
italic_ = true;
else if(tag == "underline")
underline_ = true;
else
applyColor(tag);
}
else if(unit.undo)
{
if(!cmdStack.empty())
{
tag = cmdStack.front();
cmdStack.pop();
if(tag == "bold")
bold_ = false;
else if(tag == "italic")
italic_ = false;
else if(tag == "underline")
underline_ = false;
else
applyColor(tag);
}
}
itr ++;
}
}
可以看出 支持的文本格式為<Tag>Text</>
一個例子是:
<Blue>這段代碼主要測試BGE的富文本顯示功能\n</Blue><Red>需要指出的是當前只要能支持多行顯示和多顏色顯示功能即可(不考慮下劃線斜體以及加粗顯示)。</Red><White>這句話將被顯示為白色</><Blue>這句話應該被藍色字體</Blue><Green>綠色字體</><Cyan>Cyan色</>";
最終顯示如下: