CocoStudio控件实现富文本(附效果图)

这两天简单实现了一下富文本。主要用了网上找的一个HtmlParser类,非常感谢作者!
// HtmlParser类,用于解析HTML文本
// http://blog.csdn.net/liigo/article/details/6153829 (重要)
// by liigo, @2010-2012

主要麻烦的就在长文字换行,我用了比较粗暴的办法。先把文字放进UILabel,得到总长,然后setTextareaSize强制换行,计算行高和右偏移,然后继续添加下一个控件。A标签按钮和img标签图片的实现反而要简单一些,只要计算是否换行和右偏移。暂时只添加了项目里需要用到的,慢慢来

int HtmlLabel::setHtmlText(std::string htmltext,std::string& strback)
{
if(m_lastHtml==htmltext)
{
return m_textBottom;
}

m_lastHtml=htmltext;

clearHtml();

string_replace(htmltext,"\n","<br>");

liigo::HtmlParser htmlParser;
htmlParser.parseHtml(htmltext.c_str());
for(int index = 0, count = htmlParser.getHtmlNodeCount(); index < count; index++)
{
    liigo::HtmlNode* pNode = htmlParser.getHtmlNode(index);

    switch (pNode->type)
    {
    case NODE_START_TAG:
        {
            switch (pNode->tagType)
            {
            case TAG_FONT:
                {
                    if(pNode->attributeCount>0)
                    {
                        std::string text=liigo::HtmlParser::getAttributeStringValue(pNode,"color");
                        if(text!="")
                        {
                            m_color=getColor(text.substr(1));
                        }
                    }
                    index++;
                    liigo::HtmlNode* cNode = htmlParser.getHtmlNode(index);

                    if(cNode->type==NODE_CONTENT)
                    {
                        std::string content=cNode->text;
                        addNormalText(content,m_color);
                    }
                }
                break;
            case TAG_BR:
                {
                    m_textTop=m_textBottom;
                    m_textRight=0;
                }
                break;
            case TAG_A:
                {
                    std::string link;
                    if(pNode->attributeCount>0)
                    {
                        link=liigo::HtmlParser::getAttributeStringValue(pNode,"href");
                    }

                    index++;
                    liigo::HtmlNode* cNode = htmlParser.getHtmlNode(index);

                    if(cNode->type==NODE_CONTENT)
                    {
                        std::string content=cNode->text;
                        addLinkButton(content,link);
                    }
                }
                break;
            default:
                {

                }
                break;
            }
        }
        break;
    case NODE_CONTENT:
        {
            std::string content=pNode->text;
            addNormalText(content,m_color);
        }
        break;
    case NODE_END_TAG:
        {
            if(strcmp(pNode->tagName,"font")==0)
            {
                m_color=ccWHITE;
            }
        }
        break;
    default:
        {

        }
        break;
    }
}

return m_textBottom>m_constHeight?m_textBottom:m_constHeight;

}

void HtmlLabel::string_replace(std::string& strBig, const std::string & strsrc, const std::string &strdst)
{
std::string::size_type pos = 0;
while( (pos = strBig.find(strsrc, pos)) != std::string::npos)
{
strBig.replace(pos, strsrc.length(), strdst);
pos += strdst.length();
}
}

ccColor3B HtmlLabel::getColor(std::string str)
{
int r,g,b;
sscanf(str.substr(1,2).c_str(),"%x",&r);
sscanf(str.substr(3,2).c_str(),"%x",&g);
sscanf(str.substr(5,2).c_str(),"%x",&b);
return ccc3(r,g,b);
}

int HtmlLabel::addNormalText(std::string content,ccColor3B color)
{
UILabel* label=UILabel::create();
label->setFontSize(m_fontSize);
label->setFontName(m_fontName);
label->setColor(color);

label->setText(content.c_str());
int textLength=label->getSize().width;

std::string spaceText=getSpaceOfNumber(m_textRight/m_spaceLength);
content=spaceText+content;
label->setText(content.c_str());
int totalLength=label->getSize().width;

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
totalLength*=1.1;
#endif

label->setAnchorPoint(ccp(0,1));
label->setPosition(ccp(0,-m_textTop));
addChild(label);

int lastLegth=totalLength%m_constWidth;

if(m_textRight+textLength>m_constWidth)
{
    m_textRight=lastLegth+(totalLength/m_constWidth)*10;
    label->setTextAreaSize(CCSizeMake(m_constWidth,0));
    m_textBottom=m_textTop+label->getSize().height+10;
    m_textTop=m_textBottom-m_spaceHeight-10;
}
else
{
    m_textRight=lastLegth;
    if(m_textTop+label->getSize().height>m_textBottom)
    {
        m_textBottom=m_textTop+label->getSize().height+10;
    }
}

return 0;

}

楼主很棒,谢谢分享:782:

这个一定要顶!

这个要顶!

赞哇,支持支持

还没有试过富文本,估计以后会用,先支持一下~~~