示例#1
0
FontAtlas * FontAtlasCache::getFontAtlasTTF(const std::string& fontFileName, int size, GlyphCollection glyphs, const char *customGlyphs, bool useDistanceField)
{
    std::string atlasName = generateFontName(fontFileName, size, glyphs, useDistanceField);
    FontAtlas  *tempAtlas = _atlasMap[atlasName];
    
    if ( !tempAtlas )
    {
        FontFreeType *font = FontFreeType::create(fontFileName, size, glyphs, customGlyphs);
        if (font)
        {
            font->setDistanceFieldEnabled(useDistanceField);
            tempAtlas = font->createFontAtlas();
            if (tempAtlas)
                _atlasMap[atlasName] = tempAtlas;
        }
        else
        {
            return nullptr;
        }
    }
    else
    {
        tempAtlas->retain();
    }

    return tempAtlas;
}
示例#2
0
FontAtlas::FontAtlas(Font &theFont) 
: _font(&theFont)
, _currentPageData(nullptr)
, _fontAscender(0)
, _rendererRecreatedListener(nullptr)
, _antialiasEnabled(true)
, _rendererRecreate(false)
{
    _font->retain();

    FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
    if (fontTTf)
    {
        _commonLineHeight = _font->getFontMaxHeight();
        _fontAscender = fontTTf->getFontAscender();
        auto texture = new (std::nothrow) Texture2D;
        _currentPage = 0;
        _currentPageOrigX = 0;
        _currentPageOrigY = 0;
        _letterPadding = 0;

        if(fontTTf->isDistanceFieldEnabled())
        {
            _letterPadding += 2 * FontFreeType::DistanceMapSpread;    
        }
        _currentPageDataSize = CacheTextureWidth * CacheTextureHeight;
        auto outlineSize = fontTTf->getOutlineSize();
        if(outlineSize > 0)
        {
            _commonLineHeight += 2 * outlineSize;
            _currentPageDataSize *= 2;
        }    

        _currentPageData = new unsigned char[_currentPageDataSize];
        memset(_currentPageData, 0, _currentPageDataSize);

        auto  pixelFormat = outlineSize > 0 ? Texture2D::PixelFormat::AI88 : Texture2D::PixelFormat::A8; 
        texture->initWithData(_currentPageData, _currentPageDataSize, 
            pixelFormat, CacheTextureWidth, CacheTextureHeight, Size(CacheTextureWidth,CacheTextureHeight) );

        addTexture(texture,0);
        texture->release();

#if CC_ENABLE_CACHE_TEXTURE_DATA
        auto eventDispatcher = Director::getInstance()->getEventDispatcher();

        _rendererRecreatedListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, CC_CALLBACK_1(FontAtlas::listenRendererRecreated, this));
        eventDispatcher->addEventListenerWithFixedPriority(_rendererRecreatedListener, 1);
#endif
    }
}
示例#3
0
FontAtlas::FontAtlas(Font &theFont) 
: _font(&theFont)
, _currentPageData(nullptr)
, _fontAscender(0)
, _toForegroundListener(nullptr)
, _toBackgroundListener(nullptr)
{
    _font->retain();

    FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
    if (fontTTf)
    {
        _commonLineHeight = _font->getFontMaxHeight();
        _fontAscender = fontTTf->getFontAscender();
        auto texture = new Texture2D;
        _currentPage = 0;
        _currentPageOrigX = 0;
        _currentPageOrigY = 0;
        _letterPadding = 0;

        if(fontTTf->isDistanceFieldEnabled())
        {
            _letterPadding += 2 * FontFreeType::DistanceMapSpread;    
        }
        _currentPageDataSize = CacheTextureWidth * CacheTextureHeight;
        if(fontTTf->getOutlineSize() > 0)
        {
            _currentPageDataSize *= 2;
        }    

        _currentPageData = new unsigned char[_currentPageDataSize];
        memset(_currentPageData, 0, _currentPageDataSize);  
        addTexture(texture,0);
        texture->release();
#if CC_ENABLE_CACHE_TEXTURE_DATA
        auto eventDispatcher = Director::getInstance()->getEventDispatcher();
        _toBackgroundListener = EventListenerCustom::create(EVENT_COME_TO_BACKGROUND, CC_CALLBACK_1(FontAtlas::listenToBackground, this));
        eventDispatcher->addEventListenerWithFixedPriority(_toBackgroundListener, 1);
        _toForegroundListener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND, CC_CALLBACK_1(FontAtlas::listenToForeground, this));
        eventDispatcher->addEventListenerWithFixedPriority(_toForegroundListener, 1);
#endif
    }
}
示例#4
0
void FontAtlas::listenToForeground(EventCustom *event)
{
#if CC_ENABLE_CACHE_TEXTURE_DATA
    FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
    if (fontTTf)
    {
        if (_currentPageOrigX == 0 && _currentPageOrigY == 0)
        {
            auto eventDispatcher = Director::getInstance()->getEventDispatcher();
            eventDispatcher->dispatchCustomEvent(EVENT_PURGE_TEXTURES,this);
        }
        else
        {
            auto contentSize = Size(CacheTextureWidth,CacheTextureHeight);
            auto  pixelFormat = fontTTf->getOutlineSize() > 0 ? Texture2D::PixelFormat::AI88 : Texture2D::PixelFormat::A8;

            _atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, CacheTextureWidth, CacheTextureHeight, contentSize );
        }
    }
#endif
}
示例#5
0
FontFreeType * FontFreeType::create(const std::string &fontName, int fontSize, GlyphCollection glyphs, const char *customGlyphs)
{
    if( glyphs == GlyphCollection::DYNAMIC )
    {
        log("ERROR: GlyphCollection::DYNAMIC is not supported yet!");
        return nullptr;
    }
    
    FontFreeType *tempFont =  new FontFreeType();
    
    if (!tempFont)
        return nullptr;
    
    tempFont->setCurrentGlyphCollection(glyphs, customGlyphs);
    
    if (!tempFont->createFontObject(fontName, fontSize))
    {
        delete tempFont;
        return nullptr;
    }
    
    return tempFont;
}
示例#6
0
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;
}
示例#7
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;
}