Пример #1
0
bool LabelTextFormatter::createStringSprites(Label *theLabel)
{
    theLabel->_limitShowCount = 0;
    // check for string
    int stringLen = theLabel->getStringLength();
    if (stringLen <= 0)
        return false;
    
    auto totalHeight = theLabel->_commonLineHeight * theLabel->_currNumLines;
    auto longestLine = 0.0f;
    auto nextFontPositionX = 0.0f;
    auto nextFontPositionY = totalHeight;
    auto contentScaleFactor = CC_CONTENT_SCALE_FACTOR();

    if (theLabel->_labelHeight > 0)
    {
        auto labelHeightPixel = theLabel->_labelHeight * contentScaleFactor;
        if (totalHeight > labelHeightPixel)
        {
            int numLines = labelHeightPixel / theLabel->_commonLineHeight;
            totalHeight = numLines * theLabel->_commonLineHeight;
        }
        switch (theLabel->_vAlignment)
        {
        case TextVAlignment::TOP:
            nextFontPositionY = labelHeightPixel;
            break;
        case TextVAlignment::CENTER:
            nextFontPositionY = (labelHeightPixel + totalHeight) / 2.0f;
            break;
        case TextVAlignment::BOTTOM:
            nextFontPositionY = totalHeight;
            break;
        default:
            break;
        }
    }
    
    int charXOffset = 0;
    int charYOffset = 0;
    int charAdvance = 0;

    auto strWhole = theLabel->_currentUTF16String;
    auto fontAtlas = theLabel->_fontAtlas;
    FontLetterDefinition tempDefinition;
    Vec2 letterPosition;
    const auto& kernings = theLabel->_horizontalKernings;
    CCASSERT(kernings, "kernings must's be nullptr!!!");

    float clipTop = 0;
    float clipBottom = 0;
    int lineIndex = 0;
    bool lineStart = true;
    bool clipBlank = false;
    if (theLabel->_currentLabelType == Label::LabelType::TTF && theLabel->_clipEnabled)
    {
        clipBlank = true;
    }
    
    for (int i = 0; i < stringLen; i++)
    {
        char16_t c    = strWhole[i];
        if (fontAtlas->getLetterDefinitionForChar(c, tempDefinition))
        {
            charXOffset         = tempDefinition.offsetX;
            charYOffset         = tempDefinition.offsetY;
            charAdvance         = tempDefinition.xAdvance;
        }
        else
        {
            charXOffset         = -1;
            charYOffset         = -1;
            charAdvance         = -1;
        }

        if (c == '\n')
        {
            lineIndex++;
            nextFontPositionX  = 0;
            nextFontPositionY -= theLabel->_commonLineHeight;
            
            theLabel->recordPlaceholderInfo(i);
            if(nextFontPositionY < theLabel->_commonLineHeight)
                break;

            lineStart = true;
            continue;     
        }
        else if (clipBlank && tempDefinition.height > 0.0f)
        {
            if (lineStart)
            {
                if (lineIndex == 0)
                {
                    clipTop = charYOffset;
                }
                lineStart = false;
                clipBottom = tempDefinition.clipBottom;
            }
            else if(tempDefinition.clipBottom < clipBottom)
            {
                clipBottom = tempDefinition.clipBottom;
            }

            if (lineIndex == 0 && charYOffset < clipTop)
            {
                clipTop = charYOffset;
            }
        }
        
        letterPosition.x = (nextFontPositionX + charXOffset + kernings[i]) / contentScaleFactor;
        letterPosition.y = (nextFontPositionY - charYOffset) / contentScaleFactor;
               
        if( theLabel->recordLetterInfo(letterPosition, tempDefinition, i) == false)
        {
            log("WARNING: can't find letter definition in font file for letter: %c", c);
            continue;
        }
        
        nextFontPositionX += charAdvance + theLabel->_additionalKerning;
        
        auto letterRight = letterPosition.x + tempDefinition.width;
        if (longestLine < letterRight)
        {
            longestLine = letterRight;
        }
    }
    
    Size tmpSize(longestLine * contentScaleFactor, totalHeight);
    if (theLabel->_labelHeight > 0)
    {
        tmpSize.height = theLabel->_labelHeight * contentScaleFactor;
    }

    if (clipBlank)
    {
        int clipTotal = (clipTop + clipBottom) / contentScaleFactor;
        tmpSize.height -= clipTotal * contentScaleFactor;
        clipBottom /= contentScaleFactor;

        for (int i = 0; i < theLabel->_limitShowCount; i++)
        {
            theLabel->_lettersInfo[i].position.y -= clipBottom;
        }
    }
    
    theLabel->setContentSize(CC_SIZE_PIXELS_TO_POINTS(tmpSize));

    return true;
}
Пример #2
0
bool LabelTextFormatter::createStringSprites(Label *theLabel)
{
    // check for string
    unsigned int stringLen = theLabel->getStringLength();
    theLabel->_limitShowCount = 0;

    // no string
    if (stringLen == 0)
        return false;
    
    int longestLine             = 0;
    unsigned int totalHeight    = theLabel->_commonLineHeight * theLabel->_currNumLines;
    int nextFontPositionX       = 0;
    int nextFontPositionY       = totalHeight;
    auto contentScaleFactor = CC_CONTENT_SCALE_FACTOR();

    if (theLabel->_labelHeight > 0)
    {
        auto labelHeightPixel = theLabel->_labelHeight * contentScaleFactor;
        if (totalHeight > labelHeightPixel)
        {
            int numLines = labelHeightPixel / theLabel->_commonLineHeight;
            totalHeight = numLines * theLabel->_commonLineHeight;
        }
        switch (theLabel->_vAlignment)
        {
        case TextVAlignment::TOP:
            nextFontPositionY = labelHeightPixel;
            break;
        case TextVAlignment::CENTER:
            nextFontPositionY = (labelHeightPixel + totalHeight) / 2.0f;
            break;
        case TextVAlignment::BOTTOM:
            nextFontPositionY = totalHeight;
            break;
        default:
            break;
        }
    }
    
    Rect charRect;
    int charXOffset = 0;
    int charYOffset = 0;
    int charAdvance = 0;

    auto strWhole = theLabel->_currentUTF16String;
    auto fontAtlas = theLabel->_fontAtlas;
    FontLetterDefinition tempDefinition;
    Vec2 letterPosition;
    const auto& kernings = theLabel->_horizontalKernings;

    float clipTop = 0;
    float clipBottom = 0;
    int lineIndex = 0;
    bool lineStart = true;
    bool clip = false;
    if (theLabel->_currentLabelType == Label::LabelType::TTF && theLabel->_clipEnabled)
    {
        clip = true;
    }
    
    for (unsigned int i = 0; i < stringLen; i++)
    {
        char16_t c    = strWhole[i];
        if (fontAtlas->getLetterDefinitionForChar(c, tempDefinition))
        {
            charXOffset         = tempDefinition.offsetX;
            charYOffset         = tempDefinition.offsetY;
            charAdvance         = tempDefinition.xAdvance;
        }
        else
        {
            charXOffset         = -1;
            charYOffset         = -1;
            charAdvance         = -1;
        }

        if (c == '\n')
        {
            lineIndex++;
            nextFontPositionX  = 0;
            nextFontPositionY -= theLabel->_commonLineHeight;
            
            theLabel->recordPlaceholderInfo(i);
            if(nextFontPositionY < theLabel->_commonLineHeight)
                break;

            lineStart = true;
            continue;     
        }
        else if (clip && tempDefinition.height > 0.0f)
        {
            if (lineStart)
            {
                if (lineIndex == 0)
                {
                    clipTop = charYOffset;
                }
                lineStart = false;
                clipBottom = tempDefinition.clipBottom;
            }
            else if(tempDefinition.clipBottom < clipBottom)
            {
                clipBottom = tempDefinition.clipBottom;
            }

            if (lineIndex == 0 && charYOffset < clipTop)
            {
                clipTop = charYOffset;
            }
        }
        
        letterPosition.x = (nextFontPositionX + charXOffset + kernings[i]) / contentScaleFactor;
        letterPosition.y = (nextFontPositionY - charYOffset) / contentScaleFactor;
               
        if( theLabel->recordLetterInfo(letterPosition,tempDefinition,i) == false)
        {
            log("WARNING: can't find letter definition in font file for letter: %c", c);
            continue;
        }

        nextFontPositionX += charAdvance + kernings[i] + theLabel->_additionalKerning;
        
        if (longestLine < nextFontPositionX)
        {
            longestLine = nextFontPositionX;
        }
    }
    
    float lastCharWidth = tempDefinition.width * contentScaleFactor;
    Size tmpSize;
    // If the last character processed has an xAdvance which is less that the width of the characters image, then we need
    // to adjust the width of the string to take this into account, or the character will overlap the end of the bounding
    // box
    if(charAdvance < lastCharWidth)
    {
        tmpSize.width = longestLine - charAdvance + lastCharWidth;
    }
    else
    {
        tmpSize.width = longestLine;
    }
    
    tmpSize.height = totalHeight;
    
    if (theLabel->_labelHeight > 0)
    {
        tmpSize.height = theLabel->_labelHeight * contentScaleFactor;
    }

    if (clip)
    {
        int clipTotal = (clipTop + clipBottom) / contentScaleFactor;
        tmpSize.height -= clipTotal * contentScaleFactor;
        clipBottom /= contentScaleFactor;

        for (int i = 0; i < theLabel->_limitShowCount; i++)
        {
            theLabel->_lettersInfo[i].position.y -= clipBottom;
        }
    }
    
    theLabel->setContentSize(CC_SIZE_PIXELS_TO_POINTS(tmpSize));

    return true;
}