CCLabelBMFont: Bug with 'new line' symbol

Code:

CCLabelBMFont* pLabel = CCLabelBMFont::labelWithString(“”, “Resource/fonts/header.fnt”);
pLabel~~>setPosition);
pScene~~>addChild(pLabel);
pLabel~~>setWidth;
pLabel~~>setAlignment(CCTextAlignmentRight);
pLabel->setString(“Line 1\nLine 2”);

The label draws as single line.
Also no space between ‘1’ and ‘L’ symbols.

Sorry.
Forgot mention cocos2dx version. This was “cocos2d-1.0.1-x-0.13.0-beta”.


CCLabelBMFont-newline-bug.png (13.2 KB)

//Use this
//Good luck

void CCLabelBMFont::updateLabel()
{
this ->setString(m_sInitialString, false );

if (m_fWidth > 0)
{
    // Step 1: Make multiline
    vector< unsigned short > str_whole = cc_utf16_vec_from_utf16_str(m_sString);

    unsigned int stringLength = str_whole.size();

    vector< unsigned short > multiline_string;

    multiline_string.reserve( stringLength );

    vector< unsigned short > last_word;

    last_word.reserve( stringLength );

                             unsigned int i = 0;

    bool start_line = false , start_word = false;

    float startOfLine = -1, startOfWord = -1;

    int skip = 0;

    CCArray* children = getChildren();
    for (unsigned int j = 0; j < children->count(); j++)
    {
        CCSprite* characterSprite;

        unsigned int justSkipped = 0;
       
        while (NULL == (characterSprite = (CCSprite*) this->getChildByTag(j + skip + justSkipped)))
        {
            justSkipped++;
        }
       
        skip += justSkipped;
       

        if (i >= stringLength)
            break ;

        unsigned short character = str_whole[i];

        if ( false == start_word )
        {
            startOfWord = getLetterPosXLeft( characterSprite );
            start_word = true ;
        }

        if ( false == start_line )
        {
            startOfLine = startOfWord;
            start_line = true ;
        }

        if (character == '\n' )
        {
            cc_utf8_trim_ws(&last_word);

            last_word.push_back( '\n' );

            multiline_string.insert(multiline_string.end(), last_word.begin(), last_word.end());

            last_word.clear();

            i+=justSkipped;
                                                            i++;

                                                             continue ;
        }

        if (isspace_unicode(character))
        {
            last_word.push_back(character);
            multiline_string.insert(multiline_string.end(), last_word.begin(), last_word.end());
            last_word.clear();

            start_word = false ;
            startOfWord = -1;
            i++;

            continue ;
        }

        // Out of bounds.
        if ( getLetterPosXRight( characterSprite ) - startOfLine > m_fWidth )
        {
            if ( false == m_bLineBreakWithoutSpaces )
            {
                last_word.push_back(character);

                int found = cc_utf8_find_last_not_char(multiline_string, ' ');

                if (found != -1)
                    cc_utf8_trim_ws(&multiline_string);

                else
                    multiline_string.clear();

                if (multiline_string.size() > 0)
                    multiline_string.push_back( '\n' );

                start_line = false ;
                startOfLine = -1;
                i++;
            }
            else
            {
                cc_utf8_trim_ws(&last_word);

                last_word.push_back( '\n' );
                multiline_string.insert(multiline_string.end(), last_word.begin(), last_word.end());
                last_word.clear();
                start_word = false ;
                start_line = false ;
                startOfWord = -1;
                startOfLine = -1;

                if (i >= stringLength)
                    break ;

                if (false == startOfWord)
                {
                    startOfWord = getLetterPosXLeft( characterSprite );
                    start_word = true ;
                }
                if (false == startOfLine)
                {
                    startOfLine  = startOfWord;
                    start_line = true ;
                }

                j--;
            }

            continue ;
        }
        else
        {
            // Character is normal.
            last_word.push_back(character);
            i++;
        }
    }

    multiline_string.insert(multiline_string.end(), last_word.begin(), last_word.end());

    int size = multiline_string.size();
    unsigned short * str_new = new unsigned short [size + 1];

    for (int i = 0; i < size; ++i)
    {
        str_new[i] = multiline_string[i];
    }

    str_new[size] = '\0' ;

    this ->setString(str_new, false );
   
    CC_SAFE_DELETE_ARRAY(str_new);
}

// Step 2: Make alignment
if (m_pAlignment != kCCTextAlignmentLeft)
{
    int i = 0;

    int lineNumber = 0;
    int str_len = cc_wcslen(m_sString);
    vector< unsigned short > last_line;
    for (int ctr = 0; ctr <= str_len; ++ctr)
    {
        if (m_sString[ctr] == '\n' || m_sString[ctr] == 0)
        {
            float lineWidth = 0.0f;
            unsigned int line_length = last_line.size();
                                                             // if last line is empty we must just increase lineNumber and work with next line
            if (line_length == 0)
            {
                lineNumber++;
                continue ;
            }
            int index = i + line_length - 1 + lineNumber;
            if (index < 0) continue ;

            CCSprite* lastChar = (CCSprite*)getChildByTag(index);
            if ( lastChar == NULL )
                continue ;

            lineWidth = lastChar->getPosition().x + lastChar->getContentSize().width/2.0f;

            float shift = 0;
            switch (m_pAlignment)
            {
            case kCCTextAlignmentCenter:
                shift = getContentSize().width/2.0f - lineWidth/2.0f;
                break ;
            case kCCTextAlignmentRight:
                shift = getContentSize().width - lineWidth;
                break ;
            default :
                break ;
            }

            if (shift != 0)
            {
                for (unsigned j = 0; j < line_length; j++)
                {
                    index = i + j + lineNumber;
                    if (index < 0) continue ;

                    CCSprite* characterSprite = (CCSprite*)getChildByTag(index);
                    characterSprite->setPosition(ccpAdd(characterSprite->getPosition(), ccp(shift, 0.0f)));
                }
            }

            i += line_length;
            lineNumber++;

            last_line.clear();
            continue ;
        }

        last_line.push_back(m_sString[ctr]);
    }
}

}