From 34f1daaec9e18358c93d8580ba2b77cf51dc1f6c Mon Sep 17 00:00:00 2001 From: Victor Cebollada Date: Fri, 27 Jun 2014 09:01:03 +0100 Subject: [PATCH] Adaptor - Handle font style correctly in the font controller. [problem] The font controller always retrieves a 'Regular' font style if no font name is given, even if a different font style is set (ex: Light) and a valid font for this style exists. [cause] If no font name is given, the font controller resets the style to default (which is Regular) as well. In general the font controller doesn't handle the font style completely. [solution] Fix the handle on font styles inside the font controller. Change-Id: I879ae3c12d88b32f51ce9c00d667a4948933f2a1 Signed-off-by: Victor Cebollada Signed-off-by: Adeel Kazmi --- platform-abstractions/interfaces/font-controller.h | 20 +- .../slp/data-cache/data-cache-impl.h | 4 +- .../slp/data-cache/metrics-cache.cpp | 10 +- .../slp/data-cache/metrics-cache.h | 8 +- .../slp/data-cache/tests/data-cache-debug.cpp | 2 +- .../slp/font-platform/font-controller-impl.cpp | 648 +++++++++++---------- .../slp/font-platform/font-controller-impl.h | 66 +-- .../slp/resource-loader/resource-loader.cpp | 68 ++- .../slp/resource-loader/resource-loader.h | 19 +- .../slp/slp-platform-abstraction.cpp | 33 +- .../slp/slp-platform-abstraction.h | 12 +- 11 files changed, 473 insertions(+), 417 deletions(-) diff --git a/platform-abstractions/interfaces/font-controller.h b/platform-abstractions/interfaces/font-controller.h index e1bbd60..cab28ce 100644 --- a/platform-abstractions/interfaces/font-controller.h +++ b/platform-abstractions/interfaces/font-controller.h @@ -76,24 +76,28 @@ public: * @param[in] styledFontFamily The name of the font's family and the font's style. * @return font file name. */ - virtual std::string GetFontPath( const StyledFontFamily& styledFontFamily ) = 0; + virtual const std::string& GetFontPath( const StyledFontFamily& styledFontFamily ) = 0; /** * Gets a list of fonts installed on the system. - * @param fontListMode which fonts to include in the list - * @return a list of styled font family names. + * @param[in] fontListMode which fonts to include in the list. + * @param[out] fontList The list of font family names. */ - virtual FontList GetFontList( FontListMode fontListMode ) = 0; + virtual void GetFontList( FontListMode fontListMode, FontList& fontList ) = 0; /** * Checks whether fontName is a valid font family name. * closestMatch is always set to the best matching font or the system default font if no near match is detected. * @param[in] styledFontFamily The name of the font's family and the font's style. - * @param[out] isDefaultSystemFont Whether this font has been created with a default system font. + * @param[out] isDefaultSystemFontFamily Whether this font has been created with a default system font family. + * @param[out] isDefaultSystemFontStyle Whether this font has been created with a default system font style. * @param[out] closestStyledFontFamilyMatch The name of the font's family and the font's style found based on the given input. * @return true if styledFontFamily is valid, false otherwise. */ - virtual bool ValidateFontFamilyName(const StyledFontFamily& styledFontFamily, bool& isDefaultSystemFont, StyledFontFamily& closestStyledFontFamilyMatch) = 0; + virtual bool ValidateFontFamilyName( const StyledFontFamily& styledFontFamily, + bool& isDefaultSystemFontFamily, + bool& isDefaultSystemFontStyle, + StyledFontFamily& closestStyledFontFamilyMatch ) = 0; /** * Returns font family name for displayed text. @@ -101,14 +105,14 @@ public: * Otherwise returns closest match. * @param[in] charsRequested displayed text. */ - virtual StyledFontFamily GetFontFamilyForChars(const TextArray& charsRequested) = 0; + virtual const StyledFontFamily& GetFontFamilyForChars( const TextArray& charsRequested ) = 0; /** * Checks whether all characters of text could be displayed with specified font family. * @param[in] styledFontFamily The name of the font's family and the font's style. * @param[in] text displayed text. */ - virtual bool AllGlyphsSupported(const StyledFontFamily& styledFontFamily, const TextArray& text) = 0; + virtual bool AllGlyphsSupported( const StyledFontFamily& styledFontFamily, const TextArray& text ) = 0; /** * Set the default font family and its style that should be used by the font controller. diff --git a/platform-abstractions/slp/data-cache/data-cache-impl.h b/platform-abstractions/slp/data-cache/data-cache-impl.h index f5b2810..35287e7 100644 --- a/platform-abstractions/slp/data-cache/data-cache-impl.h +++ b/platform-abstractions/slp/data-cache/data-cache-impl.h @@ -18,11 +18,9 @@ * */ -// EXTERNAL INCLUDES -#include - // INTERNAL INCLUDES #include "../../interfaces/data-cache.h" +#include namespace Dali { diff --git a/platform-abstractions/slp/data-cache/metrics-cache.cpp b/platform-abstractions/slp/data-cache/metrics-cache.cpp index 0b1a3e6..4e1402f 100644 --- a/platform-abstractions/slp/data-cache/metrics-cache.cpp +++ b/platform-abstractions/slp/data-cache/metrics-cache.cpp @@ -47,7 +47,7 @@ const std::string DALI_DEFAULT_FONT_CACHE_PATH( DALI_USER_FONT_CACHE_DIR ); const std::string METRICS_EXTENSION( ".metrics" ); -std::string CreateFileName(std::string fontFamily, std::string fontStyle) +std::string CreateFileName(const std::string& fontFamily, const std::string& fontStyle) { std::string cacheFileName(DALI_DEFAULT_FONT_CACHE_PATH + fontFamily + "-" + fontStyle + METRICS_EXTENSION); @@ -175,7 +175,7 @@ namespace SlpPlatform namespace MetricsCache { -bool ReadGlobal( std::string fontFamily, std::string fontStyle, Integration::GlobalMetrics& globalMetrics) +bool ReadGlobal( const std::string& fontFamily, const std::string& fontStyle, Integration::GlobalMetrics& globalMetrics) { bool success = false; @@ -203,7 +203,7 @@ bool ReadGlobal( std::string fontFamily, std::string fontStyle, Integration::Glo return success; } -void WriteGlobal( std::string fontFamily, std::string fontStyle, const Integration::GlobalMetrics& globalMetrics) +void WriteGlobal( const std::string& fontFamily, const std::string& fontStyle, const Integration::GlobalMetrics& globalMetrics) { std::string fileName = CreateFileName( fontFamily, fontStyle ); std::ios_base::openmode mode = ( std::ios::out | std::ios::binary | std::ios::trunc ); @@ -218,7 +218,7 @@ void WriteGlobal( std::string fontFamily, std::string fontStyle, const Integrati } } -bool Read( std::string fontFamily, std::string fontStyle, std::vector& glyphMetricsContainer ) +bool Read( const std::string& fontFamily, const std::string& fontStyle, std::vector& glyphMetricsContainer ) { std::string fileName = CreateFileName( fontFamily, fontStyle ); bool success( false ); @@ -266,7 +266,7 @@ bool Read( std::string fontFamily, std::string fontStyle, std::vector& glyphMetricsContainer ); +bool Read( const std::string& fontFamily, const std::string& fontStyle, std::vector& glyphMetricsContainer ); /** * Write the metrics into the given file @@ -60,7 +60,7 @@ bool Read( std::string fontFamily, std::string fontStyle, std::vector +#include // EXTERNAL INCLUDES #include -#include namespace Dali { diff --git a/platform-abstractions/slp/font-platform/font-controller-impl.cpp b/platform-abstractions/slp/font-platform/font-controller-impl.cpp index 4c79000..db4a327 100755 --- a/platform-abstractions/slp/font-platform/font-controller-impl.cpp +++ b/platform-abstractions/slp/font-platform/font-controller-impl.cpp @@ -47,43 +47,79 @@ const std::string SETTING_FONT_APP_FONT_PATH( FONT_APPLICATION_PATH ); const uint32_t UNICODE_CR_LF = 0x85; const uint32_t UNICODE_CHAR_START = 0x20; // start range of unicode characters (below are control chars) +const std::string FONT_FORMAT( "TrueType" ); +const std::string DEFAULT_FONT_FAMILY_NAME( "Tizen" ); +const std::string DEFAULT_FONT_STYLE( "Regular" ); + +const std::string NULL_FONT_FAMILY_NAME( "" ); +const FontController::StyledFontFamily NULL_STYLED_FONT_FAMILY( std::make_pair( NULL_FONT_FAMILY_NAME, std::string( "" ) ) ); /** * @param[in] pattern pointer to a font config pattern - * @return font style name or an empty string if the font has no style + * @param[out] familyName font family name or an empty string if the font is not found. + * @return Whether a font is found. */ -std::string GetFontStyle( const FcPattern *pattern ) +bool GetFontFamily( const FcPattern* pattern, std::string& familyName ) { - std::string styleName; - FcChar8 *style(NULL); - FcResult retVal = FcPatternGetString( pattern, FC_STYLE, 0, &style ); + FcChar8* family = NULL; + const FcResult retVal = FcPatternGetString( pattern, FC_FAMILY, 0u, &family ); - if( FcResultMatch == retVal) - { - styleName = reinterpret_cast(style); - } - else + if( FcResultMatch != retVal ) { - styleName = ""; + familyName.clear(); + return false; } - return styleName; + + // Have to use reinterpret_cast because FcChar8 is unsigned char*, not a const char*. + familyName.assign( reinterpret_cast( family ) ); + + return true; } -std::string GetFontFamily( const FcPattern *pattern ) +/** + * @param[in] pattern pointer to a font config pattern + * @param[out] fontStyle font style name or an empty string if the font has no style. + * @return Whether a font style is found. + */ +bool GetFontStyle( const FcPattern* pattern, std::string& fontStyle ) { - std::string familyName; - FcChar8 *family(NULL); - FcResult retVal = FcPatternGetString( pattern, FC_FAMILY, 0, &family ); + FcChar8* style = NULL; + const FcResult retVal = FcPatternGetString( pattern, FC_STYLE, 0u, &style ); - if( FcResultMatch == retVal) + if( FcResultMatch != retVal) { - familyName = reinterpret_cast(family); + // Has no style. + fontStyle.clear(); + return false; } - else + + // Have to use reinterpret_cast because FcChar8 is unsigned char*, not a const char*. + fontStyle.assign( reinterpret_cast( style ) ); + + return true; +} + +/** + * @param[in] pattern pointer to a font config pattern + * @param[out] fileName font file name or an empty string if the font is not found. + * @return Whether a font is found. + */ +bool GetFileName( const FcPattern* pattern, std::string& fileName ) +{ + FcChar8* file = NULL; + const FcResult retVal = FcPatternGetString( pattern, FC_FILE, 0u, &file ); + + if( FcResultMatch != retVal ) { - familyName = ""; + // Has no file name. + fileName.clear(); + return false; } - return familyName; + + // Have to use reinterpret_cast because FcChar8 is unsigned char*, not a const char*. + fileName.assign( reinterpret_cast( file ) ); + + return true; } bool CheckFontInstallPath( FontController::FontListMode listMode, const std::string& fileName ) @@ -97,8 +133,8 @@ bool CheckFontInstallPath( FontController::FontListMode listMode, const std::str const std::size_t preloadLength = preloadPath.length(); const std::size_t downloadLength = downloadPath.length(); - if( 0 == preloadPath.compare(0, preloadLength, fileName, 0, preloadLength) || - 0 == downloadPath.compare(0, downloadLength, fileName, 0, downloadLength)) + if( ( 0u == preloadPath.compare( 0u, preloadLength, fileName, 0u, preloadLength ) ) || + ( 0u == downloadPath.compare( 0u, downloadLength, fileName, 0u, downloadLength ) ) ) { return true; } @@ -109,7 +145,7 @@ bool CheckFontInstallPath( FontController::FontListMode listMode, const std::str const std::string& appPath( SETTING_FONT_APP_FONT_PATH ); const std::size_t appLength = appPath.length(); - if( 0 == appPath.compare(0, appLength, fileName, 0, appLength) ) + if( 0u == appPath.compare( 0u, appLength, fileName, 0u, appLength ) ) { return true; } @@ -117,7 +153,7 @@ bool CheckFontInstallPath( FontController::FontListMode listMode, const std::str } default: { - DALI_ASSERT_DEBUG(0 && "unhandled FontListMode"); + DALI_ASSERT_DEBUG( false && "unhandled FontListMode" ); return false; } } @@ -131,65 +167,38 @@ FontController::FontController() FcConfigEnableHome(true); } -void FontController::CreatePreferedFontList( ) +FontController::~FontController() { - StyledFontFamily tizenFont; - tizenFont.first = "Tizen"; - tizenFont.second = "Regular"; + // clear the font family cache + ClearFontFamilyCache(); - // clear the current list - mPreferredFonts.clear(); + // Clear the preferred font list. + ClearPreferredFontList(); +} - _FcPattern* searchPattern = CreateFontFamilyPattern( tizenFont ); +const std::string& FontController::GetFontPath( const StyledFontFamily& styledFontFamily ) +{ + DALI_ASSERT_DEBUG( !styledFontFamily.first.empty() && !styledFontFamily.second.empty() && "FontController::GetFontPath(): The font name or the font style is empty. Probably they have not been validated." ); - FcResult result(FcResultMatch); + // lock the mFontFamilyCacheMutex and don't release it until the function finishes. + // If we release it then another thread may try to create the same duplicate data. + boost::mutex::scoped_lock lock( mFontFamilyCacheMutex ); - // Match the pattern. - std::string previousFont; + StyledFontFamily closestStyledFontFamilyMatch; - FcFontSet* fontSet = FcFontSort( NULL /* use default configure */, searchPattern, false /* don't trim */, NULL, &result ); + // first check to see if the font has been matched before. + closestStyledFontFamilyMatch = GetMatchedFont( styledFontFamily ); - for( int i=0; i < fontSet->nfont; ++i) + if( closestStyledFontFamilyMatch.first.empty() ) { - // we have already filled in the first entry with the default font - _FcPattern* pattern = fontSet->fonts[i]; - - StyledFontFamily styledFont; - - styledFont.first = GetFontFamily( pattern ); - styledFont.second = GetFontStyle( pattern ); - - if( styledFont.first != previousFont ) - { - mPreferredFonts.push_back( styledFont ); - } - if( i == 0 ) - { - mDefaultStyledFont = styledFont; - } - previousFont = styledFont.first; + // The font is not in the matches font cache. Use the given one. + closestStyledFontFamilyMatch = styledFontFamily; } - FcPatternDestroy( searchPattern ); - FcFontSetDestroy( fontSet ); + return GetCachedFontPath( closestStyledFontFamilyMatch ); } -FontController::~FontController() -{ - // clear the font family cache - ClearFontFamilyCache(); -} - -std::string FontController::GetFontPath( const StyledFontFamily& styledFontFamily ) -{ - StyledFontFamily closestMachedStyledFontFamily; - bool isDefault( false ); - - // if the font was not found, the path will be an empty string - return GetFontFamilyPath( styledFontFamily, isDefault, closestMachedStyledFontFamily ); -} - -FontList FontController::GetFontList( FontListMode fontListMode ) +void FontController::GetFontList( FontListMode fontListMode, FontList& fontList ) { // protect the mFontList from access by multiple threads // this is locked for the entire function, because we don't want two functions @@ -199,7 +208,9 @@ FontList FontController::GetFontList( FontListMode fontListMode ) // if we have already scanned for fonts, return the cached values if ( !mFontSystemList.empty() ) { - return GetCachedFontList( fontListMode ); + GetCachedFontList( fontListMode, fontList ); + + return; } // font list needs to be cached @@ -208,191 +219,251 @@ FontList FontController::GetFontList( FontListMode fontListMode ) boost::mutex::scoped_lock lock( mFontConfigMutex ); // use font config to get the font set which contains a list of fonts - FcFontSet* fontset = GetFontSet(); + FcFontSet* fontSet = GetFontSet(); - DALI_LOG_INFO (gLogFilter, Debug::Verbose, "number of fonts found: %d\n", fontset->nfont); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "number of fonts found: %d\n", fontSet->nfont ); - if( fontset ) + if( fontSet ) { std::string preload_path(SETTING_FONT_PRELOAD_FONT_PATH); std::string download_path(SETTING_FONT_DOWNLOADED_FONT_PATH); std::string application_path(SETTING_FONT_APP_FONT_PATH); - FcChar8 *file(NULL); - FcChar8 *family(NULL); - FcResult retVal; - for( int i = 0; i < fontset->nfont; ++i) + for( int i = 0u; i < fontSet->nfont; ++i ) { - retVal = FcPatternGetString(fontset->fonts[i], FC_FILE, 0, &file); - if( FcResultMatch != retVal) - { - continue; // has no file name - } + FcPattern* fontPattern = fontSet->fonts[i]; + std::string fileName; - retVal = FcPatternGetString(fontset->fonts[i], FC_FAMILY, 0, &family); - if( FcResultMatch != retVal) + if( !GetFileName( fontPattern, fileName ) ) { - continue; // has no font name + continue; // Has no file name. Jump to the next iteration. } - std::string fileName(reinterpret_cast(file)); - // this is checking to make sure the font is in either the normal font path, or download path - if( 0 == preload_path.compare(0, preload_path.length(), fileName, 0, preload_path.length()) || - 0 == download_path.compare(0, download_path.length(), fileName, 0, download_path.length()) || - 0 == application_path.compare(0, application_path.length(), fileName, 0, application_path.length()) ) + if( 0u == preload_path.compare( 0u, preload_path.length(), fileName, 0u, preload_path.length() ) || + 0u == download_path.compare( 0u, download_path.length(), fileName, 0u, download_path.length() ) || + 0u == application_path.compare( 0u, application_path.length(), fileName, 0u, application_path.length() ) ) { - const std::string fontFamily( reinterpret_cast(family)); - const std::string fontStyle = GetFontStyle( fontset->fonts[i]); + StyledFontFamily styledFontFamily; + + if( !GetFontFamily( fontPattern, styledFontFamily.first ) ) + { + continue; // Has no font name. Jump to the next iteration. + } + + GetFontStyle( fontPattern, styledFontFamily.second ); // Add the font to the either the system or application font list - AddToFontList( fileName, std::make_pair( fontFamily, fontStyle ) ); + AddToFontList( fileName, styledFontFamily ); } } // delete the font set - FcFontSetDestroy(fontset); + FcFontSetDestroy( fontSet ); } else { - DALI_ASSERT_ALWAYS( 0 && "No valid fonts found on system." ); + DALI_ASSERT_ALWAYS( false && "No valid fonts found on system." ); } + // return the font list for the specified mode - return GetCachedFontList( fontListMode ); + GetCachedFontList( fontListMode, fontList ); } -bool FontController::ValidateFontFamilyName( const StyledFontFamily& styledFontFamily, bool& isDefaultSystemFont, StyledFontFamily& closestStyledFontFamilyMatch ) +bool FontController::ValidateFontFamilyName( const StyledFontFamily& styledFontFamily, + bool& isDefaultSystemFontFamily, + bool& isDefaultSystemFontStyle, + StyledFontFamily& closestStyledFontFamilyMatch ) { - // get font family path also finds the closest match - std::string path = GetFontFamilyPath( styledFontFamily, isDefaultSystemFont, closestStyledFontFamilyMatch ); + // Initialize the defaults to false as the validation process supposes the given font is correct. + isDefaultSystemFontFamily = false; + isDefaultSystemFontStyle = false; + + // default the closest Match to empty + closestStyledFontFamilyMatch.first.clear(); + closestStyledFontFamilyMatch.second.clear(); + + // lock the mFontFamilyCacheMutex and don't release it until the function finishes. + // If we release it then another thread may try to create the same duplicate data. + boost::mutex::scoped_lock lock( mFontFamilyCacheMutex ); - // it should always find a closest match - DALI_ASSERT_ALWAYS( !closestStyledFontFamilyMatch.first.empty() && "Cannot find closest match for font family" ); + StyledFontFamily styledFontFamilyToCheck = styledFontFamily; - if( path.empty() ) + // if the font is blank, then use the default font if it has been cached + if( styledFontFamilyToCheck.first.empty() && ( !mDefaultStyledFont.first.empty() ) ) { - return false; + styledFontFamilyToCheck.first = mDefaultStyledFont.first; + + // No font family is given, default system font is used. + isDefaultSystemFontFamily = true; } - else + + if( styledFontFamilyToCheck.second.empty() && ( !mDefaultStyledFont.second.empty() ) ) + { + styledFontFamilyToCheck.second = mDefaultStyledFont.second; + + // No font style is given, default system font is used. + isDefaultSystemFontStyle = true; + } + + // first check to see if the font has been matched before. + closestStyledFontFamilyMatch = GetMatchedFont( styledFontFamilyToCheck ); + + if( !closestStyledFontFamilyMatch.first.empty() ) + { + // The font has been cached before. + return true; + } + + // check the cache + const std::string& fontFileName = GetCachedFontPath( styledFontFamilyToCheck ); + + if( !fontFileName.empty() ) { + // The font has been cached before. + + closestStyledFontFamilyMatch = styledFontFamilyToCheck; + return true; } + + DALI_LOG_INFO( gLogFilter, Debug::Verbose,"Failed to find %s %s in cache, querying FontConfig for a match\n", styledFontFamily.first.c_str(), styledFontFamily.second.c_str() ); + + // it's not in the cache, find a match using font config and add it to the cache + boost::mutex::scoped_lock fcLock( mFontConfigMutex ); + + // create the pattern + FcPattern* fontFamilyPattern = CreateFontFamilyPattern( styledFontFamilyToCheck ); + + FcResult result(FcResultMatch); + + // match the pattern + FcPattern* match = FcFontMatch( NULL /* use default configure */, fontFamilyPattern, &result ); + + bool validFont = false; + + if( match ) + { + validFont = true; + + CacheFontInfo( match, styledFontFamilyToCheck, closestStyledFontFamilyMatch ); + + // destroyed the matched pattern + FcPatternDestroy( match ); + } + else + { + DALI_LOG_ERROR( "FcFontMatch failed for font %s %s\n", styledFontFamilyToCheck.first.c_str(), styledFontFamilyToCheck.second.c_str() ); + } + + // destroy the pattern + FcPatternDestroy( fontFamilyPattern ); + + return validFont; } -FontController::StyledFontFamily FontController::GetFontFamilyForChars(const TextArray& charsRequested) +const FontController::StyledFontFamily& FontController::GetFontFamilyForChars( const TextArray& charsRequested ) { - if( mPreferredFonts.empty() ) + if( 0u == mPreferredFonts.Count() ) { CreatePreferedFontList(); } // Cycle through the preferred list of fonts on the system for 'Tizen'. - for( std::size_t n = 0; n < mPreferredFonts.size() ; n++ ) + for( std::size_t n = 0u; n < mPreferredFonts.Count(); ++n ) { - StyledFontFamily font = mPreferredFonts[n]; + const StyledFontFamily& font = *mPreferredFonts[n]; - // First make sure it is cached so we can access it's character set object - std::string filePath = GetFontPath( font ); - if( filePath.empty()) + if( !mPreferredFontsValidated[n] ) { - filePath = GetFontPath( font ); + // First make sure it is validated and cached so we can access it's character set object + bool isDefaultSystemFontFamily = false; + bool isDefaultSystemFontStyle = false; + StyledFontFamily closestStyledFontFamilyMatch; + ValidateFontFamilyName( font, + isDefaultSystemFontFamily, + isDefaultSystemFontStyle, + closestStyledFontFamilyMatch ); + + mPreferredFontsValidated[n] = true; } - if( filePath.empty()) + const std::string& filePath = GetFontPath( font ); + + if( filePath.empty() ) { continue; } - bool matched = FontFamilySupportsText( font, charsRequested); + + const bool matched = FontFamilySupportsText( font, charsRequested ); if( matched ) { return font; } } + // return empty string - return StyledFontFamily(); + return NULL_STYLED_FONT_FAMILY; } -void FontController::CacheFontInfo(FcPattern* pattern, const StyledFontFamily& inputStyledFontFamily, StyledFontFamily& closestStyledFontFamilyMatch ) +void FontController::CacheFontInfo( FcPattern* pattern, const StyledFontFamily& inputStyledFontFamily, StyledFontFamily& closestStyledFontFamilyMatch ) { - FcChar8 *family, *file; - FcCharSet *matchedCharSet; - FcResult retVal; - // Check we can get the following data from the pattern - retVal = FcPatternGetString( pattern, FC_FAMILY, 0, &family ); - if( retVal != FcResultMatch ) + if( !GetFontFamily( pattern, closestStyledFontFamilyMatch.first ) ) { - DALI_LOG_INFO (gLogFilter, Debug::Verbose,"CacheFontInfo failed to get family information from pattern %s %s\n",inputStyledFontFamily.first.c_str(),inputStyledFontFamily.second.c_str()); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "CacheFontInfo failed to get family information from pattern %s %s\n", inputStyledFontFamily.first.c_str(), inputStyledFontFamily.second.c_str() ); return; } - retVal = FcPatternGetString( pattern, FC_FILE, 0, &file); - if( retVal!= FcResultMatch) + + std::string fileName; + if( !GetFileName( pattern, fileName ) ) { - DALI_LOG_INFO (gLogFilter, Debug::Verbose,"CacheFontInfo failed to get file information from pattern %s %s\n",inputStyledFontFamily.first.c_str(),inputStyledFontFamily.second.c_str()); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "CacheFontInfo failed to get file information from pattern %s %s\n", inputStyledFontFamily.first.c_str(), inputStyledFontFamily.second.c_str() ); return; } - retVal = FcPatternGetCharSet( pattern, FC_CHARSET, 0, &matchedCharSet); - if( retVal!= FcResultMatch) + + FcCharSet* matchedCharSet = NULL; + const FcResult retVal = FcPatternGetCharSet( pattern, FC_CHARSET, 0u, &matchedCharSet ); + if( retVal != FcResultMatch ) { - DALI_LOG_INFO (gLogFilter, Debug::Verbose,"CacheFontInfo failed to get character set from pattern %s %s\n",inputStyledFontFamily.first.c_str(),inputStyledFontFamily.second.c_str()); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "CacheFontInfo failed to get character set from pattern %s %s\n", inputStyledFontFamily.first.c_str(), inputStyledFontFamily.second.c_str() ); return; } - // have to use reinterpret_cast because FcChar8 is unsigned char *, not a char * - std::string familyName = reinterpret_cast(family); - std::string fileName = reinterpret_cast(file); - std::string fontStyle = GetFontStyle( pattern ); - - closestStyledFontFamilyMatch = std::make_pair( familyName, fontStyle ); + GetFontStyle( pattern, closestStyledFontFamilyMatch.second ); // Add the match to the font cache AddCachedFont( closestStyledFontFamilyMatch, fileName, matchedCharSet ); - if( ( !inputStyledFontFamily.first.empty() && - inputStyledFontFamily.first != familyName ) || - ( inputStyledFontFamily.second != fontStyle )) + ( inputStyledFontFamily.first != closestStyledFontFamilyMatch.first ) ) && + ( !inputStyledFontFamily.second.empty() && + ( inputStyledFontFamily.second != closestStyledFontFamilyMatch.second ) ) ) { // if the font family used to create the pattern was not found in the match then // store it in the MissingFont container - AddFontNotFound( inputStyledFontFamily, closestStyledFontFamilyMatch ); + AddMatchedFont( inputStyledFontFamily, closestStyledFontFamilyMatch ); } } -bool FontController::AllGlyphsSupported(const StyledFontFamily& styledFontFamily, const TextArray& text) +bool FontController::AllGlyphsSupported( const StyledFontFamily& styledFontFamily, const TextArray& text ) { - StyledFontFamily closestStyledFontFamilyMatch; - bool isDefault( false ); - - // make sure the font is cached first. - std::string path = GetFontFamilyPath( styledFontFamily, isDefault, closestStyledFontFamilyMatch ); - - if( path.empty() ) - { - DALI_LOG_INFO(gLogFilter, Debug::Verbose, "font family not found \n"); - return false; - } - - return FontFamilySupportsText( styledFontFamily, text); + // The font has already been validated by the font implementation. + return FontFamilySupportsText( styledFontFamily, text ); } void FontController::SetDefaultFontFamily( const StyledFontFamily& styledFontFamily ) { // reload font configuration files - bool ok = FcInitReinitialize(); + const bool ok = FcInitReinitialize(); DALI_ASSERT_ALWAYS( ok && "FcInitReinitialize failed"); CreatePreferedFontList(); } -void FontController::AddCachedFont(const StyledFontFamily& styledFontFamily, const std::string& fontPath, _FcCharSet *characterSet) +void FontController::AddCachedFont( const StyledFontFamily& styledFontFamily, const std::string& fontPath, _FcCharSet *characterSet ) { - if( styledFontFamily.first.empty() ) - { - return; - } - FontFamilyLookup::const_iterator iter = mFontFamilyCache.find( styledFontFamily ); if( iter == mFontFamilyCache.end() ) { @@ -402,34 +473,37 @@ void FontController::AddCachedFont(const StyledFontFamily& styledFontFamily, con item.FcCharSet = FcCharSetCopy( characterSet ); // increase the ref count on the char set mFontFamilyCache[ styledFontFamily ] = item; - DALI_LOG_INFO (gLogFilter, Debug::Verbose,"Caching font %s %s\n",styledFontFamily.first.c_str(), styledFontFamily.second.c_str()); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Caching font %s %s\n", styledFontFamily.first.c_str(), styledFontFamily.second.c_str() ); } } -FontList FontController::GetCachedFontList( FontListMode fontListMode ) const +void FontController::GetCachedFontList( FontListMode fontListMode, FontList& fontList ) const { // return a list of fonts, for the FontListMode switch( fontListMode ) { case LIST_SYSTEM_FONTS: { - return mFontSystemList; + fontList.insert( fontList.end(), mFontSystemList.begin(), mFontSystemList.end() ); + return; } case LIST_APPLICATION_FONTS: { - return mFontApplicationList; + fontList.insert( fontList.end(), mFontApplicationList.begin(), mFontApplicationList.end() ); + return; } case LIST_ALL_FONTS: { // add both system and application fonts together - FontList list( mFontSystemList ); - list.insert( list.end(), mFontApplicationList.begin(), mFontApplicationList.end() ); - return list; + fontList.insert( fontList.end(), mFontSystemList.begin(), mFontSystemList.end() ); + fontList.insert( fontList.end(), mFontApplicationList.begin(), mFontApplicationList.end() ); + return; } } - DALI_ASSERT_ALWAYS(!"GetCachedFontList called with invalid value."); + DALI_ASSERT_ALWAYS( false && "GetCachedFontList called with invalid value." ); } -std::string FontController::GetCachedFontPath( const StyledFontFamily& styledFontFamily ) const + +const std::string& FontController::GetCachedFontPath( const StyledFontFamily& styledFontFamily ) const { if( !mFontFamilyCache.empty() ) { @@ -439,7 +513,8 @@ std::string FontController::GetCachedFontPath( const StyledFontFamily& styledFon return (*iter).second.FontFileName; } } - return ""; + + return NULL_FONT_FAMILY_NAME; } FcCharSet* FontController::GetCachedFontCharacterSet( const StyledFontFamily& styledFontFamily ) const @@ -455,107 +530,20 @@ FcCharSet* FontController::GetCachedFontCharacterSet( const StyledFontFamily& st return NULL; } -std::string FontController::GetFontFamilyPath( const StyledFontFamily& styledFontFamily, bool& isDefaultSystemFont, StyledFontFamily& closestStyledFontFamilyMatch ) -{ - // Lets suppose the given font family is ok. - isDefaultSystemFont = false; - - // default the closest Match to empty - closestStyledFontFamilyMatch = std::make_pair("",""); - - std::string font( styledFontFamily.first ); - std::string style( styledFontFamily.second ); - - // lock the mFontFamilyCacheMutex and don't release it until the function finishes. - // If we release it then another thread may try to create the same duplicate data. - boost::mutex::scoped_lock lock( mFontFamilyCacheMutex ); - - // if the font is blank, then use the default font if it has been cached - if( font.empty() && ( !mDefaultStyledFont.first.empty() ) ) - { - font = mDefaultStyledFont.first; - style = mDefaultStyledFont.second; - - // No font family is given, default system font is used. - isDefaultSystemFont = true; - } - - StyledFontFamily styledFontFamilyToCheck = std::make_pair( font, style ); - - // first check to see if the font has been marked as not found - closestStyledFontFamilyMatch = GetFontNotFound( styledFontFamilyToCheck ); - - if( !closestStyledFontFamilyMatch.first.empty() ) - { - // the font wasn't found, so return an empty path - return ""; - } - - // check the cache - std::string fontFileName = GetCachedFontPath( styledFontFamilyToCheck ); - - if( !fontFileName.empty() ) - { - closestStyledFontFamilyMatch = std::make_pair( font, style ); - - return fontFileName; - } - - DALI_LOG_INFO( gLogFilter, Debug::Verbose,"Failed to find %s %s in cache, querying FontConfig for a match\n", styledFontFamily.first.c_str(), styledFontFamily.second.c_str()); - - // it's not in the cache, find a match using font config and add it to the cache - boost::mutex::scoped_lock fcLock( mFontConfigMutex ); - - // create the pattern - _FcPattern *fontFamilyPattern = CreateFontFamilyPattern( std::make_pair( font, style ) ); - - FcResult result(FcResultMatch); - - // match the pattern - _FcPattern *match = FcFontMatch( NULL /* use default configure */, fontFamilyPattern, &result ); - - if( match ) - { - CacheFontInfo(match, std::make_pair( font, style ), closestStyledFontFamilyMatch); - - fontFileName = GetCachedFontPath(closestStyledFontFamilyMatch); - - // destroyed the matched pattern - FcPatternDestroy( match ); - } - else - { - DALI_LOG_ERROR("FcFontMatch failed for font %s %s\n",font.c_str(),style.c_str()); - } - - // destroy the pattern - FcPatternDestroy( fontFamilyPattern ); - - if( closestStyledFontFamilyMatch != styledFontFamily ) - { - // the font wasn't font, so return an empty path - return ""; - } - else - { - return fontFileName; - } -} - -_FcPattern* FontController::CreateFontFamilyPattern(const StyledFontFamily& styledFontFamily) +_FcPattern* FontController::CreateFontFamilyPattern( const StyledFontFamily& styledFontFamily ) { // create the cached font family lookup pattern // a pattern holds a set of names, each name refers to a property of the font - _FcPattern *fontFamilyPattern = FcPatternCreate(); + FcPattern* fontFamilyPattern = FcPatternCreate(); // add a property to the pattern for the font family - FcPatternAddString( fontFamilyPattern, FC_FAMILY, (FcChar8 *)(styledFontFamily.first.c_str())); + FcPatternAddString( fontFamilyPattern, FC_FAMILY, reinterpret_cast( styledFontFamily.first.c_str() ) ); // add a property to the pattern for the font family - FcPatternAddString( fontFamilyPattern, FC_STYLE, (FcChar8 *)(styledFontFamily.second.c_str())); + FcPatternAddString( fontFamilyPattern, FC_STYLE, reinterpret_cast( styledFontFamily.second.c_str() ) ); // Add a property of the pattern, to say we want to match TrueType fonts - FcPatternAddString( fontFamilyPattern , FC_FONTFORMAT, (FcChar8 *)"TrueType"); + FcPatternAddString( fontFamilyPattern , FC_FONTFORMAT, reinterpret_cast( FONT_FORMAT.c_str() ) ); // modify the config, with the mFontFamilyPatterm FcConfigSubstitute( NULL /* use default configure */, fontFamilyPattern, FcMatchPattern ); @@ -567,34 +555,27 @@ _FcPattern* FontController::CreateFontFamilyPattern(const StyledFontFamily& styl return fontFamilyPattern; } -bool FontController::IsAControlCharacter(uint32_t character) const +bool FontController::IsAControlCharacter( uint32_t character ) const { // UNICODE_CHAR_START is the space character // below it are the control characters that we want to ignore. - if( character < UNICODE_CHAR_START || - character == UNICODE_CR_LF ) - { - return true; - } - else - { - return false; - } + return( ( character < UNICODE_CHAR_START ) || + ( character == UNICODE_CR_LF ) ); } -bool FontController::FontFamilySupportsText(const StyledFontFamily& styledFontFamily, const TextArray& text ) +bool FontController::FontFamilySupportsText( const StyledFontFamily& styledFontFamily, const TextArray& text ) { - _FcCharSet* charSet = GetCachedFontCharacterSet( styledFontFamily ); + FcCharSet* charSet = GetCachedFontCharacterSet( styledFontFamily ); DALI_ASSERT_ALWAYS( charSet && "No cached character set for font family" ); - size_t textLength = text.size(); + const size_t textLength = text.size(); // quick early exit before accessing font config for text arrays which are just a single control character - if( textLength == 1 ) + if( textLength == 1u ) { - if( IsAControlCharacter( text[0] ) ) + if( IsAControlCharacter( *text.begin() ) ) { return true; } @@ -603,19 +584,18 @@ bool FontController::FontFamilySupportsText(const StyledFontFamily& styledFontFa // protect font config boost::mutex::scoped_lock fcLock( mFontConfigMutex ); - for( TextArray::const_iterator iter = text.begin(), endIter = text.end(); iter != endIter; ++iter) + for( TextArray::const_iterator iter = text.begin(), endIter = text.end(); iter != endIter; ++iter ) { const uint32_t character = (*iter); // if it's a control character then don't test it - if( IsAControlCharacter( character) ) + if( IsAControlCharacter( character ) ) { continue; } // test to see if the character set supports the character - FcBool hasChar = FcCharSetHasChar(charSet, character ); - if( !hasChar ) + if( !FcCharSetHasChar( charSet, character ) ) { return false; } @@ -627,7 +607,7 @@ void FontController::ClearFontFamilyCache() { // should be called by the destructor only - for( FontFamilyLookup::iterator iter = mFontFamilyCache.begin(), enditer = mFontFamilyCache.end(); iter != enditer; ++iter) + for( FontFamilyLookup::iterator iter = mFontFamilyCache.begin(), enditer = mFontFamilyCache.end(); iter != enditer; ++iter ) { FontCacheItem& cacheItem = (*iter).second; @@ -638,9 +618,9 @@ void FontController::ClearFontFamilyCache() mFontFamilyCache.clear(); } -void FontController::AddToFontList(const std::string& fileName, const StyledFontFamily& styledFontFamily) +void FontController::AddToFontList( const std::string& fileName, const StyledFontFamily& styledFontFamily ) { - bool systemFont = CheckFontInstallPath(LIST_SYSTEM_FONTS, fileName); + const bool systemFont = CheckFontInstallPath( LIST_SYSTEM_FONTS, fileName ); FontList* fontList(NULL); @@ -664,19 +644,19 @@ _FcFontSet* FontController::GetFontSet() const { // create a new pattern. // a pattern holds a set of names, each name refers to a property of the font - FcPattern *pattern = FcPatternCreate(); + FcPattern* pattern = FcPatternCreate(); // create an object set used to define which properties are to be returned in the patterns from FcFontList. - FcObjectSet *objectSet = FcObjectSetCreate(); + FcObjectSet* objectSet = FcObjectSetCreate(); // build an object set from a list of property names - FcObjectSetAdd( objectSet, FC_FAMILY); - FcObjectSetAdd( objectSet, FC_STYLE); - FcObjectSetAdd( objectSet, FC_FILE); + FcObjectSetAdd( objectSet, FC_FAMILY ); + FcObjectSetAdd( objectSet, FC_STYLE ); + FcObjectSetAdd( objectSet, FC_FILE ); // get a list of fonts // creates patterns from those fonts containing only the objects in objectSet and returns the set of unique such patterns - FcFontSet *fontset = FcFontList( NULL /* the default configuration is checked to be up to date, and used */, pattern, objectSet); + FcFontSet* fontset = FcFontList( NULL /* the default configuration is checked to be up to date, and used */, pattern, objectSet ); // clear up the object set if( objectSet ) @@ -688,10 +668,11 @@ _FcFontSet* FontController::GetFontSet() const { FcPatternDestroy( pattern ); } + return fontset; } -_FcCharSet* FontController::CreateCharacterSet(const TextArray& charsRequested) +_FcCharSet* FontController::CreateCharacterSet( const TextArray& charsRequested ) { // create the character set object FcCharSet* charSet = FcCharSetCreate(); @@ -699,14 +680,14 @@ _FcCharSet* FontController::CreateCharacterSet(const TextArray& charsRequested) bool validCharAdded(false); // add valid characters to the character set. - for (TextArray::const_iterator iter = charsRequested.begin(), endIter = charsRequested.end(); iter != endIter; ++iter) + for( TextArray::const_iterator iter = charsRequested.begin(), endIter = charsRequested.end(); iter != endIter; ++iter ) { const uint32_t character = (*iter); // if it's not a control character then add it if( !IsAControlCharacter( character ) ) { - FcBool ok = FcCharSetAddChar(charSet, character ); + FcBool ok = FcCharSetAddChar( charSet, character ); if( ok ) { validCharAdded = true; @@ -722,26 +703,81 @@ _FcCharSet* FontController::CreateCharacterSet(const TextArray& charsRequested) return charSet; } -void FontController::AddFontNotFound( const StyledFontFamily& missingStyledFontFamily, StyledFontFamily& closestStyledFontFamilyMatch ) +void FontController::AddMatchedFont( const StyledFontFamily& missingStyledFontFamily, StyledFontFamily& closestStyledFontFamilyMatch ) { - // we store the missing font, and the name of the font that font config found as the closet match - mFontsNotFound[ missingStyledFontFamily ] = closestStyledFontFamilyMatch; + mMatchedFontsFound[ missingStyledFontFamily ] = closestStyledFontFamilyMatch; +} + +const FontController::StyledFontFamily& FontController::GetMatchedFont( const StyledFontFamily& styledFontFamily ) const +{ + if( mMatchedFontsFound.empty() ) + { + return NULL_STYLED_FONT_FAMILY; + } + + MatchedFontLookup::const_iterator iter = mMatchedFontsFound.find( styledFontFamily ); + if( iter != mMatchedFontsFound.end() ) + { + return iter->second; + } + + return NULL_STYLED_FONT_FAMILY; } -FontController::StyledFontFamily FontController::GetFontNotFound(const StyledFontFamily& styledFontFamily) const +void FontController::CreatePreferedFontList( ) { - if( mFontsNotFound.empty() ) + StyledFontFamily tizenFont; + tizenFont.first = DEFAULT_FONT_FAMILY_NAME; + tizenFont.second = DEFAULT_FONT_STYLE; + + // clear the current list + ClearPreferredFontList(); + + FcPattern* searchPattern = CreateFontFamilyPattern( tizenFont ); + + FcResult result(FcResultMatch); + + // Match the pattern. + StyledFontFamily previousFont; + + FcFontSet* fontSet = FcFontSort( NULL /* use default configure */, searchPattern, false /* don't trim */, NULL, &result ); + + for( int i = 0u; i < fontSet->nfont; ++i ) { - return std::make_pair("",""); + // we have already filled in the first entry with the default font + FcPattern* pattern = fontSet->fonts[i]; + + StyledFontFamily* styledFont = new StyledFontFamily(); + + GetFontFamily( pattern, styledFont->first ); + GetFontStyle( pattern, styledFont->second ); + + if( *styledFont != previousFont ) + { + mPreferredFonts.PushBack( styledFont ); + } + if( i == 0u ) + { + mDefaultStyledFont = *styledFont; + } + previousFont = *styledFont; } - FontsNotFound::const_iterator iter = mFontsNotFound.find( styledFontFamily ); - if( iter != mFontsNotFound.end() ) + // Set all fonts to non validated. + mPreferredFontsValidated.Resize( fontSet->nfont, false ); + + FcPatternDestroy( searchPattern ); + FcFontSetDestroy( fontSet ); +} + +void FontController::ClearPreferredFontList() +{ + for( Vector::Iterator it = mPreferredFonts.Begin(), endIt = mPreferredFonts.End(); it != endIt; ++it ) { - return (*iter).second; + delete *it; } - return std::make_pair("",""); + mPreferredFonts.Clear(); } } // namespace SlpPlatform diff --git a/platform-abstractions/slp/font-platform/font-controller-impl.h b/platform-abstractions/slp/font-platform/font-controller-impl.h index c79943f..db2c86e 100644 --- a/platform-abstractions/slp/font-platform/font-controller-impl.h +++ b/platform-abstractions/slp/font-platform/font-controller-impl.h @@ -20,10 +20,11 @@ // INTERNAL INCLUDES #include "../../interfaces/font-controller.h" +#include +#include // EXTERNAL INCLUDES #include -#include // forward declarations of font config types @@ -75,28 +76,31 @@ public: * Internally caches the font file name for every font family passed in * @copydoc Dali::Platform::FontController::GetFontPath() */ - virtual std::string GetFontPath( const StyledFontFamily& styledFontFamily ); + virtual const std::string& GetFontPath( const StyledFontFamily& styledFontFamily ); /** * Internally caches the font list the first time it is called. * @copydoc Dali::Platform::FontController::GetFontList() */ - virtual FontList GetFontList( FontListMode fontListMode ); + virtual void GetFontList( FontListMode fontListMode, FontList& fontList ); /** * @copydoc Dali::Platform::FontController::ValidateFontFamilyName() */ - virtual bool ValidateFontFamilyName(const StyledFontFamily& styledFontFamily, bool& isDefaultSystemFont, StyledFontFamily& closestStyledFontFamilyMatch); + virtual bool ValidateFontFamilyName( const StyledFontFamily& styledFontFamily, + bool& isDefaultSystemFontFamily, + bool& isDefaultSystemFontStyle, + StyledFontFamily& closestStyledFontFamilyMatch ); /** * @copydoc Dali::Platform::FontController::GetFontFamilyForChars() */ - virtual StyledFontFamily GetFontFamilyForChars( const TextArray& charsRequested); + virtual const StyledFontFamily& GetFontFamilyForChars( const TextArray& charsRequested); /** * @copydoc Dali::Platform::FontController::AllGlyphsSupported() */ - virtual bool AllGlyphsSupported(const StyledFontFamily& styledFontFamily, const TextArray& text); + virtual bool AllGlyphsSupported( const StyledFontFamily& styledFontFamily, const TextArray& text ); /** * @copydoc Dali::Platform::FontController::SetDefaultFontFamily() @@ -110,14 +114,14 @@ private: * @param[in] fontListMode the font list mode * @return font list */ - FontList GetCachedFontList( FontListMode fontListMode ) const; + void GetCachedFontList( FontListMode fontListMode, FontList& fontList ) const; /** * returns the font path given a font family. * @param[in] styledFontFamily The name of the font's family and the font's style. - * @return font path. + * @return The font's file name path. */ - std::string GetCachedFontPath( const StyledFontFamily& styledFontFamily ) const; + const std::string& GetCachedFontPath( const StyledFontFamily& styledFontFamily ) const; /** * returns the cached character set for a font family. @@ -133,26 +137,14 @@ private: * @param[in] fontPath font path. * @param[in] characterSet font config character set object (not const because it's ref count is increased). */ - void AddCachedFont( const StyledFontFamily& styledFontFamily, const std::string& fontPath,_FcCharSet *characterSet); - - /** - * Given a font family and its style, it will return the path for that font family. - * If the font family is not found, then the closestMatchFamily is set - * to the closes matching font family. - * @param[in] styledFontFamily The name of the font's family and the font's style. - * @param[out] isDefaultSystemFont Whether this font has been created with a default system font. - * @param[out] closestStyledFontFamilyMatch name found based on the user input family name and style. - * @return path of the font family - */ - std::string GetFontFamilyPath( const StyledFontFamily& styledFontFamily, bool& isDefaultSystemFont, StyledFontFamily& closestStyledFontFamilyMatch ); - + void AddCachedFont( const StyledFontFamily& styledFontFamily, const std::string& fontPath, _FcCharSet *characterSet ); /** * Store information held in a fontconfig pattern, into the font cache. * Stores font name, filename and character set. * @param[in] pattern pointer to a font config pattern. * @param[in] inputStyledFontFamily font family name with its style used to perform the pattern match. - * @param[out] closestStyledFontFamilyMatch mached family name and style. + * @param[out] closestStyledFontFamilyMatch matched family name and style. */ void CacheFontInfo( _FcPattern* pattern, const StyledFontFamily& inputStyledFontFamily, StyledFontFamily& closestStyledFontFamilyMatch ); @@ -165,7 +157,7 @@ private: /** * Checks whether a character is a control character. */ - bool IsAControlCharacter(uint32_t character) const; + bool IsAControlCharacter( uint32_t character ) const; /** * Checks cached fonts to see if they support the text. @@ -173,7 +165,7 @@ private: * @param text text array. * @return true if the font family supports the text false if not. */ - bool FontFamilySupportsText(const StyledFontFamily& styledFontFamily, const TextArray& text ); + bool FontFamilySupportsText( const StyledFontFamily& styledFontFamily, const TextArray& text ); /** * Clear the font family cache. @@ -187,7 +179,7 @@ private: * @param fileName the font full filename with path * @param styledFontFamily The name of the font's family and the font's style. */ - void AddToFontList( const std::string& fileName, const StyledFontFamily& styledFontFamily); + void AddToFontList( const std::string& fileName, const StyledFontFamily& styledFontFamily ); /** * Returns a FontConfig font set, which has a list of fonts. @@ -200,21 +192,21 @@ private: * @param charsRequested array of characters. * @return a pointer to _FcCharSet object on success, NULL on failure. */ - _FcCharSet* CreateCharacterSet(const TextArray& charsRequested); + _FcCharSet* CreateCharacterSet( const TextArray& charsRequested ); /** - * Add a font that has not been found on the system. + * Add a font that has not been found on the system but a match has been found. * @param[in] missingStyledFontFamily the missing font and its style to add. * @param[in] closestStyledFontFamilyMatch it's nearest font and its style match. */ - void AddFontNotFound( const StyledFontFamily& missingStyledFontFamily, StyledFontFamily& closestStyledFontFamilyMatch ); + void AddMatchedFont( const StyledFontFamily& missingStyledFontFamily, StyledFontFamily& closestStyledFontFamilyMatch ); /** * Check the cache to see if a font and its style has been added to the missing fonts list. * @param styledFontFamily the font and its style to check. * @return the closest styled font that the missing styled font has been matched with by font-config. */ - StyledFontFamily GetFontNotFound(const StyledFontFamily& styledFontFamily) const; + const StyledFontFamily& GetMatchedFont( const StyledFontFamily& styledFontFamily ) const; /** * Create a preferred list of fonts to use for when GetFontFamilyForChars() is called. @@ -222,6 +214,11 @@ private: void CreatePreferedFontList(); /** + * Deletes all preferred fonts. + */ + void ClearPreferredFontList(); + + /** * Font cache item. */ struct FontCacheItem @@ -230,9 +227,9 @@ private: _FcCharSet* FcCharSet; ///< font config character set, used to test if a character is supported }; - typedef std::map FontFamilyLookup; ///< lookup for font names and font cache itmes + typedef std::map FontFamilyLookup; ///< lookup for font names and font cache itmes - typedef std::map FontsNotFound; ///< lookup for fonts that don't exist, and their nearest match return by FontConfig + typedef std::map MatchedFontLookup; ///< lookup for fonts that don't exist, and their nearest match return by FontConfig boost::mutex mFontConfigMutex; ///< FontConfig needs serializing because it isn't thread safe boost::mutex mFontFamilyCacheMutex; ///< to protect the FontFamilyCache data @@ -244,8 +241,9 @@ private: FontList mFontApplicationList; ///< cached list of application fonts FontFamilyLookup mFontFamilyCache; ///< cache of font names and corresponding font cache items - FontsNotFound mFontsNotFound; ///< lookup for fonts that haven't been found on the sytem, and the nearest matching font. - std::vector< StyledFontFamily > mPreferredFonts; ///< Ordered list of preferred fonts. + MatchedFontLookup mMatchedFontsFound; ///< lookup for fonts that haven't been found on the sytem, and the nearest matching font. + Vector mPreferredFonts; ///< Ordered list of preferred fonts. + Vector mPreferredFontsValidated; ///< Stores which of the prefered fonts have been validated. }; diff --git a/platform-abstractions/slp/resource-loader/resource-loader.cpp b/platform-abstractions/slp/resource-loader/resource-loader.cpp index ef8ff61..66efbf2 100755 --- a/platform-abstractions/slp/resource-loader/resource-loader.cpp +++ b/platform-abstractions/slp/resource-loader/resource-loader.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include // INTERNAL HEADERS @@ -30,6 +29,7 @@ #include #include #include +#include #include #include "resource-requester-base.h" #include "resource-bitmap-requester.h" @@ -509,22 +509,31 @@ void ResourceLoader::GetClosestImageSize( ResourcePointer resourceBuffer, } -std::string ResourceLoader::GetFontFamilyForChars(const TextArray& charsRequested) +const std::string& ResourceLoader::GetFontFamilyForChars( const TextArray& charsRequested ) { return mImpl->mFontController->GetFontFamilyForChars( charsRequested ).first; } -bool ResourceLoader::AllGlyphsSupported(const std::string &fontFamily, const std::string &fontStyle, const TextArray& charsRequested) +bool ResourceLoader::AllGlyphsSupported( const std::string& fontFamily, const std::string& fontStyle, const TextArray& charsRequested ) { - return mImpl->mFontController->AllGlyphsSupported( Platform::FontController::StyledFontFamily( fontFamily, fontStyle ), charsRequested); + // At this point fontFamily and fontStyle must have been validated. + return mImpl->mFontController->AllGlyphsSupported( Platform::FontController::StyledFontFamily( fontFamily, fontStyle ), charsRequested ); } -bool ResourceLoader::ValidateFontFamilyName(const std::string& fontFamily, const std::string& fontStyle, bool& isDefaultSystemFont, std::string& closestFontFamilyMatch, std::string& closestFontStyleMatch) +bool ResourceLoader::ValidateFontFamilyName( const std::string& fontFamily, + const std::string& fontStyle, + bool& isDefaultSystemFontFamily, + bool& isDefaultSystemFontStyle, + std::string& closestFontFamilyMatch, + std::string& closestFontStyleMatch ) { Platform::FontController::StyledFontFamily closestMatch; - bool result = mImpl->mFontController->ValidateFontFamilyName( Platform::FontController::StyledFontFamily( fontFamily, fontStyle ), isDefaultSystemFont, closestMatch); + bool result = mImpl->mFontController->ValidateFontFamilyName( Platform::FontController::StyledFontFamily( fontFamily, fontStyle ), + isDefaultSystemFontFamily, + isDefaultSystemFontStyle, + closestMatch ); closestFontFamilyMatch = closestMatch.first; closestFontStyleMatch = closestMatch.second; @@ -532,13 +541,15 @@ bool ResourceLoader::ValidateFontFamilyName(const std::string& fontFamily, const return result; } -const PixelSize ResourceLoader::GetFontLineHeightFromCapsHeight(const std::string fontFamily, const std::string& fontStyle, const CapsHeight& capsHeight, FT_Library freeType) +PixelSize ResourceLoader::GetFontLineHeightFromCapsHeight( const std::string& fontFamily, const std::string& fontStyle, CapsHeight capsHeight, FT_Library freeType ) { + // At this point fontFamily and fontStyle must have been validated. + PixelSize result(0); if (!fontFamily.empty()) { - std::string fontFileName = GetFontPath( fontFamily, fontStyle ); + const std::string& fontFileName = GetFontPath( fontFamily, fontStyle ); SlpFace* slpFace = LoadFontFace(fontFileName, PixelSize(capsHeight), freeType); if (slpFace) @@ -555,15 +566,11 @@ const PixelSize ResourceLoader::GetFontLineHeightFromCapsHeight(const std::strin return result; } -std::vector ResourceLoader::GetFontList( Dali::Integration::PlatformAbstraction::FontListMode mode ) +void ResourceLoader::GetFontList( Dali::Integration::PlatformAbstraction::FontListMode mode, std::vector& fontList ) { - std::vector result; - std::set uniqueFontNames; - // VCC TODO: A GetStyles() method which returns a list of styles for a given font family is needed. - Platform::FontController::FontList fontList; - Platform::FontController::FontListMode listMode; + Platform::FontController::FontListMode listMode = Platform::FontController::LIST_SYSTEM_FONTS; switch( mode ) { @@ -584,22 +591,21 @@ std::vector ResourceLoader::GetFontList( Dali::Integration::Platfor } default: { - DALI_ASSERT_DEBUG(0 && "invalid mode"); - return result; + DALI_ASSERT_DEBUG( false && "invalid mode" ); } } - fontList = mImpl->mFontController->GetFontList( listMode ); + Platform::FontController::FontList styledFontList; + mImpl->mFontController->GetFontList( listMode, styledFontList ); - for( Platform::FontController::FontList::const_iterator it = fontList.begin(), endIt = fontList.end(); it != endIt; ++it ) + std::set uniqueFontNames; + for( Platform::FontController::FontList::const_iterator it = styledFontList.begin(), endIt = styledFontList.end(); it != endIt; ++it ) { - uniqueFontNames.insert(it->first); + uniqueFontNames.insert( it->first ); } // copy into a vector - std::copy(uniqueFontNames.begin(), uniqueFontNames.end(), std::back_inserter(result)); - - return result; + std::copy( uniqueFontNames.begin(), uniqueFontNames.end(), std::back_inserter( fontList ) ); } @@ -611,6 +617,8 @@ GlyphSet* ResourceLoader::GetGlyphData (const TextResourceType& textRequest, const std::string& fontFamily, bool getBitmap) { + // At this point fontFamily and the font style stored in the textRequest must have been validated. + GlyphSet* glyphSet = NULL; size_t fontHash = textRequest.mFontHash; @@ -620,7 +628,7 @@ GlyphSet* ResourceLoader::GetGlyphData (const TextResourceType& textRequest, // path holds the font name if( !fontFamily.empty() ) { - std::string fontFileName = GetFontPath( fontFamily, textRequest.mStyle ); + const std::string& fontFileName = GetFontPath( fontFamily, textRequest.mStyle ); const bool highQuality(textRequest.mQuality == TextResourceType::TextQualityHigh); const unsigned int glyphQuality( highQuality ? GlyphMetrics::HIGH_QUALITY : GlyphMetrics::LOW_QUALITY ); @@ -748,10 +756,11 @@ void ResourceLoader::GetGlobalMetrics( FT_Library freeType, const std::string& fontStyle, GlobalMetrics& globalMetrics ) { - // path holds the font name + // At this point fontFamily and fontStyle must have been validated. + if( !fontFamily.empty() ) { - std::string fontFileName = GetFontPath( fontFamily, fontStyle ); + const std::string& fontFileName = GetFontPath( fontFamily, fontStyle ); SlpFace* slpFace = LoadFontFace( fontFileName, PixelSize( HIGH_QUALITY_PIXEL_SIZE), freeType ); if( slpFace ) @@ -893,11 +902,13 @@ bool ResourceLoader::SaveFile(const std::string& filename, std::vector< unsigned return result; } -Integration::BitmapPtr ResourceLoader::GetGlyphImage( FT_Library freeType, const std::string& fontFamily, const std::string& fontStyle, const float fontSize, const uint32_t character ) +Integration::BitmapPtr ResourceLoader::GetGlyphImage( FT_Library freeType, const std::string& fontFamily, const std::string& fontStyle, float fontSize, uint32_t character ) { + // At this point fontFamily and fontStyle must have been validated. + Integration::BitmapPtr image; - const std::string fontFileName = GetFontPath( fontFamily, fontStyle ); + const std::string& fontFileName = GetFontPath( fontFamily, fontStyle ); SlpFace* slpFace = LoadFontFace( fontFileName, PixelSize( Font::PointsToPixels( fontSize ) ), freeType ); if( NULL != slpFace ) @@ -913,8 +924,9 @@ void ResourceLoader::SetDefaultFontFamily( const std::string& fontFamily, const mImpl->mFontController->SetDefaultFontFamily( Platform::FontController::StyledFontFamily( fontFamily, fontStyle ) ); } -std::string ResourceLoader::GetFontPath(const std::string& fontFamily, const std::string& fontStyle) +const std::string& ResourceLoader::GetFontPath(const std::string& fontFamily, const std::string& fontStyle) { + // At this point fontFamily and fontStyle must have been validated. return mImpl->mFontController->GetFontPath(std::make_pair(fontFamily,fontStyle)); } diff --git a/platform-abstractions/slp/resource-loader/resource-loader.h b/platform-abstractions/slp/resource-loader/resource-loader.h index c645c55..974dd0f 100644 --- a/platform-abstractions/slp/resource-loader/resource-loader.h +++ b/platform-abstractions/slp/resource-loader/resource-loader.h @@ -321,27 +321,32 @@ public: /** * @copydoc PlatformAbstraction::GetFontFamilyForChars() */ - std::string GetFontFamilyForChars(const TextArray& charsRequested); + const std::string& GetFontFamilyForChars(const TextArray& charsRequested); /** * @copydoc PlatformAbstraction::AllGlyphsSupported() */ - bool AllGlyphsSupported(const std::string &fontFamily, const std::string &fontStyle, const TextArray& charsRequested); + bool AllGlyphsSupported(const std::string& fontFamily, const std::string& fontStyle, const TextArray& charsRequested); /** * @copydoc PlatformAbstraction::ValidateFontFamilyName() */ - bool ValidateFontFamilyName(const std::string& fontFamily, const std::string &fontStyle, bool& isDefaultSystemFont, std::string& closestFontFamilyMatch, std::string& closestFontStyleMatch); + bool ValidateFontFamilyName( const std::string& fontFamily, + const std::string& fontStyle, + bool& isDefaultSystemFontFamily, + bool& isDefaultSystemFontStyle, + std::string& closestFontFamilyMatch, + std::string& closestFontStyleMatch ); /** * @copydoc SlpPlatformAbstraction::GetFontLineHeightFromCapsHeight */ - const PixelSize GetFontLineHeightFromCapsHeight(const std::string fontFamily, const std::string &fontStyle, const CapsHeight& capsHeight, FT_Library freeType); + PixelSize GetFontLineHeightFromCapsHeight(const std::string& fontFamily, const std::string& fontStyle, CapsHeight capsHeight, FT_Library freeType); /** * @copydoc SlpPlatformAbstraction::GetFontList */ - std::vector GetFontList( Dali::Integration::PlatformAbstraction::FontListMode mode ); + void GetFontList( Dali::Integration::PlatformAbstraction::FontListMode mode, std::vector& fontList ); /** * @copydoc SlpPlatformAbstraction::LoadFile() @@ -376,7 +381,7 @@ public: * * @return The bitmap image. */ - Integration::BitmapPtr GetGlyphImage( FT_Library freeType, const std::string& fontFamily, const std::string& fontStyle, const float fontSize, const uint32_t character ); + Integration::BitmapPtr GetGlyphImage( FT_Library freeType, const std::string& fontFamily, const std::string& fontStyle, float fontSize, uint32_t character ); private: @@ -389,7 +394,7 @@ private: * @param[in] fontStyle The font's style. * @return The path to a font resource; the closest available match for the family parameter. */ - std::string GetFontPath(const std::string& fontFamily, const std::string& fontStyle); // not const because of mutex + const std::string& GetFontPath(const std::string& fontFamily, const std::string& fontStyle); // not const because of mutex private: struct ResourceLoaderImpl; diff --git a/platform-abstractions/slp/slp-platform-abstraction.cpp b/platform-abstractions/slp/slp-platform-abstraction.cpp index 8230ae1..4fd538d 100644 --- a/platform-abstractions/slp/slp-platform-abstraction.cpp +++ b/platform-abstractions/slp/slp-platform-abstraction.cpp @@ -50,6 +50,7 @@ namespace const std::string FONT_CONFIGURATION_FILE( FONT_CONFIGURATION_FILE_PATH ); ///< Default font configuration file const std::string DEFAULT_FONT_FAMILY( "HelveticaNeue" ); ///< Default font family when unable to retrieve from font configuration file const std::string DEFAULT_FONT_STYLE( "Book" ); ///< Default font style when unable to retrieve from font configuration file +const std::string NULL_FONT_FAMILY_NAME( "" ); const unsigned int NANOSECS_TO_MICROSECS( 1000 ); ///< 1000 nanoseconds = 1 microsecond /// Settings to float point conversion table @@ -109,18 +110,18 @@ void SlpPlatformAbstraction::Resume() } } -std::string SlpPlatformAbstraction::GetDefaultFontFamily() const +const std::string& SlpPlatformAbstraction::GetDefaultFontFamily() const { // VCC TODO: return default font style as well. return mDefaultFontFamily; } -const float SlpPlatformAbstraction::GetDefaultFontSize() const +float SlpPlatformAbstraction::GetDefaultFontSize() const { return mDefaultFontSize; } -const PixelSize SlpPlatformAbstraction::GetFontLineHeightFromCapsHeight(const std::string& fontFamily, const std::string& fontStyle, const CapsHeight& capsHeight) const +PixelSize SlpPlatformAbstraction::GetFontLineHeightFromCapsHeight(const std::string& fontFamily, const std::string& fontStyle, CapsHeight capsHeight) const { PixelSize result(0); @@ -253,14 +254,14 @@ void SlpPlatformAbstraction::SetDpi(unsigned int dpiHor, unsigned int dpiVer) } } -std::string SlpPlatformAbstraction::GetFontFamilyForChars(const TextArray& charsRequested) const +const std::string& SlpPlatformAbstraction::GetFontFamilyForChars(const TextArray& charsRequested) const { - std::string ret; - if (mResourceLoader) + if( mResourceLoader ) { - ret = mResourceLoader->GetFontFamilyForChars(charsRequested); + return mResourceLoader->GetFontFamilyForChars(charsRequested); } - return ret; + + return NULL_FONT_FAMILY_NAME; } bool SlpPlatformAbstraction::AllGlyphsSupported(const std::string &fontFamily, const std::string& fontStyle, const TextArray& charsRequested) const @@ -276,21 +277,23 @@ bool SlpPlatformAbstraction::AllGlyphsSupported(const std::string &fontFamily, c bool SlpPlatformAbstraction::ValidateFontFamilyName(const std::string& fontFamily, const std::string& fontStyle, bool& isDefaultSystemFont, std::string& closestMatch, std::string& closestStyleMatch) const { bool ret = false; - if (mResourceLoader) + if( mResourceLoader ) { - ret = mResourceLoader->ValidateFontFamilyName(fontFamily, fontStyle, isDefaultSystemFont, closestMatch, closestStyleMatch); + // TODO: Consider retrieve both isDefaultSystemFontFamily and isDefaultSystemFontStyle. + bool isDefaultFamily = false; + bool isDefaultStyle = false; + ret = mResourceLoader->ValidateFontFamilyName( fontFamily, fontStyle, isDefaultFamily, isDefaultStyle, closestMatch, closestStyleMatch ); + isDefaultSystemFont = isDefaultFamily && isDefaultStyle; } return ret; } -std::vector SlpPlatformAbstraction::GetFontList ( Dali::Integration::PlatformAbstraction::FontListMode mode ) const +void SlpPlatformAbstraction::GetFontList( Dali::Integration::PlatformAbstraction::FontListMode mode, std::vector& fontList ) const { - std::vector ret; - if (mResourceLoader) + if( mResourceLoader ) { - ret = mResourceLoader->GetFontList( mode ); + mResourceLoader->GetFontList( mode, fontList ); } - return ret; } bool SlpPlatformAbstraction::LoadFile( const std::string& filename, std::vector< unsigned char >& buffer ) const diff --git a/platform-abstractions/slp/slp-platform-abstraction.h b/platform-abstractions/slp/slp-platform-abstraction.h index 166084d..a7b54c6 100644 --- a/platform-abstractions/slp/slp-platform-abstraction.h +++ b/platform-abstractions/slp/slp-platform-abstraction.h @@ -127,17 +127,17 @@ public: // PlatformAbstraction overrides /** *@copydoc PlatformAbstraction::GetDefaultFontFamily() */ - virtual std::string GetDefaultFontFamily() const; + virtual const std::string& GetDefaultFontFamily() const; /** *@copydoc PlatformAbstraction::GetDefaultFontSize() */ - virtual const float GetDefaultFontSize() const; + virtual float GetDefaultFontSize() const; /** *@copydoc PlatformAbstraction::GetFontLineHeightFromCapsHeight() */ - virtual const PixelSize GetFontLineHeightFromCapsHeight(const std::string& fontFamily, const std::string& fontStyle, const CapsHeight& capsHeight) const; + virtual PixelSize GetFontLineHeightFromCapsHeight(const std::string& fontFamily, const std::string& fontStyle, CapsHeight capsHeight) const; /** * @copydoc PlatformAbstraction::GetGlyphData() @@ -167,7 +167,7 @@ public: // PlatformAbstraction overrides /** * @copydoc PlatformAbstraction::GetFontFamilyForChars() */ - std::string GetFontFamilyForChars(const TextArray& charsRequested) const; + const std::string& GetFontFamilyForChars(const TextArray& charsRequested) const; /** * @copydoc PlatformAbstraction::AllGlyphsSupported() @@ -177,12 +177,12 @@ public: // PlatformAbstraction overrides /** * @copydoc PlatformAbstraction::ValidateFontFamilyName() */ - virtual bool ValidateFontFamilyName(const std::string& fontFamily, const std::string& fontStyle, bool& isDefaultSystemFont, std::string& closestMatch, std::string& closestStyleMatch) const; + virtual bool ValidateFontFamilyName( const std::string& fontFamily, const std::string& fontStyle, bool& isDefaultSystemFont, std::string& closestMatch, std::string& closestStyleMatch) const; /** * @copydoc PlatformAbstraction::GetFontList() */ - virtual std::vector GetFontList ( Dali::Integration::PlatformAbstraction::FontListMode mode ) const; + virtual void GetFontList ( Dali::Integration::PlatformAbstraction::FontListMode mode, std::vector& fontList ) const; /** * @copydoc PlatformAbstraction::LoadFile() -- 2.7.4