Cocos2dx-- 聊天系统之富文本(RichText)与字体对齐

前端之家收集整理的这篇文章主要介绍了Cocos2dx-- 聊天系统之富文本(RichText)与字体对齐前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

游戏开发中我们一般都会有聊天系统,我们可以同时或单独发文字图片,表情,超链接等信息的文本即称为富文本。如下图所示:

我使用的是cocos-3.4引擎版本里的RichText富文本控件实现这些操作的,但cocos自带封装的RichText还有一些问题,1:如上图看到的一样,当中英文混输时右边字体没对齐(看需求,QQ都没处理这问题)。2:聊天信息有时会需求像上面一样还要一个背景底框装着,底框大小随发送内容变化,这时我们就需要知道富文本的宽度和高度而cocos的RichText没有封装这个接口需要我们自己扩展。本章就讲讲怎么来解决这两个问题。

解决步骤

1,在UIRichText.h中新增获取富文本大小接口

public:
Size xxgetRealSize();
Size xxrealSize;

2,默认右没不齐是因为它的换行是根据字的平均长度来计算的,即单个字长度=总长度/总字数,而不同字的宽度是很可能不相同的。现在我的改法是:循环计算出每个字的大小求和换行,当然这样的效率是比默认的低,所以这个对齐还是看需求,有的QQ消息也没处理这个对齐问题。下面是UIRichText.cpp修改后的完整代码,有注释,修改处都用@cxx标记了。

/**************************************************************************** Copyright (c) 2013 cocos2d-x.org http://www.cocos2d-x.org Permission is hereby granted,free of charge,to any person obtaining a copy of this software and associated documentation files (the "Software"),to deal in the Software without restriction,including without limitation the rights to use,copy,modify,merge,publish,distribute,sublicense,and/or sell copies of the Software,and to permit persons to whom the Software is furnished to do so,subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER LIABILITY,WHETHER IN AN ACTION OF CONTRACT,TORT OR OTHERWISE,ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ****************************************************************************/@H_404_22@

#include "UIRichText.h"@H_404_22@
#include "platform/CCFileUtils.h"@H_404_22@
#include "2d/CCLabel.h"@H_404_22@
#include "2d/CCSprite.h"@H_404_22@
#include "base/ccUTF8.h"@H_404_22@
#include "ui/UIHelper.h"@H_404_22@

#include "platform/CCDevice.h" //@cxx@H_404_22@@H_404_22@
#include "base/ccMacros.h" //@cxx@H_404_22@@H_404_22@
#include "base/CCDirector.h" //@cxx@H_404_22@@H_404_22@

NS_CC_BEGIN

