bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
{
    FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
    if(fontTTf == nullptr)
        return false;

    int length = cc_wcslen(utf16String);

    float offsetAdjust = _letterPadding / 2;  
    int bitmapWidth;
    int bitmapHeight;
    Rect tempRect;
    FontLetterDefinition tempDef;

    auto contentSize = Size(CacheTextureWidth,CacheTextureHeight);
    auto scaleFactor = CC_CONTENT_SCALE_FACTOR();
    auto  pixelFormat = fontTTf->getOutlineSize() > 0 ? Texture2D::PixelFormat::AI88 : Texture2D::PixelFormat::A8; 

    bool existNewLetter = false;
    for (int i = 0; i < length; ++i)
    {
        auto outIterator = _fontLetterDefinitions.find(utf16String[i]);

        if (outIterator == _fontLetterDefinitions.end())
        {  
            existNewLetter = true;

            auto bitmap = fontTTf->getGlyphBitmap(utf16String[i],bitmapWidth,bitmapHeight,tempRect,tempDef.xAdvance);
            if (bitmap)
            {
                tempDef.validDefinition = true;
                tempDef.letteCharUTF16   = utf16String[i];
                tempDef.width            = tempRect.size.width + _letterPadding;
                tempDef.height           = tempRect.size.height + _letterPadding;
                tempDef.offsetX          = tempRect.origin.x + offsetAdjust;
                tempDef.offsetY          = _fontAscender + tempRect.origin.y - offsetAdjust;

                if (_currentPageOrigX + tempDef.width > CacheTextureWidth)
                {
                    _currentPageOrigY += _commonLineHeight;
                    _currentPageOrigX = 0;
                    if(_currentPageOrigY + _commonLineHeight >= CacheTextureHeight)
                    {             
                        _atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, CacheTextureWidth, CacheTextureHeight, contentSize );
                        _currentPageOrigY = 0;
                        memset(_currentPageData, 0, _currentPageDataSize);
                        _currentPage++;
                        auto tex = new Texture2D;
                        addTexture(tex,_currentPage);
                        tex->release();
                    }  
                }
                fontTTf->renderCharAt(_currentPageData,_currentPageOrigX,_currentPageOrigY,bitmap,bitmapWidth,bitmapHeight);

                tempDef.U                = _currentPageOrigX;
                tempDef.V                = _currentPageOrigY;
                tempDef.textureID        = _currentPage;
                _currentPageOrigX        += tempDef.width + 1;
                // take from pixels to points
                tempDef.width  =    tempDef.width  / scaleFactor;
                tempDef.height =    tempDef.height / scaleFactor;      
                tempDef.U      =    tempDef.U      / scaleFactor;
                tempDef.V      =    tempDef.V      / scaleFactor;
            }
            else{
                if(tempDef.xAdvance)
                    tempDef.validDefinition = true;
                else
                    tempDef.validDefinition = false;

                tempDef.letteCharUTF16   = utf16String[i];
                tempDef.width            = 0;
                tempDef.height           = 0;
                tempDef.U                = 0;
                tempDef.V                = 0;
                tempDef.offsetX          = 0;
                tempDef.offsetY          = 0;
                tempDef.textureID        = 0;
                _currentPageOrigX += 1;
            }

            _fontLetterDefinitions[tempDef.letteCharUTF16] = tempDef;
        }       
    }

    if(existNewLetter)
    {
        _atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, CacheTextureWidth, CacheTextureHeight, contentSize );
    }
    return true;
}
Exemple #2
0
bool FontAtlas::prepareLetterDefinitions(const std::u16string& utf16String)
{
    FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
    if(fontTTf == nullptr)
        return false;
    
    size_t length = utf16String.length();

    float offsetAdjust = _letterPadding / 2;  
    long bitmapWidth;
    long bitmapHeight;
    Rect tempRect;
    FontLetterDefinition tempDef;

    auto scaleFactor = CC_CONTENT_SCALE_FACTOR();
    auto  pixelFormat = fontTTf->getOutlineSize() > 0 ? Texture2D::PixelFormat::AI88 : Texture2D::PixelFormat::A8; 

    bool existNewLetter = false;
    int bottomHeight = _commonLineHeight - _fontAscender;

    float startY = _currentPageOrigY;

    for (size_t i = 0; i < length; ++i)
    {
        auto outIterator = _fontLetterDefinitions.find(utf16String[i]);

        if (outIterator == _fontLetterDefinitions.end())
        {  
            existNewLetter = true;

            auto bitmap = fontTTf->getGlyphBitmap(utf16String[i],bitmapWidth,bitmapHeight,tempRect,tempDef.xAdvance);
            if (bitmap)
            {
                tempDef.validDefinition = true;
                tempDef.letteCharUTF16   = utf16String[i];
                tempDef.width            = tempRect.size.width + _letterPadding;
                tempDef.height           = tempRect.size.height + _letterPadding;
                tempDef.offsetX          = tempRect.origin.x + offsetAdjust;
                tempDef.offsetY          = _fontAscender + tempRect.origin.y - offsetAdjust;
                tempDef.clipBottom     = bottomHeight - (tempDef.height + tempRect.origin.y + offsetAdjust);

                if (_currentPageOrigX + tempDef.width > CacheTextureWidth)
                {
                    _currentPageOrigY += _commonLineHeight;
                    _currentPageOrigX = 0;
                    if(_currentPageOrigY + _commonLineHeight >= CacheTextureHeight)
                    {
                        unsigned char *data = nullptr;
                        if(pixelFormat == Texture2D::PixelFormat::AI88)
                        {
                            data = _currentPageData + CacheTextureWidth * (int)startY * 2;
                        }
                        else
                        {
                            data = _currentPageData + CacheTextureWidth * (int)startY;
                        }
                        _atlasTextures[_currentPage]->updateWithData(data, 0, startY, 
                            CacheTextureWidth, CacheTextureHeight - startY);

                        startY = 0.0f;

                        _currentPageOrigY = 0;
                        memset(_currentPageData, 0, _currentPageDataSize);
                        _currentPage++;
                        auto tex = new (std::nothrow) Texture2D;
                        if (_antialiasEnabled)
                        {
                            tex->setAntiAliasTexParameters();
                        } 
                        else
                        {
                            tex->setAliasTexParameters();
                        }
                        tex->initWithData(_currentPageData, _currentPageDataSize, 
                            pixelFormat, CacheTextureWidth, CacheTextureHeight, Size(CacheTextureWidth,CacheTextureHeight) );
                        addTexture(tex,_currentPage);
                        tex->release();
                    }  
                }
                fontTTf->renderCharAt(_currentPageData,_currentPageOrigX,_currentPageOrigY,bitmap,bitmapWidth,bitmapHeight);

                tempDef.U                = _currentPageOrigX;
                tempDef.V                = _currentPageOrigY;
                tempDef.textureID        = _currentPage;
                _currentPageOrigX        += tempDef.width + 1;
                // take from pixels to points
                tempDef.width  =    tempDef.width  / scaleFactor;
                tempDef.height =    tempDef.height / scaleFactor;      
                tempDef.U      =    tempDef.U      / scaleFactor;
                tempDef.V      =    tempDef.V      / scaleFactor;
            }
            else{
                if(tempDef.xAdvance)
                    tempDef.validDefinition = true;
                else
                    tempDef.validDefinition = false;

                tempDef.letteCharUTF16   = utf16String[i];
                tempDef.width            = 0;
                tempDef.height           = 0;
                tempDef.U                = 0;
                tempDef.V                = 0;
                tempDef.offsetX          = 0;
                tempDef.offsetY          = 0;
                tempDef.textureID        = 0;
                tempDef.clipBottom = 0;
                _currentPageOrigX += 1;
            }

            _fontLetterDefinitions[tempDef.letteCharUTF16] = tempDef;
        }       
    }

    if(existNewLetter)
    {
        if (_rendererRecreate)
        {
            _atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, 
                pixelFormat, CacheTextureWidth, CacheTextureHeight, Size(CacheTextureWidth,CacheTextureHeight) );
        } 
        else
        {
            unsigned char *data = nullptr;
            if(pixelFormat == Texture2D::PixelFormat::AI88)
            {
                data = _currentPageData + CacheTextureWidth * (int)startY * 2;
            }
            else
            {
                data = _currentPageData + CacheTextureWidth * (int)startY;
            }
            _atlasTextures[_currentPage]->updateWithData(data, 0, startY, 
                CacheTextureWidth, _currentPageOrigY - startY + _commonLineHeight);
        }
    }
    return true;
}