From 1190ee283d32d881dafed0b87835356be16a876c Mon Sep 17 00:00:00 2001 From: Victor Cebollada Date: Fri, 18 Aug 2017 17:41:56 +0100 Subject: [PATCH] [3.0] FontClient - Create again the character set info. * The character set info stores the characters supported by a font. The font client stores a pointer to a FontConfig data structure that becomes invalid when the platform's default font changes. The font client reinitializes the font config library when the platform's default font changes making the character set pointers invalid. Change-Id: I9a1a1537760536d721576024c077873462af6bf5 Signed-off-by: Victor Cebollada --- .../text-abstraction/font-client-plugin-impl.cpp | 126 +++++++++++++++++++-- .../text-abstraction/font-client-plugin-impl.h | 12 +- 2 files changed, 127 insertions(+), 11 deletions(-) diff --git a/text/dali/internal/text-abstraction/font-client-plugin-impl.cpp b/text/dali/internal/text-abstraction/font-client-plugin-impl.cpp index 8eabda9..6e7d294 100644 --- a/text/dali/internal/text-abstraction/font-client-plugin-impl.cpp +++ b/text/dali/internal/text-abstraction/font-client-plugin-impl.cpp @@ -268,7 +268,7 @@ void FontClient::Plugin::ResetSystemDefaults() mDefaultFontDescriptionCached = false; } - void FontClient::Plugin::SetFontList( const FontDescription& fontDescription, FontList& fontList, CharacterSetList& characterSetList ) +void FontClient::Plugin::SetFontList( const FontDescription& fontDescription, FontList& fontList, CharacterSetList& characterSetList ) { DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::SetFontList\n" ); DALI_LOG_INFO( gLogFilter, Debug::General, " description; family : [%s]\n", fontDescription.family.c_str() ); @@ -369,7 +369,27 @@ void FontClient::Plugin::GetDefaultPlatformFontDescription( FontDescription& fon if( !mDefaultFontDescriptionCached ) { - FcInitReinitialize(); // FcInitBringUptoDate did not seem to reload config file as was still getting old default font. + // Clear any font config stored info in the caches. + mDefaultFontCharacterSets.Clear(); + mCharacterSetCache.Clear(); + + for( std::vector::iterator it = mFallbackCache.begin(), endIt = mFallbackCache.end(); it != endIt; ++it ) + { + FallbackCacheItem& item = *it; + + item.characterSets->Clear(); + } + + for( std::vector::iterator it = mFontCache.begin(), endIt = mFontCache.end(); it != endIt; ++it ) + { + FontFaceCacheItem& item = *it; + + // Set the character set pointer as null. Will be created again the next time IsCharacterSupportedByFont() + item.mCharacterSet = NULL; + } + + // FcInitBringUptoDate did not seem to reload config file as was still getting old default font. + FcInitReinitialize(); FcPattern* matchPattern = FcPatternCreate(); @@ -383,6 +403,41 @@ void FontClient::Plugin::GetDefaultPlatformFontDescription( FontDescription& fon FcPatternDestroy( matchPattern ); } + // Create again the character sets as they are not valid after FcInitReinitialize() + + for( FontList::const_iterator it = mDefaultFonts.begin(), endIt = mDefaultFonts.end(); it != endIt; ++it ) + { + const FontDescription& description = *it; + + mDefaultFontCharacterSets.PushBack( CreateCharacterSetFromDescription( description ) ); + } + + for( FontList::const_iterator it = mFontDescriptionCache.begin(), endIt = mFontDescriptionCache.end(); it != endIt; ++it ) + { + const FontDescription& description = *it; + + mCharacterSetCache.PushBack( CreateCharacterSetFromDescription( description ) ); + } + + for( std::vector::iterator it = mFallbackCache.begin(), endIt = mFallbackCache.end(); it != endIt; ++it ) + { + FallbackCacheItem& item = *it; + + if( NULL != item.fallbackFonts ) + { + if( NULL == item.characterSets ) + { + item.characterSets = new CharacterSetList; + } + + for( FontList::const_iterator flIt = item.fallbackFonts->begin(), flEndIt = item.fallbackFonts->end(); flIt != flEndIt; ++flIt ) + { + const FontDescription& description = *flIt; + item.characterSets->PushBack( CreateCharacterSetFromDescription( description ) ); + } + } + } + mDefaultFontDescriptionCached = true; } @@ -485,7 +540,32 @@ bool FontClient::Plugin::IsCharacterSupportedByFont( FontId fontId, Character ch bool isSupported = false; - const FontFaceCacheItem& cacheItem = mFontCache[fontId]; + FontFaceCacheItem& cacheItem = mFontCache[fontId]; + + if( NULL == cacheItem.mCharacterSet ) + { + // Create again the character set. + // It can be null if the ResetSystemDefaults() method has been called. + + FontDescription description; + description.path = cacheItem.mPath; + description.family = FontFamily( cacheItem.mFreeTypeFace->family_name ); + description.weight = FontWeight::NONE; + description.width = FontWidth::NONE; + description.slant = FontSlant::NONE; + + // Note FreeType doesn't give too much info to build a proper font style. + if( cacheItem.mFreeTypeFace->style_flags & FT_STYLE_FLAG_ITALIC ) + { + description.slant = FontSlant::ITALIC; + } + if( cacheItem.mFreeTypeFace->style_flags & FT_STYLE_FLAG_BOLD ) + { + description.weight = FontWeight::BOLD; + } + + cacheItem.mCharacterSet = CreateCharacterSetFromDescription( description ); + } isSupported = FcCharSetHasChar( cacheItem.mCharacterSet, character ); @@ -596,6 +676,7 @@ FontId FontClient::Plugin::FindDefaultFont( Character charcode, DALI_LOG_INFO( gLogFilter, Debug::General, " font id : %d\n", fontId ); DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::FindDefaultFont\n" ); + return fontId; } @@ -1098,6 +1179,9 @@ void FontClient::Plugin::CreateVectorBlob( FontId fontId, GlyphIndex glyphIndex, const GlyphInfo& FontClient::Plugin::GetEllipsisGlyph( PointSize26Dot6 requestedPointSize ) { + DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::GetEllipsisGlyph\n" ); + DALI_LOG_INFO( gLogFilter, Debug::General, " requestedPointSize %d.\n", requestedPointSize ); + // First look into the cache if there is an ellipsis glyph for the requested point size. for( Vector::ConstIterator it = mEllipsisCache.Begin(), endIt = mEllipsisCache.End(); @@ -1109,6 +1193,11 @@ const GlyphInfo& FontClient::Plugin::GetEllipsisGlyph( PointSize26Dot6 requested if( fabsf( item.requestedPointSize - requestedPointSize ) < Math::MACHINE_EPSILON_1000 ) { // Use the glyph in the cache. + + DALI_LOG_INFO( gLogFilter, Debug::General, " glyph id %d found in the cache.\n", item.glyph.index ); + DALI_LOG_INFO( gLogFilter, Debug::General, " font %d.\n", item.glyph.fontId ); + DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::GetEllipsisGlyph\n" ); + return item.glyph; } } @@ -1130,6 +1219,10 @@ const GlyphInfo& FontClient::Plugin::GetEllipsisGlyph( PointSize26Dot6 requested GetBitmapMetrics( &item.glyph, 1u, true ); + DALI_LOG_INFO( gLogFilter, Debug::General, " glyph id %d found in the cache.\n", item.glyph.index ); + DALI_LOG_INFO( gLogFilter, Debug::General, " font %d.\n", item.glyph.fontId ); + DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::GetEllipsisGlyph\n" ); + return item.glyph; } @@ -1177,11 +1270,6 @@ void FontClient::Plugin::InitSystemFonts() // Skip fonts with no path if( GetFcString( fontPattern, FC_FILE, path ) ) { - FcCharSet* characterSet = NULL; - FcPatternGetCharSet( fontPattern, FC_CHARSET, 0u, &characterSet ); - - mSystemFontCharacterSets.PushBack( characterSet ); - mSystemFonts.push_back( FontDescription() ); FontDescription& fontDescription = mSystemFonts.back(); @@ -1252,7 +1340,7 @@ bool FontClient::Plugin::MatchFontDescriptionToPattern( FcPattern* pattern, Dali return matched; } -FcPattern* FontClient::Plugin::CreateFontFamilyPattern( const FontDescription& fontDescription ) +FcPattern* FontClient::Plugin::CreateFontFamilyPattern( const FontDescription& fontDescription ) const { // create the cached font family lookup pattern // a pattern holds a set of names, each name refers to a property of the font @@ -1861,6 +1949,26 @@ void FontClient::Plugin::CacheFontPath( FT_Face ftFace, FontId id, PointSize26Do } } +FcCharSet* FontClient::Plugin::CreateCharacterSetFromDescription( const FontDescription& description ) const +{ + FcCharSet* characterSet = NULL; + + FcPattern* pattern = CreateFontFamilyPattern( description ); + + if( NULL != pattern ) + { + FcResult result = FcResultMatch; + FcPattern* match = FcFontMatch( NULL, pattern, &result ); + + FcPatternGetCharSet( match, FC_CHARSET, 0u, &characterSet ); + + FcPatternDestroy( match ); + FcPatternDestroy( pattern ); + } + + return characterSet; +} + } // namespace Internal } // namespace TextAbstraction diff --git a/text/dali/internal/text-abstraction/font-client-plugin-impl.h b/text/dali/internal/text-abstraction/font-client-plugin-impl.h index 856fed7..d0601e7 100644 --- a/text/dali/internal/text-abstraction/font-client-plugin-impl.h +++ b/text/dali/internal/text-abstraction/font-client-plugin-impl.h @@ -344,7 +344,7 @@ private: * * @return The pattern. */ - _FcPattern* CreateFontFamilyPattern( const FontDescription& fontDescription ); + _FcPattern* CreateFontFamilyPattern( const FontDescription& fontDescription ) const; /** * Retrieves the fonts present in the platform. @@ -476,6 +476,15 @@ private: */ void CacheFontPath( FT_Face ftFace, FontId id, PointSize26Dot6 requestedPointSize, const FontPath& path ); + /** + * @brief Creates a character set from a given font's @p description. + * + * @param[in] description The font's description. + * + * @return A character set. + */ + _FcCharSet* CreateCharacterSetFromDescription( const FontDescription& description ) const; + private: // Declared private and left undefined to avoid copies. @@ -494,7 +503,6 @@ private: FontList mSystemFonts; ///< Cached system fonts. FontList mDefaultFonts; ///< Cached default fonts. - CharacterSetList mSystemFontCharacterSets; CharacterSetList mDefaultFontCharacterSets; std::vector mFallbackCache; ///< Cached fallback font lists. -- 2.7.4