namespace@H_404_22@ ui {


bool@H_404_22@ RichElement::init(int@H_404_22@ tag,const@H_404_22@ Color3B &color,GLubyte opacity)
{
    _tag = tag;
    _color = color;
    _opacity = opacity;
    return@H_404_22@ true@H_404_22@;
}


RichElementText* RichElementText::create(int@H_404_22@ tag,GLubyte opacity,const@H_404_22@ std@H_404_22@::string@H_404_22@& text,const@H_404_22@ std@H_404_22@::string@H_404_22@& fontName,float@H_404_22@ fontSize)
{
    RichElementText* element = new@H_404_22@ (std@H_404_22@::nothrow) RichElementText();
    if@H_404_22@ (element && element->init(tag,color,opacity,text,fontName,fontSize))
    {
        element->autorelease();
        return@H_404_22@ element;
    }
    CC_SAFE_DELETE(element);
    return@H_404_22@ nullptr@H_404_22@;
}

bool@H_404_22@ RichElementText::init(int@H_404_22@ tag,float@H_404_22@ fontSize)
{
    if@H_404_22@ (RichElement::init(tag,opacity))
    {
        _text = text;
        _fontName = fontName;
        _fontSize = fontSize;
        return@H_404_22@ true@H_404_22@;
    }
    return@H_404_22@ false@H_404_22@;
}

RichElementImage* RichElementImage::create(int@H_404_22@ tag,const@H_404_22@ std@H_404_22@::string@H_404_22@& filePath)
{
    RichElementImage* element = new@H_404_22@ (std@H_404_22@::nothrow) RichElementImage();
    if@H_404_22@ (element && element->init(tag,filePath))
    {
        element->autorelease();
        return@H_404_22@ element;
    }
    CC_SAFE_DELETE(element);
    return@H_404_22@ nullptr@H_404_22@;
}

bool@H_404_22@ RichElementImage::init(int@H_404_22@ tag,const@H_404_22@ std@H_404_22@::string@H_404_22@& filePath)
{
    if@H_404_22@ (RichElement::init(tag,opacity))
    {
        _filePath = filePath;
        return@H_404_22@ true@H_404_22@;
    }
    return@H_404_22@ false@H_404_22@;
}

RichElementCustomNode* RichElementCustomNode::create(int@H_404_22@ tag,cocos2d::Node *customNode)
{
    RichElementCustomNode* element = new@H_404_22@ (std@H_404_22@::nothrow) RichElementCustomNode();
    if@H_404_22@ (element && element->init(tag,customNode))
    {
        element->autorelease();
        return@H_404_22@ element;
    }
    CC_SAFE_DELETE(element);
    return@H_404_22@ nullptr@H_404_22@;
}

bool@H_404_22@ RichElementCustomNode::init(int@H_404_22@ tag,cocos2d::Node *customNode)
{
    if@H_404_22@ (RichElement::init(tag,opacity))
    {
        _customNode = customNode;
        _customNode->retain();
        return@H_404_22@ true@H_404_22@;
    }
    return@H_404_22@ false@H_404_22@;
}

RichText::RichText():
_formatTextDirty(true@H_404_22@),_leftSpaceWidth(0.0f@H_404_22@),_verticalSpace(0.0f@H_404_22@),_elementRenderersContainer(nullptr@H_404_22@)
{

}

RichText::~RichText()
{
    _richElements.clear();
}

RichText* RichText::create()
{
    RichText* widget = new@H_404_22@ (std@H_404_22@::nothrow) RichText();
    if@H_404_22@ (widget && widget->init())
    {
        widget->autorelease();
        return@H_404_22@ widget;
    }
    CC_SAFE_DELETE(widget);
    return@H_404_22@ nullptr@H_404_22@;
}

bool@H_404_22@ RichText::init()
{
    if@H_404_22@ (Widget::init())
    {
        return@H_404_22@ true@H_404_22@;
    }
    return@H_404_22@ false@H_404_22@;
}

void@H_404_22@ RichText::initRenderer()
{
    _elementRenderersContainer = Node::create();
    _elementRenderersContainer->setAnchorPoint(Vec2(0.5f@H_404_22@,0.5f@H_404_22@));
    addProtectedChild(_elementRenderersContainer,0@H_404_22@,-1@H_404_22@);
}

void@H_404_22@ RichText::insertElement(RichElement *element,int@H_404_22@ index)
{
    _richElements.insert(index,element);
    _formatTextDirty = true@H_404_22@;
}

void@H_404_22@ RichText::pushBackElement(RichElement *element)
{
    _richElements.pushBack(element);
    _formatTextDirty = true@H_404_22@;
}

void@H_404_22@ RichText::removeElement(int@H_404_22@ index)
{
    _richElements.erase(index);
    _formatTextDirty = true@H_404_22@;
}

void@H_404_22@ RichText::removeElement(RichElement *element)
{
    _richElements.eraSEObject(element);
    _formatTextDirty = true@H_404_22@;
}

