2013-07-25 01:22:46 +08:00
/****************************************************************************
Copyright ( c ) 2013 Zynga Inc .
2018-01-29 16:25:32 +08:00
Copyright ( c ) 2013 - 2016 Chukong Technologies Inc .
Copyright ( c ) 2017 - 2018 Xiamen Yaji Software Co . , Ltd .
2013-07-25 01:22:46 +08:00
http : //www.cocos2d-x.org
Permission is hereby granted , free of charge , to any person obtaining a copy
of this software and associated documentation files ( the " Software " ) , to deal
in the Software without restriction , including without limitation the rights
to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
copies of the Software , and to permit persons to whom the Software is
furnished to do so , subject to the following conditions :
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software .
THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-07-14 17:53:55 +08:00
# include "2d/CCFontAtlasCache.h"
2013-07-25 01:22:46 +08:00
2015-07-30 11:33:18 +08:00
# include "base/CCDirector.h"
2014-05-01 10:09:13 +08:00
# include "2d/CCFontFNT.h"
# include "2d/CCFontFreeType.h"
2014-08-27 13:39:50 +08:00
# include "2d/CCFontAtlas.h"
# include "2d/CCFontCharMap.h"
2015-07-30 11:33:18 +08:00
# include "2d/CCLabel.h"
2016-11-18 09:23:44 +08:00
# include "platform/CCFileUtils.h"
2013-07-25 01:22:46 +08:00
NS_CC_BEGIN
2013-11-07 09:05:13 +08:00
std : : unordered_map < std : : string , FontAtlas * > FontAtlasCache : : _atlasMap ;
2016-03-25 21:21:09 +08:00
# define ATLAS_MAP_KEY_BUFFER 255
2013-07-25 01:22:46 +08:00
2014-03-14 14:59:26 +08:00
void FontAtlasCache : : purgeCachedData ( )
{
2015-08-05 14:12:02 +08:00
auto atlasMapCopy = _atlasMap ;
for ( auto & & atlas : atlasMapCopy )
2014-03-14 14:59:26 +08:00
{
2017-07-31 09:05:55 +08:00
auto refCount = atlas . second - > getReferenceCount ( ) ;
atlas . second - > release ( ) ;
if ( refCount ! = 1 )
atlas . second - > purgeTexturesAtlas ( ) ;
2014-03-14 14:59:26 +08:00
}
2016-03-24 23:05:22 +08:00
_atlasMap . clear ( ) ;
2014-03-14 14:59:26 +08:00
}
2015-07-30 11:33:18 +08:00
FontAtlas * FontAtlasCache : : getFontAtlasTTF ( const _ttfConfig * config )
2016-11-18 09:23:44 +08:00
{
auto realFontFilename = FileUtils : : getInstance ( ) - > getNewFilename ( config - > fontFilePath ) ; // resolves real file path, to prevent storing multiple atlases for the same file.
2015-07-30 11:33:18 +08:00
bool useDistanceField = config - > distanceFieldEnabled ;
if ( config - > outlineSize > 0 )
2014-03-05 15:54:40 +08:00
{
useDistanceField = false ;
}
2014-03-25 09:58:16 +08:00
2016-03-25 21:21:09 +08:00
char tmp [ ATLAS_MAP_KEY_BUFFER ] ;
2016-03-24 23:05:22 +08:00
if ( useDistanceField ) {
2016-03-25 21:21:09 +08:00
snprintf ( tmp , ATLAS_MAP_KEY_BUFFER , " df %.2f %d %s " , config - > fontSize , config - > outlineSize ,
2016-11-18 09:23:44 +08:00
realFontFilename . c_str ( ) ) ;
2016-03-24 23:05:22 +08:00
} else {
2016-03-25 21:21:09 +08:00
snprintf ( tmp , ATLAS_MAP_KEY_BUFFER , " %.2f %d %s " , config - > fontSize , config - > outlineSize ,
2016-11-18 09:23:44 +08:00
realFontFilename . c_str ( ) ) ;
2016-03-24 23:05:22 +08:00
}
std : : string atlasName = tmp ;
2014-03-05 15:54:40 +08:00
2014-03-28 16:52:48 +08:00
auto it = _atlasMap . find ( atlasName ) ;
2014-03-05 15:54:40 +08:00
2014-03-28 16:52:48 +08:00
if ( it = = _atlasMap . end ( ) )
2013-07-25 01:22:46 +08:00
{
2016-11-18 09:23:44 +08:00
auto font = FontFreeType : : create ( realFontFilename , config - > fontSize , config - > glyphs ,
2015-07-30 11:33:18 +08:00
config - > customGlyphs , useDistanceField , config - > outlineSize ) ;
2014-01-20 10:32:12 +08:00
if ( font )
{
2014-03-28 16:52:48 +08:00
auto tempAtlas = font - > createFontAtlas ( ) ;
2014-01-20 10:32:12 +08:00
if ( tempAtlas )
2014-03-28 16:52:48 +08:00
{
2014-01-20 10:32:12 +08:00
_atlasMap [ atlasName ] = tempAtlas ;
2014-03-28 16:52:48 +08:00
return _atlasMap [ atlasName ] ;
}
2014-01-20 10:32:12 +08:00
}
2013-07-25 01:22:46 +08:00
}
2013-07-31 07:41:26 +08:00
else
2018-05-30 20:33:53 +08:00
return it - > second ;
2014-01-20 10:32:12 +08:00
2014-03-28 16:52:48 +08:00
return nullptr ;
2013-07-25 01:22:46 +08:00
}
2015-07-30 11:33:18 +08:00
FontAtlas * FontAtlasCache : : getFontAtlasFNT ( const std : : string & fontFileName , const Vec2 & imageOffset /* = Vec2::ZERO */ )
2013-07-25 01:22:46 +08:00
{
2016-11-18 09:23:44 +08:00
auto realFontFilename = FileUtils : : getInstance ( ) - > getNewFilename ( fontFileName ) ; // resolves real file path, to prevent storing multiple atlases for the same file.
2016-03-25 21:21:09 +08:00
char tmp [ ATLAS_MAP_KEY_BUFFER ] ;
2016-11-18 09:23:44 +08:00
snprintf ( tmp , ATLAS_MAP_KEY_BUFFER , " %.2f %.2f %s " , imageOffset . x , imageOffset . y , realFontFilename . c_str ( ) ) ;
2016-03-24 23:05:22 +08:00
std : : string atlasName = tmp ;
2014-03-28 16:52:48 +08:00
auto it = _atlasMap . find ( atlasName ) ;
if ( it = = _atlasMap . end ( ) )
2013-07-25 01:22:46 +08:00
{
2016-11-18 09:23:44 +08:00
auto font = FontFNT : : create ( realFontFilename , imageOffset ) ;
2014-01-20 10:32:12 +08:00
if ( font )
{
2014-03-28 16:52:48 +08:00
auto tempAtlas = font - > createFontAtlas ( ) ;
2014-01-20 10:32:12 +08:00
if ( tempAtlas )
2014-03-28 16:52:48 +08:00
{
2014-01-20 10:32:12 +08:00
_atlasMap [ atlasName ] = tempAtlas ;
2014-03-28 16:52:48 +08:00
return _atlasMap [ atlasName ] ;
}
2014-01-20 10:32:12 +08:00
}
2013-07-25 01:22:46 +08:00
}
2013-07-31 07:41:26 +08:00
else
2018-05-30 20:33:53 +08:00
return it - > second ;
2013-07-25 01:22:46 +08:00
2014-03-28 16:52:48 +08:00
return nullptr ;
2013-07-25 01:22:46 +08:00
}
2015-07-30 11:33:18 +08:00
FontAtlas * FontAtlasCache : : getFontAtlasCharMap ( const std : : string & plistFile )
2014-01-16 16:37:29 +08:00
{
2016-03-24 23:05:22 +08:00
std : : string atlasName = plistFile ;
2014-03-28 16:52:48 +08:00
auto it = _atlasMap . find ( atlasName ) ;
if ( it = = _atlasMap . end ( ) )
2014-01-16 16:37:29 +08:00
{
2014-03-28 16:52:48 +08:00
auto font = FontCharMap : : create ( plistFile ) ;
2014-01-20 10:32:12 +08:00
if ( font )
{
2014-03-28 16:52:48 +08:00
auto tempAtlas = font - > createFontAtlas ( ) ;
2014-01-20 10:32:12 +08:00
if ( tempAtlas )
2014-03-28 16:52:48 +08:00
{
2014-01-20 10:32:12 +08:00
_atlasMap [ atlasName ] = tempAtlas ;
2014-03-28 16:52:48 +08:00
return _atlasMap [ atlasName ] ;
}
2014-01-20 10:32:12 +08:00
}
2014-01-16 16:37:29 +08:00
}
else
2018-05-30 20:33:53 +08:00
return it - > second ;
2014-01-16 16:37:29 +08:00
2014-03-28 16:52:48 +08:00
return nullptr ;
2014-01-16 16:37:29 +08:00
}
2015-07-30 11:33:18 +08:00
FontAtlas * FontAtlasCache : : getFontAtlasCharMap ( Texture2D * texture , int itemWidth , int itemHeight , int startCharMap )
2014-01-16 16:37:29 +08:00
{
char tmp [ 30 ] ;
2014-01-16 17:50:09 +08:00
sprintf ( tmp , " name:%u_%d_%d_%d " , texture - > getName ( ) , itemWidth , itemHeight , startCharMap ) ;
2016-03-24 23:05:22 +08:00
std : : string atlasName = tmp ;
2014-01-16 16:37:29 +08:00
2014-03-28 16:52:48 +08:00
auto it = _atlasMap . find ( atlasName ) ;
if ( it = = _atlasMap . end ( ) )
2014-01-16 16:37:29 +08:00
{
2014-03-28 16:52:48 +08:00
auto font = FontCharMap : : create ( texture , itemWidth , itemHeight , startCharMap ) ;
2014-01-20 10:32:12 +08:00
if ( font )
{
2014-03-28 16:52:48 +08:00
auto tempAtlas = font - > createFontAtlas ( ) ;
2014-01-20 10:32:12 +08:00
if ( tempAtlas )
2014-03-28 16:52:48 +08:00
{
2014-01-20 10:32:12 +08:00
_atlasMap [ atlasName ] = tempAtlas ;
2014-03-28 16:52:48 +08:00
return _atlasMap [ atlasName ] ;
}
2014-01-20 10:32:12 +08:00
}
2014-01-16 16:37:29 +08:00
}
else
2018-05-30 20:33:53 +08:00
return it - > second ;
2014-01-16 16:37:29 +08:00
2014-03-28 16:52:48 +08:00
return nullptr ;
2014-01-16 16:37:29 +08:00
}
2015-07-30 11:33:18 +08:00
FontAtlas * FontAtlasCache : : getFontAtlasCharMap ( const std : : string & charMapFile , int itemWidth , int itemHeight , int startCharMap )
2014-01-16 16:37:29 +08:00
{
2016-03-25 21:21:09 +08:00
char tmp [ ATLAS_MAP_KEY_BUFFER ] ;
snprintf ( tmp , ATLAS_MAP_KEY_BUFFER , " %d %d %d %s " , itemWidth , itemHeight , startCharMap , charMapFile . c_str ( ) ) ;
2016-03-24 23:05:22 +08:00
std : : string atlasName = tmp ;
2014-01-16 16:37:29 +08:00
2014-03-28 16:52:48 +08:00
auto it = _atlasMap . find ( atlasName ) ;
if ( it = = _atlasMap . end ( ) )
2014-01-16 16:37:29 +08:00
{
2014-03-28 16:52:48 +08:00
auto font = FontCharMap : : create ( charMapFile , itemWidth , itemHeight , startCharMap ) ;
2014-01-20 10:32:12 +08:00
if ( font )
{
2014-03-28 16:52:48 +08:00
auto tempAtlas = font - > createFontAtlas ( ) ;
2014-01-20 10:32:12 +08:00
if ( tempAtlas )
2014-03-28 16:52:48 +08:00
{
2014-01-20 10:32:12 +08:00
_atlasMap [ atlasName ] = tempAtlas ;
2014-03-28 16:52:48 +08:00
return _atlasMap [ atlasName ] ;
}
2014-01-20 10:32:12 +08:00
}
2014-01-16 16:37:29 +08:00
}
else
2018-05-30 20:33:53 +08:00
return it - > second ;
2014-01-16 16:37:29 +08:00
2014-03-28 16:52:48 +08:00
return nullptr ;
2014-01-16 16:37:29 +08:00
}
2013-07-25 01:22:46 +08:00
bool FontAtlasCache : : releaseFontAtlas ( FontAtlas * atlas )
{
2014-01-04 18:22:50 +08:00
if ( nullptr ! = atlas )
2013-07-25 01:22:46 +08:00
{
2013-08-06 06:11:07 +08:00
for ( auto & item : _atlasMap )
2013-07-25 01:22:46 +08:00
{
if ( item . second = = atlas )
{
2014-01-22 13:47:29 +08:00
if ( atlas - > getReferenceCount ( ) = = 1 )
2014-01-04 18:22:50 +08:00
{
_atlasMap . erase ( item . first ) ;
}
2013-07-25 01:22:46 +08:00
2014-01-04 18:22:50 +08:00
atlas - > release ( ) ;
2013-07-25 01:22:46 +08:00
return true ;
}
}
}
return false ;
}
2015-11-12 09:49:49 +08:00
void FontAtlasCache : : reloadFontAtlasFNT ( const std : : string & fontFileName , const Vec2 & imageOffset /* = Vec2::ZERO*/ )
{
2016-03-25 21:21:09 +08:00
char tmp [ ATLAS_MAP_KEY_BUFFER ] ;
snprintf ( tmp , ATLAS_MAP_KEY_BUFFER , " %.2f %.2f %s " , imageOffset . x , imageOffset . y , fontFileName . c_str ( ) ) ;
2016-03-24 23:05:22 +08:00
std : : string atlasName = tmp ;
2015-11-12 09:49:49 +08:00
auto it = _atlasMap . find ( atlasName ) ;
if ( it ! = _atlasMap . end ( ) )
{
CC_SAFE_RELEASE_NULL ( it - > second ) ;
_atlasMap . erase ( it ) ;
}
FontFNT : : reloadBMFontResource ( fontFileName ) ;
auto font = FontFNT : : create ( fontFileName , imageOffset ) ;
if ( font )
{
auto tempAtlas = font - > createFontAtlas ( ) ;
if ( tempAtlas )
{
_atlasMap [ atlasName ] = tempAtlas ;
}
}
}
void FontAtlasCache : : unloadFontAtlasTTF ( const std : : string & fontFileName )
{
auto item = _atlasMap . begin ( ) ;
while ( item ! = _atlasMap . end ( ) )
{
2016-01-20 22:59:45 +08:00
if ( item - > first . find ( fontFileName ) ! = std : : string : : npos )
2015-11-12 09:49:49 +08:00
{
CC_SAFE_RELEASE_NULL ( item - > second ) ;
item = _atlasMap . erase ( item ) ;
}
else
item + + ;
}
}
2014-01-04 18:22:50 +08:00
NS_CC_END