Cpper
C/C++高级工程师 Android高级软件工程师 IT集成工程师 音频工程师 熟悉c,c++,java,c#,py,js,asp等多种语言 程序猿
给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色</>";
最终显示如下:
posted on 2016-02-22 17:46 ccsdu2009 阅读(337) 评论(0)  编辑 收藏 引用 所属分类: Game引擎设计模式

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理