/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// INTERNAL INCLUDES
#include <dali/devel-api/text-abstraction/font-list.h>
+
#include <dali/public-api/common/dali-vector.h>
#include <dali/public-api/common/vector-wrapper.h>
#include <dali/integration-api/debug.h>
FT_Done_FreeType( mFreeTypeLibrary );
}
+void FontClient::Plugin::ClearCache()
+{
+ mDefaultFontDescription = FontDescription();
+
+ mSystemFonts.clear();
+ mDefaultFonts.clear();
+
+ DestroyCharacterSets( mDefaultFontCharacterSets );
+ mDefaultFontCharacterSets.Clear();
+
+ ClearFallbackCache( mFallbackCache );
+ mFallbackCache.clear();
+
+ mFontIdCache.Clear();
+
+ ClearCharacterSetFromFontFaceCache();
+ mFontFaceCache.clear();
+
+ mValidatedFontCache.clear();
+ mFontDescriptionCache.clear();
+ mFontDescriptionCache.resize( 1u );
+
+ DestroyCharacterSets( mCharacterSetCache );
+ mCharacterSetCache.Clear();
+ mCharacterSetCache.Resize( 1u );
+
+ mFontDescriptionSizeCache.clear();
+
+ mEllipsisCache.Clear();
+ mPixelBufferCache.clear();
+ mEmbeddedItemCache.Clear();
+ mBitmapFontCache.clear();
+
+ mDefaultFontDescriptionCached = false;
+}
+
void FontClient::Plugin::SetDpi( unsigned int horizontalDpi,
unsigned int verticalDpi )
{
false );
fontFaceId = mFontIdCache[fontId-1u].id;
- mFontFaceCache[fontFaceId].mCharacterSet = mCharacterSetCache[validatedFontId];
+ mFontFaceCache[fontFaceId].mCharacterSet = FcCharSetCopy( mCharacterSetCache[validatedFontId] );
// Cache the pair 'validatedFontId, requestedPointSize' to improve the following queries.
mFontDescriptionSizeCache.push_back( FontDescriptionSizeCacheItem( validatedFontId,
switch( fontIdCacheItem.type )
{
- case FontDescription::FACE_FONT:
- {
- const FontFaceCacheItem& font = mFontFaceCache[fontIdCacheItem.id];
+ case FontDescription::FACE_FONT:
+ {
+ const FontFaceCacheItem& font = mFontFaceCache[fontIdCacheItem.id];
- FT_Face ftFace = font.mFreeTypeFace;
+ FT_Face ftFace = font.mFreeTypeFace;
#ifdef FREETYPE_BITMAP_SUPPORT
- // Check to see if we should be loading a Fixed Size bitmap?
- if( font.mIsFixedSizeBitmap )
- {
- FT_Select_Size( ftFace, font.mFixedSizeIndex ); ///< @todo: needs to be investigated why it's needed to select the size again.
- int error = FT_Load_Glyph( ftFace, glyph.index, FT_LOAD_COLOR );
- if ( FT_Err_Ok == error )
+ // Check to see if we should be loading a Fixed Size bitmap?
+ if( font.mIsFixedSizeBitmap )
{
- glyph.width = font.mFixedWidthPixels;
- glyph.height = font.mFixedHeightPixels;
- glyph.advance = font.mFixedWidthPixels;
- glyph.xBearing = 0.0f;
- glyph.yBearing = font.mFixedHeightPixels;
+ FT_Select_Size( ftFace, font.mFixedSizeIndex ); ///< @todo: needs to be investigated why it's needed to select the size again.
+ int error = FT_Load_Glyph( ftFace, glyph.index, FT_LOAD_COLOR );
+ if ( FT_Err_Ok == error )
+ {
+ glyph.width = font.mFixedWidthPixels;
+ glyph.height = font.mFixedHeightPixels;
+ glyph.advance = font.mFixedWidthPixels;
+ glyph.xBearing = 0.0f;
+ glyph.yBearing = font.mFixedHeightPixels;
- // Adjust the metrics if the fixed-size font should be down-scaled
- const float desiredFixedSize = static_cast<float>( font.mRequestedPointSize ) * FROM_266 / POINTS_PER_INCH * mDpiVertical;
+ // Adjust the metrics if the fixed-size font should be down-scaled
+ const float desiredFixedSize = static_cast<float>( font.mRequestedPointSize ) * FROM_266 / POINTS_PER_INCH * mDpiVertical;
- if( desiredFixedSize > 0.f )
- {
- const float scaleFactor = desiredFixedSize / font.mFixedHeightPixels;
+ if( desiredFixedSize > 0.f )
+ {
+ const float scaleFactor = desiredFixedSize / font.mFixedHeightPixels;
- glyph.width = glyph.width * scaleFactor ;
- glyph.height = glyph.height * scaleFactor;
- glyph.advance = glyph.advance * scaleFactor;
- glyph.xBearing = glyph.xBearing * scaleFactor;
- glyph.yBearing = glyph.yBearing * scaleFactor;
+ glyph.width = glyph.width * scaleFactor ;
+ glyph.height = glyph.height * scaleFactor;
+ glyph.advance = glyph.advance * scaleFactor;
+ glyph.xBearing = glyph.xBearing * scaleFactor;
+ glyph.yBearing = glyph.yBearing * scaleFactor;
- glyph.scaleFactor = scaleFactor;
+ glyph.scaleFactor = scaleFactor;
+ }
+ }
+ else
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::GetBitmapMetrics. FreeType Bitmap Load_Glyph error %d\n", error );
+ success = false;
}
}
else
- {
- DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::GetBitmapMetrics. FreeType Bitmap Load_Glyph error %d\n", error );
- success = false;
- }
- }
- else
#endif
- {
- int error = FT_Load_Glyph( ftFace, glyph.index, FT_LOAD_NO_AUTOHINT );
-
- if( FT_Err_Ok == error )
{
- glyph.width = static_cast< float >( ftFace->glyph->metrics.width ) * FROM_266;
- glyph.height = static_cast< float >( ftFace->glyph->metrics.height ) * FROM_266 ;
- if( horizontal )
+ int error = FT_Load_Glyph( ftFace, glyph.index, FT_LOAD_NO_AUTOHINT );
+
+ if( FT_Err_Ok == error )
{
- glyph.xBearing += static_cast< float >( ftFace->glyph->metrics.horiBearingX ) * FROM_266;
- glyph.yBearing += static_cast< float >( ftFace->glyph->metrics.horiBearingY ) * FROM_266;
+ glyph.width = static_cast< float >( ftFace->glyph->metrics.width ) * FROM_266;
+ glyph.height = static_cast< float >( ftFace->glyph->metrics.height ) * FROM_266 ;
+ if( horizontal )
+ {
+ glyph.xBearing += static_cast< float >( ftFace->glyph->metrics.horiBearingX ) * FROM_266;
+ glyph.yBearing += static_cast< float >( ftFace->glyph->metrics.horiBearingY ) * FROM_266;
+ }
+ else
+ {
+ glyph.xBearing += static_cast< float >( ftFace->glyph->metrics.vertBearingX ) * FROM_266;
+ glyph.yBearing += static_cast< float >( ftFace->glyph->metrics.vertBearingY ) * FROM_266;
+ }
}
else
{
- glyph.xBearing += static_cast< float >( ftFace->glyph->metrics.vertBearingX ) * FROM_266;
- glyph.yBearing += static_cast< float >( ftFace->glyph->metrics.vertBearingY ) * FROM_266;
+ success = false;
}
}
- else
- {
- success = false;
- }
+ break;
}
- break;
- }
- case FontDescription::BITMAP_FONT:
- {
- BitmapFontCacheItem& bitmapFontCacheItem = mBitmapFontCache[fontIdCacheItem.id];
-
- unsigned int index = 0u;
- for( auto& item : bitmapFontCacheItem.font.glyphs )
+ case FontDescription::BITMAP_FONT:
{
- if( item.utf32 == glyph.index )
+ BitmapFontCacheItem& bitmapFontCacheItem = mBitmapFontCache[fontIdCacheItem.id];
+
+ unsigned int index = 0u;
+ for( auto& item : bitmapFontCacheItem.font.glyphs )
{
- Devel::PixelBuffer& pixelBuffer = bitmapFontCacheItem.pixelBuffers[index];
- if( !pixelBuffer )
+ if( item.utf32 == glyph.index )
{
- pixelBuffer = LoadImageFromFile( item.url );
- }
+ Devel::PixelBuffer& pixelBuffer = bitmapFontCacheItem.pixelBuffers[index];
+ if( !pixelBuffer )
+ {
+ pixelBuffer = LoadImageFromFile( item.url );
+ }
- glyph.width = static_cast< float >( pixelBuffer.GetWidth() );
- glyph.height = static_cast< float >( pixelBuffer.GetHeight() );
- glyph.xBearing = 0.f;
- glyph.yBearing = glyph.height + item.descender;
- glyph.advance = glyph.width;
- glyph.scaleFactor = 1.f;
- break;
+ glyph.width = static_cast< float >( pixelBuffer.GetWidth() );
+ glyph.height = static_cast< float >( pixelBuffer.GetHeight() );
+ glyph.xBearing = 0.f;
+ glyph.yBearing = glyph.height + item.descender;
+ glyph.advance = glyph.width;
+ glyph.scaleFactor = 1.f;
+ break;
+ }
+ ++index;
}
- ++index;
- }
- success = true;
- break;
- }
- default:
- {
- DALI_LOG_INFO(gLogFilter, Debug::General, " Invalid type of font\n");
- }
+ success = true;
+ break;
+ }
+ default:
+ {
+ DALI_LOG_INFO(gLogFilter, Debug::General, " Invalid type of font\n");
+ }
}
}
else
if( ( fontId > 0u ) &&
( index < mFontIdCache.Count() ) )
{
+ data.isColorBitmap = false;
+ data.isColorEmoji = false;
+
const FontIdCacheItem& fontIdCacheItem = mFontIdCache[index];
switch( fontIdCacheItem.type )
{
- case FontDescription::FACE_FONT:
- {
- // For the software italics.
- bool isShearRequired = false;
+ case FontDescription::FACE_FONT:
+ {
+ // For the software italics.
+ bool isShearRequired = false;
- const FontFaceCacheItem& fontFaceCacheItem = mFontFaceCache[fontIdCacheItem.id];
- FT_Face ftFace = fontFaceCacheItem.mFreeTypeFace;
+ const FontFaceCacheItem& fontFaceCacheItem = mFontFaceCache[fontIdCacheItem.id];
+ FT_Face ftFace = fontFaceCacheItem.mFreeTypeFace;
- FT_Error error;
+ FT_Error error;
#ifdef FREETYPE_BITMAP_SUPPORT
- // Check to see if this is fixed size bitmap
- if( fontFaceCacheItem.mIsFixedSizeBitmap )
- {
- error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
- }
- else
-#endif
- {
- error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_NO_AUTOHINT );
- }
- if( FT_Err_Ok == error )
- {
- if( isBoldRequired && !( ftFace->style_flags & FT_STYLE_FLAG_BOLD ) )
+ // Check to see if this is fixed size bitmap
+ if( fontFaceCacheItem.mIsFixedSizeBitmap )
{
- // Does the software bold.
- FT_GlyphSlot_Embolden( ftFace->glyph );
+ error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
}
-
- if( isItalicRequired && !( ftFace->style_flags & FT_STYLE_FLAG_ITALIC ) )
+ else
+#endif
{
- // Will do the software italic.
- isShearRequired = true;
+ error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_NO_AUTOHINT );
}
+ if( FT_Err_Ok == error )
+ {
+ if( isBoldRequired && !( ftFace->style_flags & FT_STYLE_FLAG_BOLD ) )
+ {
+ // Does the software bold.
+ FT_GlyphSlot_Embolden( ftFace->glyph );
+ }
+
+ if( isItalicRequired && !( ftFace->style_flags & FT_STYLE_FLAG_ITALIC ) )
+ {
+ // Will do the software italic.
+ isShearRequired = true;
+ }
- FT_Glyph glyph;
- error = FT_Get_Glyph( ftFace->glyph, &glyph );
+ FT_Glyph glyph;
+ error = FT_Get_Glyph( ftFace->glyph, &glyph );
- // Convert to bitmap if necessary
- if ( FT_Err_Ok == error )
- {
- if( glyph->format != FT_GLYPH_FORMAT_BITMAP )
+ // Convert to bitmap if necessary
+ if( FT_Err_Ok == error )
{
- // Check whether we should create a bitmap for the outline
- if( glyph->format == FT_GLYPH_FORMAT_OUTLINE && outlineWidth > 0 )
+ if( glyph->format != FT_GLYPH_FORMAT_BITMAP )
{
- // Set up a stroker
- FT_Stroker stroker;
- error = FT_Stroker_New( mFreeTypeLibrary, &stroker );
-
- if( FT_Err_Ok == error )
+ // Check whether we should create a bitmap for the outline
+ if( glyph->format == FT_GLYPH_FORMAT_OUTLINE && outlineWidth > 0 )
{
- FT_Stroker_Set( stroker, outlineWidth * 64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0 );
- error = FT_Glyph_StrokeBorder( &glyph, stroker, 0, 1 );
+ // Set up a stroker
+ FT_Stroker stroker;
+ error = FT_Stroker_New( mFreeTypeLibrary, &stroker );
if( FT_Err_Ok == error )
{
- FT_Stroker_Done( stroker );
+ FT_Stroker_Set( stroker, outlineWidth * 64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0 );
+ error = FT_Glyph_StrokeBorder( &glyph, stroker, 0, 1 );
+
+ if( FT_Err_Ok == error )
+ {
+ FT_Stroker_Done( stroker );
+ }
+ else
+ {
+ DALI_LOG_ERROR( "FT_Glyph_StrokeBorder Failed with error: %d\n", error );
+ }
}
else
{
- DALI_LOG_ERROR( "FT_Glyph_StrokeBorder Failed with error: %d\n", error );
+ DALI_LOG_ERROR( "FT_Stroker_New Failed with error: %d\n", error );
}
}
+
+ error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, 0, 1 );
+ if( FT_Err_Ok == error )
+ {
+ FT_BitmapGlyph bitmapGlyph = reinterpret_cast< FT_BitmapGlyph >( glyph );
+ ConvertBitmap( data, bitmapGlyph->bitmap, isShearRequired );
+ }
else
{
- DALI_LOG_ERROR( "FT_Stroker_New Failed with error: %d\n", error );
+ DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::CreateBitmap. FT_Get_Glyph Failed with error: %d\n", error );
}
}
-
- error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, 0, 1 );
- if( FT_Err_Ok == error )
- {
- FT_BitmapGlyph bitmapGlyph = reinterpret_cast< FT_BitmapGlyph >( glyph );
- ConvertBitmap( data, bitmapGlyph->bitmap, isShearRequired );
- }
else
{
- DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::CreateBitmap. FT_Get_Glyph Failed with error: %d\n", error );
+ ConvertBitmap( data, ftFace->glyph->bitmap, isShearRequired );
}
- }
- else
- {
- ConvertBitmap( data, ftFace->glyph->bitmap, isShearRequired );
- }
- // Created FT_Glyph object must be released with FT_Done_Glyph
- FT_Done_Glyph( glyph );
+ data.isColorEmoji = fontFaceCacheItem.mIsFixedSizeBitmap;
+
+ // Created FT_Glyph object must be released with FT_Done_Glyph
+ FT_Done_Glyph( glyph );
+ }
+ }
+ else
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::CreateBitmap. FT_Load_Glyph Failed with error: %d\n", error );
}
+ break;
}
- else
+ case FontDescription::BITMAP_FONT:
{
- DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::CreateBitmap. FT_Load_Glyph Failed with error: %d\n", error );
- }
- break;
- }
- case FontDescription::BITMAP_FONT:
- {
- BitmapFontCacheItem& bitmapFontCacheItem = mBitmapFontCache[fontIdCacheItem.id];
+ BitmapFontCacheItem& bitmapFontCacheItem = mBitmapFontCache[fontIdCacheItem.id];
- unsigned int index = 0u;
- for( auto& item : bitmapFontCacheItem.font.glyphs )
- {
- if( item.utf32 == glyphIndex )
+ unsigned int index = 0u;
+ for( auto& item : bitmapFontCacheItem.font.glyphs )
{
- Devel::PixelBuffer& pixelBuffer = bitmapFontCacheItem.pixelBuffers[index];
- if( !pixelBuffer )
+ if( item.utf32 == glyphIndex )
{
- pixelBuffer = LoadImageFromFile( item.url );
- }
+ Devel::PixelBuffer& pixelBuffer = bitmapFontCacheItem.pixelBuffers[index];
+ if( !pixelBuffer )
+ {
+ pixelBuffer = LoadImageFromFile( item.url );
+ }
- data.width = pixelBuffer.GetWidth();
- data.height = pixelBuffer.GetHeight();
+ data.width = pixelBuffer.GetWidth();
+ data.height = pixelBuffer.GetHeight();
- ConvertBitmap( data, data.width, data.height, pixelBuffer.GetBuffer() );
+ data.isColorBitmap = bitmapFontCacheItem.font.isColorFont;
- // Sets the pixel format.
- data.format = pixelBuffer.GetPixelFormat();
- break;
+ ConvertBitmap( data, data.width, data.height, pixelBuffer.GetBuffer() );
+
+ // Sets the pixel format.
+ data.format = pixelBuffer.GetPixelFormat();
+ break;
+ }
+ ++index;
}
- ++index;
+ break;
+ }
+ default:
+ {
+ DALI_LOG_INFO(gLogFilter, Debug::General, " Invalid type of font\n");
}
- break;
- }
- default:
- {
- DALI_LOG_INFO(gLogFilter, Debug::General, " Invalid type of font\n");
- }
}
}
else
const FontId index = fontId - 1u;
-#ifdef FREETYPE_BITMAP_SUPPORT
if( ( fontId > 0u ) &&
( index < mFontIdCache.Count() ) )
{
switch( fontIdCacheItem.type )
{
- case FontDescription::FACE_FONT:
- {
- const FontFaceCacheItem& item = mFontFaceCache[fontIdCacheItem.id];
- FT_Face ftFace = item.mFreeTypeFace;
+ case FontDescription::FACE_FONT:
+ {
+#ifdef FREETYPE_BITMAP_SUPPORT
+ const FontFaceCacheItem& item = mFontFaceCache[fontIdCacheItem.id];
+ FT_Face ftFace = item.mFreeTypeFace;
- // Check to see if this is fixed size bitmap
- if( item.mHasColorTables )
+ // Check to see if this is fixed size bitmap
+ if( item.mHasColorTables )
+ {
+ error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
+ }
+#endif
+ break;
+ }
+ case FontDescription::BITMAP_FONT:
{
- error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
+ error = FT_Err_Ok; // Will return true;
+ break;
+ }
+ default:
+ {
+ DALI_LOG_INFO(gLogFilter, Debug::General, " Invalid type of font\n");
}
- break;
- }
- case FontDescription::BITMAP_FONT:
- {
- error = FT_Err_Ok; // Will return true;
- break;
- }
- default:
- {
- DALI_LOG_INFO(gLogFilter, Debug::General, " Invalid type of font\n");
- }
}
}
-#endif
return FT_Err_Ok == error;
}
bool FontClient::Plugin::AddCustomFontDirectory( const FontPath& path )
{
- // NULL as first parameter means the current configuration is used.
- return FcConfigAppFontAddDir( NULL, reinterpret_cast<const FcChar8 *>( path.c_str() ) );
+ // nullptr as first parameter means the current configuration is used.
+ return FcConfigAppFontAddDir( nullptr, reinterpret_cast<const FcChar8 *>( path.c_str() ) );
}
GlyphIndex FontClient::Plugin::CreateEmbeddedItem( const TextAbstraction::FontClient::EmbeddedItemDescription& description, Pixel::Format& pixelFormat )
FcPatternAddString( fontFamilyPattern, FC_FAMILY, reinterpret_cast<const FcChar8*>( fontDescription.family.c_str() ) );
// add a property to the pattern for local setting.
- const char* locale = setlocale( LC_MESSAGES, NULL );
- if( locale != NULL)
+ const char* locale = setlocale( LC_MESSAGES, nullptr );
+ if( locale != nullptr)
{
FcPatternAddString( fontFamilyPattern, FC_LANG, reinterpret_cast<const FcChar8*>( locale ) );
}