2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/text-abstraction/font-client-plugin-impl.h>
22 #include <dali/public-api/common/dali-vector.h>
23 #include <dali/public-api/common/vector-wrapper.h>
24 #include <dali/public-api/text-abstraction/glyph-info.h>
25 #include <dali/integration-api/debug.h>
28 #include <fontconfig/fontconfig.h>
31 * Conversion from Fractional26.6 to float
35 const float FROM_266 = 1.0f / 64.0f;
37 const std::string FONT_FORMAT( "TrueType" );
38 const std::string DEFAULT_FONT_FAMILY_NAME( "Tizen" );
39 const std::string DEFAULT_FONT_STYLE( "Regular" );
47 namespace TextAbstraction
53 const bool FONT_FIXED_SIZE_BITMAP( true );
55 FontClient::Plugin::FontDescriptionCacheItem::FontDescriptionCacheItem( const FontFamily& fontFamily,
56 const FontStyle& fontStyle,
57 FontDescriptionId index )
58 : fontFamily( fontFamily ),
59 fontStyle( fontStyle ),
64 FontClient::Plugin::FontIdCacheItem::FontIdCacheItem( FontDescriptionId validatedFontId,
65 PointSize26Dot6 pointSize,
67 : validatedFontId( validatedFontId ),
68 pointSize( pointSize ),
73 FontClient::Plugin::CacheItem::CacheItem( FT_Face ftFace,
75 PointSize26Dot6 pointSize,
77 const FontMetrics& metrics )
78 : mFreeTypeFace( ftFace ),
80 mPointSize( pointSize ),
83 mFixedWidthPixels( 0.0f ),
84 mFixedHeightPixels( 0.0f ),
85 mIsFixedSizeBitmap( false )
89 FontClient::Plugin::CacheItem::CacheItem( FT_Face ftFace,
91 PointSize26Dot6 pointSize,
93 const FontMetrics& metrics,
96 : mFreeTypeFace( ftFace ),
98 mPointSize( pointSize ),
101 mFixedWidthPixels( fixedWidth ),
102 mFixedHeightPixels( fixedHeight ),
103 mIsFixedSizeBitmap( true )
107 FontClient::Plugin::Plugin( unsigned int horizontalDpi,
108 unsigned int verticalDpi )
109 : mFreeTypeLibrary( NULL ),
110 mDpiHorizontal( horizontalDpi ),
111 mDpiVertical( verticalDpi ),
115 mValidatedFontCache(),
116 mFontDescriptionCache( 1u ),
119 int error = FT_Init_FreeType( &mFreeTypeLibrary );
120 if( FT_Err_Ok != error )
122 DALI_LOG_ERROR( "FreeType Init error: %d\n", error );
126 FontClient::Plugin::~Plugin()
128 FT_Done_FreeType( mFreeTypeLibrary );
131 void FontClient::Plugin::SetDpi( unsigned int horizontalDpi,
132 unsigned int verticalDpi )
134 mDpiHorizontal = horizontalDpi;
135 mDpiVertical = verticalDpi;
138 void FontClient::Plugin::SetDefaultFontFamily( const FontFamily& fontFamilyName,
139 const FontStyle& fontStyle )
141 mDefaultFonts.clear();
143 FcPattern* fontFamilyPattern = CreateFontFamilyPattern( fontFamilyName,
146 FcResult result = FcResultMatch;
148 // Match the pattern.
149 FcFontSet* fontSet = FcFontSort( NULL /* use default configure */,
151 false /* don't trim */,
155 if( NULL != fontSet )
157 // Reserve some space to avoid reallocations.
158 mDefaultFonts.reserve( fontSet->nfont );
160 for( int i = 0u; i < fontSet->nfont; ++i )
162 FcPattern* fontPattern = fontSet->fonts[i];
166 // Skip fonts with no path
167 if( GetFcString( fontPattern, FC_FILE, path ) )
169 mDefaultFonts.push_back( FontDescription() );
170 FontDescription& fontDescription = mDefaultFonts.back();
172 fontDescription.path = path;
174 GetFcString( fontPattern, FC_FAMILY, fontDescription.family );
175 GetFcString( fontPattern, FC_STYLE, fontDescription.style );
179 FcFontSetDestroy( fontSet );
182 FcPatternDestroy( fontFamilyPattern );
185 void FontClient::Plugin::GetDefaultFonts( FontList& defaultFonts )
187 if( mDefaultFonts.empty() )
189 SetDefaultFontFamily( DEFAULT_FONT_FAMILY_NAME,
190 DEFAULT_FONT_STYLE );
193 defaultFonts = mDefaultFonts;
196 void FontClient::Plugin::GetSystemFonts( FontList& systemFonts )
198 if( mSystemFonts.empty() )
203 systemFonts = mSystemFonts;
206 void FontClient::Plugin::GetDescription( FontId id,
207 FontDescription& fontDescription ) const
209 for( std::vector<FontIdCacheItem>::const_iterator it = mFontIdCache.begin(),
210 endIt = mFontIdCache.end();
214 const FontIdCacheItem& item = *it;
216 if( item.fontId == id )
218 fontDescription = *( mFontDescriptionCache.begin() + item.validatedFontId );
223 DALI_LOG_ERROR( "FontClient::Plugin::GetDescription. No description found for the font ID %d\n", id );
226 PointSize26Dot6 FontClient::Plugin::GetPointSize( FontId id )
228 const FontId index = id - 1u;
231 index < mFontCache.size() )
233 return ( *( mFontCache.begin() + index ) ).mPointSize;
237 DALI_LOG_ERROR( "FontClient::Plugin::GetPointSize. Invalid font ID %d\n", id );
240 return TextAbstraction::FontClient::DEFAULT_POINT_SIZE;
243 FontId FontClient::Plugin::FindDefaultFont( Character charcode,
244 PointSize26Dot6 requestedSize,
248 bool foundColor(false);
250 // Create the list of default fonts if it has not been created.
251 if( mDefaultFonts.empty() )
253 SetDefaultFontFamily( DEFAULT_FONT_FAMILY_NAME,
254 DEFAULT_FONT_STYLE );
257 // Traverse the list of default fonts.
258 // Check for each default font if supports the character.
260 for( FontList::const_iterator it = mDefaultFonts.begin(), endIt = mDefaultFonts.end();
264 const FontDescription& description = *it;
266 FcPattern* pattern = CreateFontFamilyPattern( description.family,
269 FcResult result = FcResultMatch;
270 FcPattern* match = FcFontMatch( NULL /* use default configure */, pattern, &result );
272 FcCharSet* charSet = NULL;
273 FcPatternGetCharSet( match, FC_CHARSET, 0u, &charSet );
275 if( FcCharSetHasChar( charSet, charcode ) )
277 Vector< PointSize26Dot6 > fixedSizes;
278 GetFixedSizes( description.family,
282 const Vector< PointSize26Dot6 >::SizeType count = fixedSizes.Count();
285 // If the font is not scalable, pick the largest size <= requestedSize
286 PointSize26Dot6 size = fixedSizes[0];
287 for( unsigned int i=1; i<count; ++i )
289 if( fixedSizes[i] <= requestedSize &&
290 fixedSizes[i] > size )
292 size = fixedSizes[i];
295 requestedSize = size;
298 fontId = GetFontId( description.family,
305 BufferImage bitmap = CreateBitmap( fontId, GetGlyphIndex(fontId,charcode) );
307 Pixel::BGRA8888 == bitmap.GetPixelFormat() )
313 // Keep going unless we prefer a different (color) font
314 if( !preferColor || foundColor )
324 FontId FontClient::Plugin::GetFontId( const FontPath& path,
325 PointSize26Dot6 pointSize,
327 bool cacheDescription )
331 if( NULL != mFreeTypeLibrary )
334 if( FindFont( path, pointSize, faceIndex, foundId ) )
340 id = CreateFont( path, pointSize, faceIndex, cacheDescription );
347 FontId FontClient::Plugin::GetFontId( const FontFamily& fontFamily,
348 const FontStyle& fontStyle,
349 PointSize26Dot6 pointSize,
350 FaceIndex faceIndex )
352 // This method uses three vectors which caches:
353 // * Pairs of non validated 'fontFamily, fontStyle' and an index to a vector with paths to font file names.
354 // * The path to font file names.
355 // * The font ids of pairs 'font point size, index to the vector with paths to font file names'.
357 // 1) Checks in the cache if the pair 'fontFamily, fontStyle' has been validated before.
358 // If it was it gets an index to the vector with paths to font file names. Otherwise,
359 // retrieves using font config a path to a font file name which matches with the pair
360 // 'fontFamily, fontStyle'. The path is stored in the chache.
362 // 2) Checks in the cache if the pair 'font point size, index to the vector with paths to
363 // fon file names' exists. If exists, it gets the font id. If it doesn't it calls
364 // the GetFontId() method with the path to the font file name and the point size to
367 // The font id to be returned.
370 // Check first if the pair font family and style have been validated before.
371 FontDescriptionId validatedFontId = 0u;
373 if( !FindValidatedFont( fontFamily,
377 // Use font config to validate the font family name and font style.
378 ValidateFont( fontFamily, fontStyle, validatedFontId );
381 // Check if exists a pair 'validatedFontId, pointSize' in the cache.
382 if( !FindFont( validatedFontId, pointSize, fontId ) )
384 // Retrieve the font file name path.
385 const FontDescription& description = *( mFontDescriptionCache.begin() + validatedFontId );
387 // Retrieve the font id. Do not cache the description as it has been already cached.
388 fontId = GetFontId( description.path,
393 // Cache the pair 'validatedFontId, pointSize' to improve the following queries.
394 mFontIdCache.push_back( FontIdCacheItem( validatedFontId,
402 void FontClient::Plugin::ValidateFont( const FontFamily& fontFamily,
403 const FontStyle& fontStyle,
404 FontDescriptionId& validatedFontId )
406 // Create a font pattern.
407 FcPattern* fontFamilyPattern = CreateFontFamilyPattern( fontFamily,
410 FcResult result = FcResultMatch;
413 FcPattern* match = FcFontMatch( NULL /* use default configure */, fontFamilyPattern, &result );
417 // Get the path to the font file name.
418 FontDescription description;
419 GetFcString( match, FC_FILE, description.path );
420 GetFcString( match, FC_FAMILY, description.family );
421 GetFcString( match, FC_STYLE, description.style );
423 // Set the index to the vector of paths to font file names.
424 validatedFontId = mFontDescriptionCache.size();
426 // Add the path to the cache.
427 mFontDescriptionCache.push_back( description );
429 // Cache the index and the pair font family name, font style.
430 FontDescriptionCacheItem item( fontFamily, fontStyle, validatedFontId );
431 mValidatedFontCache.push_back( item );
433 // destroyed the matched pattern
434 FcPatternDestroy( match );
438 DALI_LOG_ERROR( "FontClient::Plugin::ValidateFont failed for font %s %s\n", fontFamily.c_str(), fontStyle.c_str() );
441 // destroy the pattern
442 FcPatternDestroy( fontFamilyPattern );
447 void FontClient::Plugin::GetFontMetrics( FontId fontId,
448 FontMetrics& metrics )
451 fontId-1 < mFontCache.size() )
453 metrics = mFontCache[fontId-1].mMetrics;
457 DALI_LOG_ERROR( "Invalid font ID %d\n", fontId );
461 GlyphIndex FontClient::Plugin::GetGlyphIndex( FontId fontId,
464 GlyphIndex index( 0 );
467 fontId-1 < mFontCache.size() )
469 FT_Face ftFace = mFontCache[fontId-1].mFreeTypeFace;
471 index = FT_Get_Char_Index( ftFace, charcode );
477 bool FontClient::Plugin::GetGlyphMetrics( GlyphInfo* array,
481 bool success( true );
483 for( unsigned int i=0; i<size; ++i )
485 FontId fontId = array[i].fontId;
488 fontId-1 < mFontCache.size() )
490 FT_Face ftFace = mFontCache[fontId-1].mFreeTypeFace;
492 // Check to see if we should be loading a Fixed Size bitmap?
493 if ( mFontCache[fontId-1].mIsFixedSizeBitmap )
495 int error = FT_Load_Glyph( ftFace, array[i].index, FT_LOAD_COLOR );
496 if ( FT_Err_Ok == error )
498 array[i].width = mFontCache[ fontId -1 ].mFixedWidthPixels;
499 array[i].height = mFontCache[ fontId -1 ].mFixedHeightPixels;
500 array[i].advance = mFontCache[ fontId -1 ].mFixedWidthPixels;
501 array[i].xBearing = 0.0f;
502 array[i].yBearing = mFontCache[ fontId -1 ].mFixedHeightPixels;
506 DALI_LOG_ERROR( "FreeType Bitmap Load_Glyph error %d\n", error );
512 int error = FT_Load_Glyph( ftFace, array[i].index, FT_LOAD_DEFAULT );
514 if( FT_Err_Ok == error )
516 array[i].width = static_cast< float >( ftFace->glyph->metrics.width ) * FROM_266;
517 array[i].height = static_cast< float >( ftFace->glyph->metrics.height ) * FROM_266 ;
520 array[i].xBearing = static_cast< float >( ftFace->glyph->metrics.horiBearingX ) * FROM_266;
521 array[i].yBearing = static_cast< float >( ftFace->glyph->metrics.horiBearingY ) * FROM_266;
522 array[i].advance = static_cast< float >( ftFace->glyph->metrics.horiAdvance ) * FROM_266;
526 array[i].xBearing = static_cast< float >( ftFace->glyph->metrics.vertBearingX ) * FROM_266;
527 array[i].yBearing = static_cast< float >( ftFace->glyph->metrics.vertBearingY ) * FROM_266;
528 array[i].advance = static_cast< float >( ftFace->glyph->metrics.vertAdvance ) * FROM_266;
546 BufferImage FontClient::Plugin::CreateBitmap( FontId fontId,
547 GlyphIndex glyphIndex )
552 fontId-1 < mFontCache.size() )
554 FT_Face ftFace = mFontCache[fontId-1].mFreeTypeFace;
558 // Check to see if this is fixed size bitmap
559 if ( mFontCache[fontId-1].mIsFixedSizeBitmap )
561 error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
565 error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_DEFAULT );
567 if( FT_Err_Ok == error )
570 error = FT_Get_Glyph( ftFace->glyph, &glyph );
572 // Convert to bitmap if necessary
573 if ( FT_Err_Ok == error )
575 if( glyph->format != FT_GLYPH_FORMAT_BITMAP )
577 error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, 0, 1 );
578 if ( FT_Err_Ok == error )
580 FT_BitmapGlyph bitmapGlyph = (FT_BitmapGlyph)glyph;
581 ConvertBitmap( bitmap, bitmapGlyph->bitmap );
585 DALI_LOG_ERROR( "FT_Get_Glyph Failed with error: %d\n", error );
590 ConvertBitmap( bitmap, ftFace->glyph->bitmap );
593 // Created FT_Glyph object must be released with FT_Done_Glyph
594 FT_Done_Glyph( glyph );
599 DALI_LOG_ERROR( "FT_Load_Glyph Failed with error: %d\n", error );
606 void FontClient::Plugin::InitSystemFonts()
608 FcFontSet* fontSet = GetFcFontSet();
612 // Reserve some space to avoid reallocations.
613 mSystemFonts.reserve( fontSet->nfont );
615 for( int i = 0u; i < fontSet->nfont; ++i )
617 FcPattern* fontPattern = fontSet->fonts[i];
621 // Skip fonts with no path
622 if( GetFcString( fontPattern, FC_FILE, path ) )
624 mSystemFonts.push_back( FontDescription() );
625 FontDescription& fontDescription = mSystemFonts.back();
627 fontDescription.path = path;
629 GetFcString( fontPattern, FC_FAMILY, fontDescription.family );
630 GetFcString( fontPattern, FC_STYLE, fontDescription.style );
634 FcFontSetDestroy( fontSet );
638 FcPattern* FontClient::Plugin::CreateFontFamilyPattern( const FontFamily& fontFamily,
639 const FontStyle& fontStyle )
641 // create the cached font family lookup pattern
642 // a pattern holds a set of names, each name refers to a property of the font
643 FcPattern* fontFamilyPattern = FcPatternCreate();
645 // add a property to the pattern for the font family
646 FcPatternAddString( fontFamilyPattern, FC_FAMILY, reinterpret_cast<const FcChar8*>( fontFamily.c_str() ) );
648 // add a property to the pattern for the font family
649 FcPatternAddString( fontFamilyPattern, FC_STYLE, reinterpret_cast<const FcChar8*>( fontStyle.c_str() ) );
651 // Add a property of the pattern, to say we want to match TrueType fonts
652 FcPatternAddString( fontFamilyPattern , FC_FONTFORMAT, reinterpret_cast<const FcChar8*>( FONT_FORMAT.c_str() ) );
654 // modify the config, with the mFontFamilyPatterm
655 FcConfigSubstitute( NULL /* use default configure */, fontFamilyPattern, FcMatchPattern );
657 // provide default values for unspecified properties in the font pattern
658 // e.g. patterns without a specified style or weight are set to Medium
659 FcDefaultSubstitute( fontFamilyPattern );
661 return fontFamilyPattern;
664 _FcFontSet* FontClient::Plugin::GetFcFontSet() const
666 // create a new pattern.
667 // a pattern holds a set of names, each name refers to a property of the font
668 FcPattern* pattern = FcPatternCreate();
670 // create an object set used to define which properties are to be returned in the patterns from FcFontList.
671 FcObjectSet* objectSet = FcObjectSetCreate();
673 // build an object set from a list of property names
674 FcObjectSetAdd( objectSet, FC_FILE );
675 FcObjectSetAdd( objectSet, FC_FAMILY );
676 FcObjectSetAdd( objectSet, FC_STYLE );
678 // get a list of fonts
679 // creates patterns from those fonts containing only the objects in objectSet and returns the set of unique such patterns
680 FcFontSet* fontset = FcFontList( NULL /* the default configuration is checked to be up to date, and used */, pattern, objectSet );
682 // clear up the object set
685 FcObjectSetDestroy( objectSet );
687 // clear up the pattern
690 FcPatternDestroy( pattern );
696 bool FontClient::Plugin::GetFcString( const FcPattern* const pattern,
698 std::string& string )
700 FcChar8* file = NULL;
701 const FcResult retVal = FcPatternGetString( pattern, n, 0u, &file );
703 if( FcResultMatch == retVal )
705 // Have to use reinterpret_cast because FcChar8 is unsigned char*, not a const char*.
706 string.assign( reinterpret_cast<const char*>( file ) );
714 FontId FontClient::Plugin::CreateFont( const FontPath& path,
715 PointSize26Dot6 pointSize,
717 bool cacheDescription )
721 // Create & cache new font face
723 int error = FT_New_Face( mFreeTypeLibrary,
728 if( FT_Err_Ok == error )
730 // Check to see if the font contains fixed sizes?
731 if ( ftFace->num_fixed_sizes && ftFace->available_sizes )
733 // Ensure this size is available
734 for ( int i = 0; i < ftFace->num_fixed_sizes; ++i )
736 if ( static_cast<FT_Pos>(pointSize) == ftFace->available_sizes[ i ].size )
738 // Tell Freetype to use this size
739 error = FT_Select_Size( ftFace, i );
740 if ( FT_Err_Ok != error )
742 DALI_LOG_ERROR( "FreeType Select_Size error: %d\n", error );
746 float fixedWidth = static_cast< float >( ftFace->available_sizes[ i ].width );
747 float fixedHeight = static_cast< float >( ftFace->available_sizes[ i ].height );
749 // Indicate that the font is a fixed sized bitmap
750 FontMetrics metrics( fixedHeight,
756 mFontCache.push_back( CacheItem( ftFace, path, pointSize, faceIndex, metrics, fixedWidth, fixedHeight ) );
757 id = mFontCache.size();
759 if( cacheDescription )
761 FontDescription description;
762 description.path = path;
763 description.family = FontFamily( ftFace->family_name );
764 description.style = FontStyle( ftFace->style_name );
766 mFontDescriptionCache.push_back( description );
773 // Can't find this size
774 std::stringstream sizes;
775 for ( int i = 0; i < ftFace->num_fixed_sizes; ++i )
781 sizes << ftFace->available_sizes[ i ].size;
783 DALI_LOG_ERROR( "FreeType Font: %s, does not contain Bitmaps of size: %d. Available sizes are: %s\n",
784 path.c_str(), pointSize, sizes.str().c_str() );
788 error = FT_Set_Char_Size( ftFace,
794 if( FT_Err_Ok == error )
797 FT_Size_Metrics& ftMetrics = ftFace->size->metrics;
799 FontMetrics metrics( static_cast< float >( ftMetrics.ascender ) * FROM_266,
800 static_cast< float >( ftMetrics.descender ) * FROM_266,
801 static_cast< float >( ftMetrics.height ) * FROM_266,
802 static_cast< float >( ftFace->underline_position ) * FROM_266,
803 static_cast< float >( ftFace->underline_thickness ) * FROM_266 );
805 mFontCache.push_back( CacheItem( ftFace, path, pointSize, faceIndex, metrics ) );
806 id = mFontCache.size();
808 if( cacheDescription )
810 FontDescription description;
811 description.path = path;
812 description.family = FontFamily( ftFace->family_name );
813 description.style = FontStyle( ftFace->style_name );
815 mFontDescriptionCache.push_back( description );
820 DALI_LOG_ERROR( "FreeType Set_Char_Size error: %d for pointSize %d\n", error, pointSize );
826 DALI_LOG_ERROR( "FreeType New_Face error: %d for %s\n", error, path.c_str() );
832 void FontClient::Plugin::ConvertBitmap( BufferImage& destBitmap,
833 FT_Bitmap srcBitmap )
835 if( srcBitmap.width*srcBitmap.rows > 0 )
837 switch( srcBitmap.pixel_mode )
839 case FT_PIXEL_MODE_GRAY:
841 if( srcBitmap.pitch == static_cast< int >( srcBitmap.width ) )
843 destBitmap = BufferImage::New( srcBitmap.width, srcBitmap.rows, Pixel::L8 );
845 PixelBuffer* destBuffer = destBitmap.GetBuffer();
846 memcpy( destBuffer, srcBitmap.buffer, srcBitmap.width*srcBitmap.rows );
851 case FT_PIXEL_MODE_BGRA:
853 if ( srcBitmap.pitch == static_cast< int >( srcBitmap.width << 2 ) )
855 destBitmap = BufferImage::New( srcBitmap.width, srcBitmap.rows, Pixel::BGRA8888 );
857 PixelBuffer* destBuffer = destBitmap.GetBuffer();
858 memcpy( destBuffer, srcBitmap.buffer, srcBitmap.width*srcBitmap.rows*4 );
864 DALI_LOG_ERROR( "FontClient Unable to create Bitmap of this PixelType\n" );
871 bool FontClient::Plugin::FindFont( const FontPath& path,
872 PointSize26Dot6 pointSize,
874 FontId& fontId ) const
877 for( std::vector<CacheItem>::const_iterator it = mFontCache.begin(),
878 endIt = mFontCache.end();
882 const CacheItem& cacheItem = *it;
884 if( cacheItem.mPointSize == pointSize &&
885 cacheItem.mFaceIndex == faceIndex &&
886 cacheItem.mPath == path )
896 bool FontClient::Plugin::FindValidatedFont( const FontFamily& fontFamily,
897 const FontStyle& fontStyle,
898 FontDescriptionId& validatedFontId )
900 validatedFontId = 0u;
902 for( std::vector<FontDescriptionCacheItem>::const_iterator it = mValidatedFontCache.begin(),
903 endIt = mValidatedFontCache.end();
907 const FontDescriptionCacheItem& item = *it;
909 if( ( fontFamily == item.fontFamily ) &&
910 ( fontStyle == item.fontStyle ) )
912 validatedFontId = item.index;
921 bool FontClient::Plugin::FindFont( FontDescriptionId validatedFontId,
922 PointSize26Dot6 pointSize,
927 for( std::vector<FontIdCacheItem>::const_iterator it = mFontIdCache.begin(),
928 endIt = mFontIdCache.end();
932 const FontIdCacheItem& item = *it;
934 if( ( validatedFontId == item.validatedFontId ) &&
935 ( pointSize == item.pointSize ) )
937 fontId = item.fontId;
945 bool FontClient::Plugin::IsScalable( const FontPath& path )
948 int error = FT_New_Face( mFreeTypeLibrary,
952 if( FT_Err_Ok != error )
954 DALI_LOG_ERROR( "FreeType Cannot check font: %s\n", path.c_str() );
956 return ( ftFace->num_fixed_sizes == 0 );
959 bool FontClient::Plugin::IsScalable( const FontFamily& fontFamily, const FontStyle& fontStyle )
961 // Create a font pattern.
962 FcPattern* fontFamilyPattern = CreateFontFamilyPattern( fontFamily,
965 FcResult result = FcResultMatch;
968 FcPattern* match = FcFontMatch( NULL /* use default configure */, fontFamilyPattern, &result );
972 // Get the path to the font file name.
974 GetFcString( match, FC_FILE, path );
975 return IsScalable( path );
977 DALI_LOG_ERROR( "FreeType Cannot check font: %s %s\n", fontFamily.c_str(), fontStyle.c_str() );
981 void FontClient::Plugin::GetFixedSizes( const FontPath& path, Vector< PointSize26Dot6 >& sizes )
983 // Empty the caller container
987 int error = FT_New_Face( mFreeTypeLibrary,
991 if( FT_Err_Ok != error )
993 DALI_LOG_ERROR( "FreeType Cannot check font: %s\n", path.c_str() );
996 // Fetch the number of fixed sizes available
997 if ( ftFace->num_fixed_sizes && ftFace->available_sizes )
999 for ( int i = 0; i < ftFace->num_fixed_sizes; ++i )
1001 sizes.PushBack( ftFace->available_sizes[ i ].size );
1006 void FontClient::Plugin::GetFixedSizes( const FontFamily& fontFamily,
1007 const FontStyle& fontStyle,
1008 Vector< PointSize26Dot6 >& sizes )
1010 // Create a font pattern.
1011 FcPattern* fontFamilyPattern = CreateFontFamilyPattern( fontFamily,
1014 FcResult result = FcResultMatch;
1016 // match the pattern
1017 FcPattern* match = FcFontMatch( NULL /* use default configure */, fontFamilyPattern, &result );
1021 // Get the path to the font file name.
1023 GetFcString( match, FC_FILE, path );
1024 return GetFixedSizes( path, sizes );
1026 DALI_LOG_ERROR( "FreeType Cannot check font: %s %s\n", fontFamily.c_str(), fontStyle.c_str() );
1029 } // namespace Internal
1031 } // namespace TextAbstraction