    //渲染富文本@H_404_22@
void@H_404_22@ RichText::formatText()
{
    if@H_404_22@ (_formatTextDirty)
    {
        _elementRenderersContainer->removeAllChildren();
        _elementRenders.clear();
        if@H_404_22@ (_ignoreSize) //是否忽略换行@H_404_22@
        {
            addNewLine();
            for@H_404_22@ (ssize_t i=0@H_404_22@; i<_richElements.size(); i++)
            {
                RichElement* element = _richElements.at(i);
                Node* elementRenderer = nullptr@H_404_22@;
                switch@H_404_22@ (element->_type)
                {
                    case@H_404_22@ RichElement::Type::TEXT:
                    {
                        RichElementText* elmtText = static_cast@H_404_22@<RichElementText*>(element);
                        if@H_404_22@ (FileUtils::getInstance()->isFileExist(elmtText->_fontName))
                        {
                            elementRenderer = Label::createWithTTF(elmtText->_text.c_str(),elmtText->_fontName,elmtText->_fontSize);
                        }
                        else@H_404_22@
                        {
                            elementRenderer = Label::createWithSystemFont(elmtText->_text.c_str(),elmtText->_fontSize);
                        }
                        break@H_404_22@;
                    }
                    case@H_404_22@ RichElement::Type::IMAGE:
                    {
                        RichElementImage* elmtImage = static_cast@H_404_22@<RichElementImage*>(element);
                        elementRenderer = Sprite::create(elmtImage->_filePath.c_str());
                        break@H_404_22@;
                    }
                    case@H_404_22@ RichElement::Type::CUSTOM:
                    {
                        RichElementCustomNode* elmtCustom = static_cast@H_404_22@<RichElementCustomNode*>(element);
                        elementRenderer = elmtCustom->_customNode;
                        break@H_404_22@;
                    }
                    default@H_404_22@:
                        break@H_404_22@;
                }
                elementRenderer->setColor(element->_color);
                elementRenderer->setOpacity(element->_opacity);
                pushToContainer(elementRenderer);
            }
        }
        else@H_404_22@
        {
            addNewLine();
            for@H_404_22@ (ssize_t i=0@H_404_22@; i<_richElements.size(); i++)
            {

                RichElement* element = static_cast@H_404_22@<RichElement*>(_richElements.at(i));
                switch@H_404_22@ (element->_type)
                {
                    case@H_404_22@ RichElement::Type::TEXT:
                    {
                        RichElementText* elmtText = static_cast@H_404_22@<RichElementText*>(element);
                        handleTextRenderer(elmtText->_text.c_str(),elmtText->_fontName.c_str(),elmtText->_fontSize,elmtText->_color,elmtText->_opacity);
                        break@H_404_22@;
                    }
                    case@H_404_22@ RichElement::Type::IMAGE:
                    {
                        RichElementImage* elmtImage = static_cast@H_404_22@<RichElementImage*>(element);
                        handleImageRenderer(elmtImage->_filePath.c_str(),elmtImage->_color,elmtImage->_opacity);
                        break@H_404_22@;
                    }
                    case@H_404_22@ RichElement::Type::CUSTOM:
                    {
                        RichElementCustomNode* elmtCustom = static_cast@H_404_22@<RichElementCustomNode*>(element);
                        handleCustomRenderer(elmtCustom->_customNode);
                        break@H_404_22@;
                    }
                    default@H_404_22@:
                        break@H_404_22@;
                }
            }
        }
        formarRenderers();
        _formatTextDirty = false@H_404_22@;
    }
}

//begin @cxx 得到一行文字的个数@H_404_22@
bool@H_404_22@ s_getLineTextNumber(const@H_404_22@ std@H_404_22@::string@H_404_22@& text,float@H_404_22@ fontSize,float@H_404_22@ rowWidth,int@H_404_22@ &textNumber)
{
    bool@H_404_22@ ret =  true@H_404_22@ ;
    float@H_404_22@ maxW = rowWidth ;
    int@H_404_22@ count = 0@H_404_22@ ;

    while@H_404_22@(true@H_404_22@)
    {
        std@H_404_22@::string@H_404_22@ tempChar = Helper::getSubStringOfUTF8String(text,count,1@H_404_22@);  //截取字符串@H_404_22@
        float@H_404_22@ tempW,tempH ;
        if@H_404_22@(tempChar.length() == 0@H_404_22@ )
        {
            break@H_404_22@ ;
        }
        bool@H_404_22@ bSuccess = Device::CalculateTextSize(tempChar.c_str(),fontName.c_str(),fontSize,tempW,tempH);
        if@H_404_22@( !bSuccess )
        {
            ret = false@H_404_22@ ;
            break@H_404_22@ ;
        }
        //tempW = tempW / CC_CONTENT_SCALE_FACTOR();@H_404_22@

        maxW -= tempW ;
        if@H_404_22@(maxW< -tempW / 2@H_404_22@)
        {
            break@H_404_22@ ;
        }
        count++ ;
    }

    textNumber = count ;

    return@H_404_22@ ret ;
}
//end @cxx@H_404_22@

void@H_404_22@ RichText::handleTextRenderer(const@H_404_22@ std@H_404_22@::string@H_404_22@& text,GLubyte opacity)
{
    auto@H_404_22@ fileExist = FileUtils::getInstance()->isFileExist(fontName);
    Label* textRenderer = nullptr@H_404_22@;
    if@H_404_22@ (fileExist)
    {
        textRenderer = Label::createWithTTF(text,fontSize);
    } 
    else@H_404_22@
    {
        textRenderer = Label::createWithSystemFont(text,fontSize);
    }
    float@H_404_22@ textRendererWidth = textRenderer->getContentSize().width;
    float@H_404_22@ saveLeftSpaceWidth = _leftSpaceWidth ; //@cxx@H_404_22@
    _leftSpaceWidth -= textRendererWidth;
    if@H_404_22@ (_leftSpaceWidth < 0.0f@H_404_22@)
    {
        float@H_404_22@ overstepPercent = (-_leftSpaceWidth) / textRendererWidth;
        std@H_404_22@::string@H_404_22@ curText = text;
        size_t stringLength = StringUtils::getCharacterCountInUTF8String(text);

        //原来代码(原来是求出整个文字长度和文字个数,用平均长度作为每个字长度,所以混输对不齐)@H_404_22@
        //int leftLength = stringLength * (1.0f - overstepPercent);@H_404_22@
        //std::string leftWords = Helper::getSubStringOfUTF8String(curText,leftLength);@H_404_22@
        //std::string cutWords = Helper::getSubStringOfUTF8String(curText,leftLength,stringLength - leftLength);@H_404_22@

        //begin @cxx 现在改为循环计算每个字的长度@H_404_22@
        int@H_404_22@ leftLength = 0@H_404_22@ ;
        std@H_404_22@::string@H_404_22@ leftWords = ""@H_404_22@ ;
        std@H_404_22@::string@H_404_22@ cutWords = ""@H_404_22@ ;

        float@H_404_22@ rowWidth = saveLeftSpaceWidth ; //_customSize.width ;@H_404_22@
        int@H_404_22@ textNumber = 0@H_404_22@  ;
        if@H_404_22@( s_getLineTextNumber( curText,rowWidth,textNumber) )//计算一行多少字@H_404_22@
        {
            leftLength = textNumber ;
            leftWords = Helper::getSubStringOfUTF8String(curText,leftLength);
            cutWords = Helper::getSubStringOfUTF8String(curText,stringLength - leftLength);
        }
        else@H_404_22@
        {
            leftLength = stringLength * (1.0f@H_404_22@ - overstepPercent);
            leftWords = Helper::getSubStringOfUTF8String(curText,stringLength - leftLength);
        }
        //end of @cxx@H_404_22@

        if@H_404_22@ (leftLength > 0@H_404_22@)
        {
            Label* leftRenderer = nullptr@H_404_22@;
            if@H_404_22@ (fileExist)
            {
                leftRenderer = Label::createWithTTF(Helper::getSubStringOfUTF8String(leftWords,leftLength),fontSize);
            }
            else@H_404_22@
            {
                leftRenderer = Label::createWithSystemFont(Helper::getSubStringOfUTF8String(leftWords,fontSize);
            }
            if@H_404_22@ (leftRenderer)
            {
                leftRenderer->setColor(color);
                leftRenderer->setOpacity(opacity);
                pushToContainer(leftRenderer);
            }
        }

        addNewLine();
        handleTextRenderer(cutWords.c_str(),opacity);
    }
    else@H_404_22@
    {
        textRenderer->setColor(color);
        textRenderer->setOpacity(opacity);
        pushToContainer(textRenderer);
    }
}

void@H_404_22@ RichText::handleImageRenderer(const@H_404_22@ std@H_404_22@::string@H_404_22@& fileParh,GLubyte opacity)
{
    Sprite* imageRenderer = Sprite::create(fileParh);
    handleCustomRenderer(imageRenderer);
}

void@H_404_22@ RichText::handleCustomRenderer(cocos2d::Node *renderer)
{
    Size imgSize = renderer->getContentSize();
    _leftSpaceWidth -= imgSize.width;
    if@H_404_22@ (_leftSpaceWidth < 0.0f@H_404_22@)
    {
        addNewLine();
        pushToContainer(renderer);
        _leftSpaceWidth -= imgSize.width;
    }
    else@H_404_22@
    {
        pushToContainer(renderer);
    }
}

void@H_404_22@ RichText::addNewLine()
{
    _leftSpaceWidth = _customSize.width;
    _elementRenders.push_back(new@H_404_22@ Vector<Node*>());
}

void@H_404_22@ RichText::formarRenderers()
{
    if@H_404_22@ (_ignoreSize)
    {
        float@H_404_22@ newContentSizeWidth = 0.0f@H_404_22@;
        float@H_404_22@ newContentSizeHeight = 0.0f@H_404_22@;

        Vector<Node*>* row = (_elementRenders[0@H_404_22@]);
        float@H_404_22@ nextPosX = 0.0f@H_404_22@;
        for@H_404_22@ (ssize_t j=0@H_404_22@; j<row->size(); j++)
        {
            Node* l = row->at(j);
            l->setAnchorPoint(Vec2::ZERO);
            l->setPosition(nextPosX,0.0f@H_404_22@);
            _elementRenderersContainer->addChild(l,1@H_404_22@);
            Size iSize = l->getContentSize();
            newContentSizeWidth += iSize.width;
            newContentSizeHeight = MAX(newContentSizeHeight,iSize.height);
            nextPosX += iSize.width;
        }
        _elementRenderersContainer->setContentSize(Size(newContentSizeWidth,newContentSizeHeight));
    }
    else@H_404_22@
    {
        float@H_404_22@ newContentSizeHeight = 0.0f@H_404_22@;
        float@H_404_22@ *maxHeights = new@H_404_22@ float@H_404_22@[_elementRenders.size()];

        for@H_404_22@ (size_t i=0@H_404_22@; i<_elementRenders.size(); i++)
        {
            Vector<Node*>* row = (_elementRenders[i]);
            float@H_404_22@ maxHeight = 0.0f@H_404_22@;
            for@H_404_22@ (ssize_t j=0@H_404_22@; j<row->size(); j++)
            {
                Node* l = row->at(j);
                maxHeight = MAX(l->getContentSize().height,maxHeight);
            }
            maxHeights[i] = maxHeight;
            newContentSizeHeight += maxHeights[i];
        }


        float@H_404_22@ nextPosY = _customSize.height;
        float@H_404_22@ realWidth = 0@H_404_22@ ;  //@cxx@H_404_22@
        for@H_404_22@ (size_t i=0@H_404_22@; i<_elementRenders.size(); i++)
        {
            Vector<Node*>* row = (_elementRenders[i]);
            float@H_404_22@ nextPosX = 0.0f@H_404_22@;
            nextPosY -= (maxHeights[i] + _verticalSpace);

            for@H_404_22@ (ssize_t j=0@H_404_22@; j<row->size(); j++)
            {
                Node* l = row->at(j);
                l->setAnchorPoint(Vec2::ZERO);
                l->setPosition(nextPosX,nextPosY);
                _elementRenderersContainer->addChild(l,1@H_404_22@);
                nextPosX += l->getContentSize().width;
            }

            if@H_404_22@( realWidth < nextPosX ) //@cxx@H_404_22@
            {
                realWidth = nextPosX ;//@cxx@H_404_22@
            }
        }

        float@H_404_22@ realHeight = _customSize.height - nextPosY;   //@cxx@H_404_22@

        //富文本真实宽高@H_404_22@
        this@H_404_22@->xxrealSize.height = realHeight;               //@cxx@H_404_22@
        this@H_404_22@->xxrealSize.width = realWidth ; //_contentSize.width; //@cxx@H_404_22@

        _elementRenderersContainer->setContentSize(_contentSize);
        delete@H_404_22@ [] maxHeights;
    }

    size_t length = _elementRenders.size();
    for@H_404_22@ (size_t i = 0@H_404_22@; i<length; i++)
    {
        Vector<Node*>* l = _elementRenders[i];
        l->clear();
        delete@H_404_22@ l;
    }    
    _elementRenders.clear();

    if@H_404_22@ (_ignoreSize)
    {
        Size s = getVirtualRendererSize();
        this@H_404_22@->setContentSize(s);
    }
    else@H_404_22@
    {
        this@H_404_22@->setContentSize(_customSize);
    }
    updateContentSizeWithTextureSize(_contentSize);
    _elementRenderersContainer->setPosition(_contentSize.width / 2.0f@H_404_22@,_contentSize.height / 2.0f@H_404_22@);
}

//获得富文本大小@H_404_22@
Size RichText::xxgetRealSize()//@cxx@H_404_22@
{
    //this->xxrealSize = this->getContentSize();@H_404_22@
    this@H_404_22@->formatText();   //需要手动调用@H_404_22@
    return@H_404_22@ this@H_404_22@->xxrealSize;
}

//下帧drawScene时调用(基类调过来),这里是富文本渲染入口@H_404_22@
void@H_404_22@ RichText::adaptRenderers()
{
    this@H_404_22@->formatText();
}

void@H_404_22@ RichText::pushToContainer(cocos2d::Node *renderer)
{
    if@H_404_22@ (_elementRenders.size() <= 0@H_404_22@)
    {
        return@H_404_22@;
    }
    _elementRenders[_elementRenders.size()-1@H_404_22@]->pushBack(renderer);
}

void@H_404_22@ RichText::setVerticalSpace(float@H_404_22@ space)
{
    _verticalSpace = space;
}

void@H_404_22@ RichText::setAnchorPoint(const@H_404_22@ Vec2 &pt)
{
    Widget::setAnchorPoint(pt);
    _elementRenderersContainer->setAnchorPoint(pt);
}

Size RichText::getVirtualRendererSize() const@H_404_22@
{
    return@H_404_22@ _elementRenderersContainer->getContentSize();
}

void@H_404_22@ RichText::ignoreContentAdaptWithSize(bool@H_404_22@ ignore)
{
    if@H_404_22@ (_ignoreSize != ignore)
    {
        _formatTextDirty = true@H_404_22@;
        Widget::ignoreContentAdaptWithSize(ignore);
    }
}

std@H_404_22@::string@H_404_22@ RichText::getDescription() const@H_404_22@
{
    return@H_404_22@ "RichText"@H_404_22@;
}

}

NS_CC_END

3,getSubStringOfUTF8String这个截取字符串的接口要修改,它的返回值不对。

std@H_404_22@::string@H_404_22@ Helper::getSubStringOfUTF8String(const@H_404_22@ std@H_404_22@::string@H_404_22@& str,std@H_404_22@::string@H_404_22@::size_type start,std@H_404_22@::string@H_404_22@::size_type length)
{
    if@H_404_22@ (length==0@H_404_22@)
    {
        return@H_404_22@ ""@H_404_22@;
    }
    std@H_404_22@::string@H_404_22@::size_type c,i,ix,q,min=std@H_404_22@::string@H_404_22@::npos,max=std@H_404_22@::string@H_404_22@::npos;
    for@H_404_22@ (q=0@H_404_22@,i=0@H_404_22@,ix=str.length(); i < ix; i++,q++)
    {
        if@H_404_22@ (q==start)
        {
            min = i;
        }
        if@H_404_22@ (q <= start+length || length==std@H_404_22@::string@H_404_22@::npos)   //结束是以start位置开始,所以截取是min->max-min@H_404_22@
        {
            max = i;
        }

        c = (unsigned@H_404_22@ char@H_404_22@) str[i];

        if@H_404_22@      (c<=127@H_404_22@) i+=0@H_404_22@;
        else@H_404_22@ if@H_404_22@ ((c & 0xE0@H_404_22@) == 0xC0@H_404_22@) i+=1@H_404_22@;
        else@H_404_22@ if@H_404_22@ ((c & 0xF0@H_404_22@) == 0xE0@H_404_22@) i+=2@H_404_22@;
        else@H_404_22@ if@H_404_22@ ((c & 0xF8@H_404_22@) == 0xF0@H_404_22@) i+=3@H_404_22@;
        else@H_404_22@ return@H_404_22@ ""@H_404_22@;//invalid utf8@H_404_22@
    }
    if@H_404_22@ (q <= start+length || length == std@H_404_22@::string@H_404_22@::npos)
    {
        max = i;
    }
    if@H_404_22@ (min==std@H_404_22@::string@H_404_22@::npos || max==std@H_404_22@::string@H_404_22@::npos)
    {
        return@H_404_22@ ""@H_404_22@;
    }
    return@H_404_22@ str.substr(min,max-min);  //@cxx 原来是: return str.substr(min,max);@H_404_22@
}

4,在CCDevice.h中新增计算字体大小的接口,具体实现和平台相关,这里我只实现的ios平台。

static bool CalculateTextSize(const char * text,const char * fontName,float size,float &width,float &height ) ; //@cxx

5,ios平台CalculateTextSize的实现

//@cxx begin@H_404_22@
static@H_404_22@ CGSize@H_404_22@ _my_calculateStringSize(NSString@H_404_22@ *str,id@H_404_22@ font,CGSize@H_404_22@ *constrainSize)
{
    CGSize@H_404_22@ textRect = CGSizeZero;
    textRect.width@H_404_22@ = constrainSize->width > 0@H_404_22@ ? constrainSize->width
    : 0x7fffffff@H_404_22@;
    textRect.height@H_404_22@ = constrainSize->height > 0@H_404_22@ ? constrainSize->height
    : 0x7fffffff@H_404_22@;


    CGSize@H_404_22@ dim;
    if@H_404_22@(s_isIOS7OrHigher){
        NSDictionary@H_404_22@ *attibutes = @{NSFontAttributeName:font};
        dim = [str boundingRectWithSize:textRect options:(NSStringDrawingOptions)(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:attibutes context:nil@H_404_22@].size@H_404_22@;
    }
    else@H_404_22@ {
        dim = [str sizeWithFont:font constrainedToSize:textRect];
    }

    dim.width@H_404_22@ = (dim.width@H_404_22@);
    dim.height@H_404_22@ = (dim.height@H_404_22@);

    return@H_404_22@ dim;
}

// 计算字体大小@H_404_22@
bool@H_404_22@ Device::CalculateTextSize(const@H_404_22@ char@H_404_22@ * text,const@H_404_22@ char@H_404_22@ * fontName,float@H_404_22@ size,float@H_404_22@ &width,float@H_404_22@ &height )
{
    //float constrainWidth,float constrainHeight,@H_404_22@
    bool@H_404_22@ ret = false@H_404_22@ ;
    CGSize@H_404_22@ dim,constrainSize ;
    dim.width@H_404_22@ = 0.0@H_404_22@f ;
    dim.height@H_404_22@ = 0.0@H_404_22@f;
    constrainSize.width@H_404_22@ = 0.0@H_404_22@f ; //constrainWidth ;@H_404_22@
    constrainSize.height@H_404_22@ = 0.0@H_404_22@f ;// constrainHeight ;@H_404_22@
    do@H_404_22@
    {
        CC_BREAK_IF(! text );

        NSString@H_404_22@ * str          = [NSString@H_404_22@ stringWithUTF8String:text];
        NSString@H_404_22@ * fntName      = [NSString@H_404_22@ stringWithUTF8String:fontName];

        fntName = [[fntName lastPathComponent] stringByDeletingPathExtension];

        // create the font@H_404_22@
        id@H_404_22@ font = [UIFont@H_404_22@ fontWithName:fntName size:size];

        if@H_404_22@ (font)
        {
            dim = _my_calculateStringSize(str,font,&constrainSize);
        }
        else@H_404_22@
        {
            if@H_404_22@ (!font)
            {
                font = [UIFont@H_404_22@ systemFontOfSize:size];
            }

            if@H_404_22@ (font)
            {
                dim = _my_calculateStringSize(str,&constrainSize);
            }
        }

        if@H_404_22@ (font)
        {
            ret = true@H_404_22@ ;
        }
    }while@H_404_22@(false@H_404_22@);

    width = dim.width@H_404_22@ ;
    height = dim.height@H_404_22@ ;

    return@H_404_22@ ret;
}
//@cxx end@H_404_22@

测试示例

auto _richText =@H_404_22@ RichText::create@H_404_22@();
_richText->@H_404_22@ignoreContentAdaptWithSize(false@H_404_22@);
_richText->@H_404_22@setContentSize(Size(100@H_404_22@,100@H_404_22@));

auto str1 =@H_404_22@ "是减肥了快iii速的减肥了快SD卡路附近ffm国恢复共和国fkdsjfkldsj假了jjiij经济ii的快速减肥了mshfjksdhKSDFHJKDSJFKLlfj。、里的时刻福建路口的.sdfdsjflkjlksdjfl JlkdsjflkdsfjkldsjflkdsjfkljLjkd是福建代理商福建路口的"@H_404_22@;

RichElementText*@H_404_22@ re1 =@H_404_22@ RichElementText::create@H_404_22@(1@H_404_22@,Color3B::WHITE@H_404_22@,255@H_404_22@,str1,"Marker Felt"@H_404_22@,20@H_404_22@);

_richText->@H_404_22@pushBackElement(re1);
_richText->@H_404_22@setPosition(Vec2(visibleSize.@H_404_22@width /@H_404_22@ 2@H_404_22@,visibleSize.@H_404_22@height /@H_404_22@ 2@H_404_22@ +@H_404_22@ 100@H_404_22@));
this->@H_404_22@addChild(_richText);

系统默认的对齐效果图:

修改后的对齐效果图:

猜你在找的Cocos2d-x相关文章