+bool FontClient::Plugin::IsScalable( const FontPath& path )
+{
+ FT_Face ftFace;
+ int error = FT_New_Face( mFreeTypeLibrary,
+ path.c_str(),
+ 0,
+ &ftFace );
+ if( FT_Err_Ok != error )
+ {
+ DALI_LOG_ERROR( "FreeType Cannot check font: %s\n", path.c_str() );
+ }
+ return ( ftFace->num_fixed_sizes == 0 );
+}
+
+bool FontClient::Plugin::IsScalable( const FontDescription& fontDescription )
+{
+ // Create a font pattern.
+ FcPattern* fontFamilyPattern = CreateFontFamilyPattern( fontDescription );
+
+ FcResult result = FcResultMatch;
+
+ // match the pattern
+ FcPattern* match = FcFontMatch( NULL /* use default configure */, fontFamilyPattern, &result );
+ bool isScalable = true;
+
+ if( match )
+ {
+ // Get the path to the font file name.
+ FontPath path;
+ GetFcString( match, FC_FILE, path );
+ isScalable = IsScalable( path );
+ }
+ else
+ {
+ DALI_LOG_ERROR( "FreeType Cannot check font: %s %d %d %d\n",
+ fontDescription.family.c_str(),
+ fontDescription.width,
+ fontDescription.weight,
+ fontDescription.slant );
+ }
+ FcPatternDestroy( fontFamilyPattern );
+ FcPatternDestroy( match );
+ return isScalable;
+}
+
+void FontClient::Plugin::GetFixedSizes( const FontPath& path, Vector< PointSize26Dot6 >& sizes )
+{
+ // Empty the caller container
+ sizes.Clear();
+
+ FT_Face ftFace;
+ int error = FT_New_Face( mFreeTypeLibrary,
+ path.c_str(),
+ 0,
+ &ftFace );
+ if( FT_Err_Ok != error )
+ {
+ DALI_LOG_ERROR( "FreeType Cannot check font: %s\n", path.c_str() );
+ }
+
+ // Fetch the number of fixed sizes available
+ if ( ftFace->num_fixed_sizes && ftFace->available_sizes )
+ {
+ for ( int i = 0; i < ftFace->num_fixed_sizes; ++i )
+ {
+ sizes.PushBack( ftFace->available_sizes[ i ].size );
+ }
+ }
+}
+
+void FontClient::Plugin::GetFixedSizes( const FontDescription& fontDescription,
+ Vector< PointSize26Dot6 >& sizes )
+{
+ // Create a font pattern.
+ FcPattern* fontFamilyPattern = CreateFontFamilyPattern( fontDescription );
+
+ FcResult result = FcResultMatch;
+
+ // match the pattern
+ FcPattern* match = FcFontMatch( NULL /* use default configure */, fontFamilyPattern, &result );
+
+ if( match )
+ {
+ // Get the path to the font file name.
+ FontPath path;
+ GetFcString( match, FC_FILE, path );
+ GetFixedSizes( path, sizes );
+ }
+ else
+ {
+ DALI_LOG_ERROR( "FreeType Cannot check font: %s %d %d %d\n",
+ fontDescription.family.c_str(),
+ fontDescription.width,
+ fontDescription.weight,
+ fontDescription.slant );
+ }
+ FcPatternDestroy( match );
+ FcPatternDestroy( fontFamilyPattern );
+}
+
+void FontClient::Plugin::CacheFontPath( FT_Face ftFace, FontId id, PointSize26Dot6 requestedPointSize, const FontPath& path )
+{
+ FontDescription description;
+ description.path = path;
+ description.family = FontFamily( ftFace->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( ftFace->style_flags & FT_STYLE_FLAG_ITALIC )
+ {
+ description.slant = FontSlant::ITALIC;
+ }
+ if( ftFace->style_flags & FT_STYLE_FLAG_BOLD )
+ {
+ description.weight = FontWeight::BOLD;
+ }
+
+ FontDescriptionId validatedFontId = 0u;
+ if( !FindValidatedFont( description,
+ validatedFontId ) )
+ {
+ // Set the index to the vector of paths to font file names.
+ validatedFontId = mFontDescriptionCache.size();
+
+ // Add the path to the cache.
+ mFontDescriptionCache.push_back( description );
+
+ // Cache the index and the font's description.
+ FontDescriptionCacheItem item( description,
+ validatedFontId );
+
+ mValidatedFontCache.push_back( item );
+
+ // Cache the pair 'validatedFontId, requestedPointSize' to improve the following queries.
+ mFontIdCache.push_back( FontIdCacheItem( validatedFontId,
+ requestedPointSize,
+ id ) );
+ }
+}
+