Merge pull request #5788 from Dhilan007/develop_label

Label:fixed text display incorrect when come to foreground on android.
This commit is contained in:
James Chen 2014-03-14 15:46:39 +08:00
commit cc929f42cd
6 changed files with 188 additions and 26 deletions

View File

@ -27,16 +27,22 @@
#include "CCFontFreeType.h"
#include "ccUTF8.h"
#include "CCDirector.h"
#include "CCEventListenerCustom.h"
#include "CCEventDispatcher.h"
#include "CCEventType.h"
NS_CC_BEGIN
const int FontAtlas::CacheTextureWidth = 1024;
const int FontAtlas::CacheTextureHeight = 1024;
const char* FontAtlas::EVENT_PURGE_TEXTURES = "__cc_FontAtlasPurgeTextures";
FontAtlas::FontAtlas(Font &theFont)
: _font(&theFont)
, _currentPageData(nullptr)
, _fontAscender(0)
, _toForegroundListener(nullptr)
, _toBackgroundListener(nullptr)
{
_font->retain();
@ -61,15 +67,40 @@ FontAtlas::FontAtlas(Font &theFont)
_currentPageDataSize *= 2;
}
_currentPageData = new unsigned char[_currentPageDataSize];
_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
}
}
FontAtlas::~FontAtlas()
{
#if CC_ENABLE_CACHE_TEXTURE_DATA
FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
if (fontTTf)
{
auto eventDispatcher = Director::getInstance()->getEventDispatcher();
if (_toForegroundListener)
{
eventDispatcher->removeEventListener(_toForegroundListener);
_toForegroundListener = nullptr;
}
if (_toBackgroundListener)
{
eventDispatcher->removeEventListener(_toBackgroundListener);
_toBackgroundListener = nullptr;
}
}
#endif
_font->release();
relaseTextures();
@ -82,6 +113,82 @@ void FontAtlas::relaseTextures()
{
item.second->release();
}
_atlasTextures.clear();
}
void FontAtlas::purgeTexturesAtlas()
{
FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
if (fontTTf && _atlasTextures.size() > 1)
{
for( auto &item: _atlasTextures)
{
if (item.first != 0)
{
item.second->release();
}
}
auto temp = _atlasTextures[0];
_atlasTextures.clear();
_atlasTextures[0] = temp;
_fontLetterDefinitions.clear();
memset(_currentPageData,0,_currentPageDataSize);
_currentPage = 0;
_currentPageOrigX = 0;
_currentPageOrigY = 0;
auto eventDispatcher = Director::getInstance()->getEventDispatcher();
eventDispatcher->dispatchCustomEvent(EVENT_PURGE_TEXTURES,this);
}
}
void FontAtlas::listenToBackground(EventCustom *event)
{
#if CC_ENABLE_CACHE_TEXTURE_DATA
FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
if (fontTTf && _atlasTextures.size() > 1)
{
for( auto &item: _atlasTextures)
{
if (item.first != 0)
{
item.second->release();
}
}
auto temp = _atlasTextures[0];
_atlasTextures.clear();
_atlasTextures[0] = temp;
_fontLetterDefinitions.clear();
memset(_currentPageData,0,_currentPageDataSize);
_currentPage = 0;
_currentPageOrigX = 0;
_currentPageOrigY = 0;
}
#endif
}
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
}
void FontAtlas::addLetterDefinition(const FontLetterDefinition &letterDefinition)
@ -107,10 +214,10 @@ bool FontAtlas::getLetterDefinitionForChar(unsigned short letteCharUTF16, FontL
bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
{
if(_currentPageData == nullptr)
FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
if(fontTTf == nullptr)
return false;
FontFreeType* fontTTf = (FontFreeType*)_font;
int length = cc_wcslen(utf16String);
float offsetAdjust = _letterPadding / 2;
@ -150,11 +257,6 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
{
_atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, CacheTextureWidth, CacheTextureHeight, contentSize );
_currentPageOrigY = 0;
delete []_currentPageData;
_currentPageData = new unsigned char[_currentPageDataSize];
if(_currentPageData == nullptr)
return false;
memset(_currentPageData, 0, _currentPageDataSize);
_currentPage++;
auto tex = new Texture2D;

View File

@ -34,6 +34,8 @@ NS_CC_BEGIN
//fwd
class Font;
class Texture2D;
class EventCustom;
class EventListenerCustom;
struct FontLetterDefinition
{
@ -54,6 +56,7 @@ class CC_DLL FontAtlas : public Ref
public:
static const int CacheTextureWidth;
static const int CacheTextureHeight;
static const char* EVENT_PURGE_TEXTURES;
/**
* @js ctor
*/
@ -76,7 +79,22 @@ public:
Texture2D* getTexture(int slot);
const Font* getFont() const;
/** Listen "come to background" message, and clear the texture atlas.
It only has effect on Android.
*/
void listenToBackground(EventCustom *event);
/** Listen "come to foreground" message and restore the texture atlas.
It only has effect on Android.
*/
void listenToForeground(EventCustom *event);
/** Removes textures atlas.
It will purge the textures atlas and if multiple texture exist in the FontAtlas.
*/
void purgeTexturesAtlas();
private:
void relaseTextures();
@ -95,6 +113,8 @@ private:
bool _makeDistanceMap;
int _fontAscender;
EventListenerCustom* _toBackgroundListener;
EventListenerCustom* _toForegroundListener;
};

View File

@ -36,6 +36,14 @@ NS_CC_BEGIN
std::unordered_map<std::string, FontAtlas *> FontAtlasCache::_atlasMap;
void FontAtlasCache::purgeCachedData()
{
for (auto & atlas:_atlasMap)
{
atlas.second->purgeTexturesAtlas();
}
}
FontAtlas * FontAtlasCache::getFontAtlasTTF(const TTFConfig & config)
{
bool useDistanceField = config.distanceFieldEnabled;
@ -46,7 +54,7 @@ FontAtlas * FontAtlasCache::getFontAtlasTTF(const TTFConfig & config)
int fontSize = config.fontSize;
if (useDistanceField)
{
fontSize = Label::DistanceFieldFontSize;
fontSize = Label::DistanceFieldFontSize / CC_CONTENT_SCALE_FACTOR();
}
std::string atlasName = generateFontName(config.fontFilePath, fontSize, GlyphCollection::DYNAMIC, useDistanceField);

View File

@ -45,6 +45,11 @@ public:
static FontAtlas * getFontAtlasCharMap(const std::string& plistFile);
static bool releaseFontAtlas(FontAtlas *atlas);
/** Removes cached data.
It will purge the textures atlas and if multiple texture exist in one FontAtlas.
*/
static void purgeCachedData();
private:
static std::string generateFontName(const std::string& fontFileName, int size, GlyphCollection theGlyphs, bool useDistanceField);

View File

@ -33,6 +33,10 @@
#include "CCDirector.h"
#include "renderer/CCRenderer.h"
#include "CCFont.h"
#include "CCEventListenerCustom.h"
#include "CCEventDispatcher.h"
#include "CCEventType.h"
#include "CCEventCustom.h"
NS_CC_BEGIN
@ -278,6 +282,14 @@ Label::Label(FontAtlas *atlas /* = nullptr */, TextHAlignment hAlignment /* = Te
_cascadeColorEnabled = true;
reset();
#if CC_ENABLE_CACHE_TEXTURE_DATA
auto toBackgroundListener = EventListenerCustom::create(EVENT_COME_TO_BACKGROUND, CC_CALLBACK_1(Label::listenToBackground, this));
_eventDispatcher->addEventListenerWithSceneGraphPriority(toBackgroundListener, this);
#endif
auto purgeTextureListener = EventListenerCustom::create(FontAtlas::EVENT_PURGE_TEXTURES, CC_CALLBACK_1(Label::listenToFontAtlasPurge, this));
_eventDispatcher->addEventListenerWithSceneGraphPriority(purgeTextureListener, this);
}
Label::~Label()
@ -813,7 +825,7 @@ void Label::disableEffect()
void Label::setFontScale(float fontScale)
{
_fontScale = fontScale;
_fontScale = fontScale * CC_CONTENT_SCALE_FACTOR();
Node::setScale(_fontScale);
}
@ -1024,13 +1036,7 @@ void Label::setFontName(const std::string& fontName)
const std::string& Label::getFontName() const
{
switch (_currentLabelType)
{
case LabelType::TTF:
return _fontConfig.fontFilePath;
default:
return _fontDefinition._fontName;
}
return _fontName;
}
void Label::setFontSize(int fontSize)
@ -1044,15 +1050,7 @@ void Label::setFontSize(int fontSize)
int Label::getFontSize() const
{
switch (_currentLabelType)
{
case LabelType::TTF:
return _fontConfig.fontSize;
case LabelType::STRING_TEXTURE:
return _fontDefinition._fontSize;
default:
return 0;
}
return _fontSize;
}
///// PROTOCOL STUFF
@ -1215,4 +1213,24 @@ const Size& Label::getContentSize() const
return Node::getContentSize();
}
void Label::listenToBackground(EventCustom *event)
{
#if CC_ENABLE_CACHE_TEXTURE_DATA
if (_fontAtlas && _currentLabelType == LabelType::TTF)
{
_batchNodes.clear();
_batchNodes.push_back(this);
Node::removeAllChildrenWithCleanup(true);
}
#endif
}
void Label::listenToFontAtlasPurge(EventCustom *event)
{
if (_fontAtlas && _currentLabelType == LabelType::TTF && event->getUserData() == _fontAtlas)
{
alignText();
}
}
NS_CC_END

View File

@ -230,6 +230,15 @@ public:
virtual const Size& getContentSize() const override;
/** Listen "come to background" message
It only has effect on Android.
*/
void listenToBackground(EventCustom *event);
/** Listen "FontAtlas purge textures" message
*/
void listenToFontAtlasPurge(EventCustom *event);
protected:
void onDraw(const kmMat4& transform, bool transformUpdated);