[3.0] New methods added to the font-client.
[platform/core/uifw/dali-adaptor.git] / text / dali / internal / text-abstraction / font-client-plugin-impl.cpp
index feaec05..1ba5361 100644 (file)
@@ -55,6 +55,7 @@ const bool FONT_FIXED_SIZE_BITMAP( true );
 
 // http://www.freedesktop.org/software/fontconfig/fontconfig-user.html
 
+// NONE            -1  --> DEFAULT_FONT_WIDTH (NORMAL) will be used.
 // ULTRA_CONDENSED 50
 // EXTRA_CONDENSED 63
 // CONDENSED       75
@@ -64,9 +65,10 @@ const bool FONT_FIXED_SIZE_BITMAP( true );
 // EXPANDED       125
 // EXTRA_EXPANDED 150
 // ULTRA_EXPANDED 200
-const int FONT_WIDTH_TYPE_TO_INT[] = { 50, 63, 75, 87, 100, 113, 125, 150, 200 };
+const int FONT_WIDTH_TYPE_TO_INT[] = { -1, 50, 63, 75, 87, 100, 113, 125, 150, 200 };
 const unsigned int NUM_FONT_WIDTH_TYPE = sizeof( FONT_WIDTH_TYPE_TO_INT ) / sizeof( int );
 
+// NONE                       -1  --> DEFAULT_FONT_WEIGHT (NORMAL) will be used.
 // THIN                        0
 // ULTRA_LIGHT, EXTRA_LIGHT   40
 // LIGHT                      50
@@ -78,13 +80,14 @@ const unsigned int NUM_FONT_WIDTH_TYPE = sizeof( FONT_WIDTH_TYPE_TO_INT ) / size
 // BOLD                      200
 // ULTRA_BOLD, EXTRA_BOLD    205
 // BLACK, HEAVY, EXTRA_BLACK 210
-const int FONT_WEIGHT_TYPE_TO_INT[] = { 0, 40, 50, 55, 75, 80, 100, 180, 200, 205, 210 };
+const int FONT_WEIGHT_TYPE_TO_INT[] = { -1, 0, 40, 50, 55, 75, 80, 100, 180, 200, 205, 210 };
 const unsigned int NUM_FONT_WEIGHT_TYPE = sizeof( FONT_WEIGHT_TYPE_TO_INT ) / sizeof( int );
 
-// NORMAL, ROMAN   0
-// ITALIC        100
-// OBLIQUE       110
-const int FONT_SLANT_TYPE_TO_INT[] = { 0, 100, 110 };
+// NONE             -1 --> DEFAULT_FONT_SLANT (NORMAL) will be used.
+// NORMAL, ROMAN     0
+// ITALIC          100
+// OBLIQUE         110
+const int FONT_SLANT_TYPE_TO_INT[] = { -1, 0, 100, 110 };
 const unsigned int NUM_FONT_SLANT_TYPE = sizeof( FONT_SLANT_TYPE_TO_INT ) / sizeof( int );
 
 } // namespace
@@ -158,11 +161,11 @@ FontClient::Plugin::FontIdCacheItem::FontIdCacheItem( FontDescriptionId validate
 {
 }
 
-FontClient::Plugin::CacheItem::CacheItem( FT_Face ftFace,
-                                          const FontPath& path,
-                                          PointSize26Dot6 requestedPointSize,
-                                          FaceIndex face,
-                                          const FontMetrics& metrics )
+FontClient::Plugin::FontFaceCacheItem::FontFaceCacheItem( FT_Face ftFace,
+                                                          const FontPath& path,
+                                                          PointSize26Dot6 requestedPointSize,
+                                                          FaceIndex face,
+                                                          const FontMetrics& metrics )
 : mFreeTypeFace( ftFace ),
   mPath( path ),
   mRequestedPointSize( requestedPointSize ),
@@ -175,13 +178,13 @@ FontClient::Plugin::CacheItem::CacheItem( FT_Face ftFace,
 {
 }
 
-FontClient::Plugin::CacheItem::CacheItem( FT_Face ftFace,
-                                          const FontPath& path,
-                                          PointSize26Dot6 requestedPointSize,
-                                          FaceIndex face,
-                                          const FontMetrics& metrics,
-                                          float fixedWidth,
-                                          float fixedHeight )
+FontClient::Plugin::FontFaceCacheItem::FontFaceCacheItem( FT_Face ftFace,
+                                                          const FontPath& path,
+                                                          PointSize26Dot6 requestedPointSize,
+                                                          FaceIndex face,
+                                                          const FontMetrics& metrics,
+                                                          float fixedWidth,
+                                                          float fixedHeight )
 : mFreeTypeFace( ftFace ),
   mPath( path ),
   mRequestedPointSize( requestedPointSize ),
@@ -408,12 +411,11 @@ FontId FontClient::Plugin::FindFontForCharacter( const FontList& fontList,
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::FindFontForCharacter\n");
 
-  FontId fontId(0);
-  bool foundColor(false);
+  FontId fontId = 0u;
+  bool foundColor = false;
 
   // Traverse the list of fonts.
-  // Check for each default font if supports the character.
-
+  // Check for each font if supports the character.
   for( FontList::const_iterator it = fontList.begin(), endIt = fontList.end();
        it != endIt;
        ++it )
@@ -459,15 +461,10 @@ FontId FontClient::Plugin::FindFontForCharacter( const FontList& fontList,
 
       if( preferColor )
       {
-        PixelData bitmap = CreateBitmap( fontId, GetGlyphIndex(fontId,charcode) );
-        if( bitmap &&
-            Pixel::BGRA8888 == bitmap.GetPixelFormat() )
-        {
-          foundColor = true;
-        }
+        foundColor = IsColorGlyph( fontId, GetGlyphIndex( fontId, charcode ) );
       }
 
-      // Keep going unless we prefer a different (color) font
+      // Keep going unless we prefer a different (color) font.
       if( !preferColor || foundColor )
       {
         FcPatternDestroy( match );
@@ -499,6 +496,7 @@ FontId FontClient::Plugin::FindDefaultFont( Character charcode,
     fontDescription.width = IntToWidthType( DEFAULT_FONT_WIDTH );
     fontDescription.weight = IntToWeightType( DEFAULT_FONT_WEIGHT );
     fontDescription.slant = IntToSlantType( DEFAULT_FONT_SLANT );
+
     SetFontList( fontDescription, mDefaultFonts );
   }
 
@@ -509,8 +507,8 @@ FontId FontClient::Plugin::FindDefaultFont( Character charcode,
   return fontId;
 }
 
-FontId FontClient::Plugin::FindFallbackFont( FontId preferredFont,
-                                             Character charcode,
+FontId FontClient::Plugin::FindFallbackFont( Character charcode,
+                                             const FontDescription& preferredFontDescription,
                                              PointSize26Dot6 requestedPointSize,
                                              bool preferColor )
 {
@@ -518,7 +516,12 @@ FontId FontClient::Plugin::FindFallbackFont( FontId preferredFont,
   FontId fontId = 0u;
 
   FontDescription fontDescription;
-  GetDescription( preferredFont, fontDescription );
+
+  // Fill the font description with the preferred font description and complete with the defaults.
+  fontDescription.family = preferredFontDescription.family.empty() ? DEFAULT_FONT_FAMILY_NAME : preferredFontDescription.family;
+  fontDescription.weight = ( ( FontWeight::NONE == preferredFontDescription.weight ) ? IntToWeightType( DEFAULT_FONT_WEIGHT ) : preferredFontDescription.weight );
+  fontDescription.width = ( ( FontWidth::NONE == preferredFontDescription.width ) ? IntToWidthType( DEFAULT_FONT_WIDTH ) : preferredFontDescription.width );
+  fontDescription.slant = ( ( FontSlant::NONE == preferredFontDescription.slant ) ? IntToSlantType( DEFAULT_FONT_SLANT ) : preferredFontDescription.slant );
 
   // Check first if the font's description has been queried before.
   FontList* fontList( NULL );
@@ -529,7 +532,7 @@ FontId FontClient::Plugin::FindFallbackFont( FontId preferredFont,
     SetFontList( fontDescription, *fontList );
 
     // Add the font-list to the cache.
-    mFallbackCache.push_back( FallbackCacheItem(fontDescription, fontList) );
+    mFallbackCache.push_back( FallbackCacheItem( fontDescription, fontList ) );
   }
 
   if( fontList )
@@ -683,7 +686,7 @@ void FontClient::Plugin::GetFontMetrics( FontId fontId,
   if( ( fontId > 0 ) &&
       ( fontId - 1u < mFontCache.size() ) )
   {
-    const CacheItem& font = mFontCache[fontId-1];
+    const FontFaceCacheItem& font = mFontCache[fontId-1];
 
     metrics = font.mMetrics;
 
@@ -754,7 +757,7 @@ bool FontClient::Plugin::GetBitmapMetrics( GlyphInfo* array,
     if( fontId > 0 &&
         fontId-1 < mFontCache.size() )
     {
-      const CacheItem& font = mFontCache[fontId-1];
+      const FontFaceCacheItem& font = mFontCache[fontId-1];
 
       FT_Face ftFace = font.mFreeTypeFace;
 
@@ -842,7 +845,7 @@ bool FontClient::Plugin::GetVectorMetrics( GlyphInfo* array,
     if( fontId > 0 &&
         fontId-1 < mFontCache.size() )
     {
-      CacheItem& font = mFontCache[fontId-1];
+      FontFaceCacheItem& font = mFontCache[fontId-1];
 
       if( ! font.mVectorFontId )
       {
@@ -871,21 +874,18 @@ bool FontClient::Plugin::GetVectorMetrics( GlyphInfo* array,
 #endif
 }
 
-PixelData FontClient::Plugin::CreateBitmap( FontId fontId,
-                                              GlyphIndex glyphIndex )
+void FontClient::Plugin::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, Dali::TextAbstraction::FontClient::GlyphBufferData& data )
 {
-  PixelData bitmap;
-
-  if( fontId > 0 &&
-      fontId-1 < mFontCache.size() )
+  if( ( fontId > 0 ) &&
+      ( fontId - 1u < mFontCache.size() ) )
   {
-    FT_Face ftFace = mFontCache[fontId-1].mFreeTypeFace;
+    FT_Face ftFace = mFontCache[fontId - 1u].mFreeTypeFace;
 
     FT_Error error;
 
 #ifdef FREETYPE_BITMAP_SUPPORT
     // Check to see if this is fixed size bitmap
-    if ( mFontCache[fontId-1].mIsFixedSizeBitmap )
+    if ( mFontCache[fontId - 1u].mIsFixedSizeBitmap )
     {
       error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
     }
@@ -908,7 +908,7 @@ PixelData FontClient::Plugin::CreateBitmap( FontId fontId,
           if ( FT_Err_Ok == error )
           {
             FT_BitmapGlyph bitmapGlyph = (FT_BitmapGlyph)glyph;
-            ConvertBitmap( bitmap, bitmapGlyph->bitmap );
+            ConvertBitmap( data, bitmapGlyph->bitmap );
           }
           else
           {
@@ -917,7 +917,7 @@ PixelData FontClient::Plugin::CreateBitmap( FontId fontId,
         }
         else
         {
-          ConvertBitmap( bitmap, ftFace->glyph->bitmap );
+          ConvertBitmap( data, ftFace->glyph->bitmap );
         }
 
         // Created FT_Glyph object must be released with FT_Done_Glyph
@@ -929,8 +929,21 @@ PixelData FontClient::Plugin::CreateBitmap( FontId fontId,
       DALI_LOG_ERROR( "FT_Load_Glyph Failed with error: %d\n", error );
     }
   }
+}
 
-  return bitmap;
+PixelData FontClient::Plugin::CreateBitmap( FontId fontId,
+                                            GlyphIndex glyphIndex )
+{
+  TextAbstraction::FontClient::GlyphBufferData data;
+
+  CreateBitmap( fontId, glyphIndex, data );
+
+  return PixelData::New( data.buffer,
+                         data.width * data.height * Pixel::GetBytesPerPixel( data.format ),
+                         data.width,
+                         data.height,
+                         data.format,
+                         PixelData::DELETE_ARRAY );
 }
 
 void FontClient::Plugin::CreateVectorBlob( FontId fontId, GlyphIndex glyphIndex, VectorBlob*& blob, unsigned int& blobLength, unsigned int& nominalWidth, unsigned int& nominalHeight )
@@ -942,7 +955,7 @@ void FontClient::Plugin::CreateVectorBlob( FontId fontId, GlyphIndex glyphIndex,
   if( fontId > 0 &&
       fontId-1 < mFontCache.size() )
   {
-    CacheItem& font = mFontCache[fontId-1];
+    FontFaceCacheItem& font = mFontCache[fontId-1];
 
     if( ! font.mVectorFontId )
     {
@@ -991,6 +1004,28 @@ const GlyphInfo& FontClient::Plugin::GetEllipsisGlyph( PointSize26Dot6 requested
   return item.glyph;
 }
 
+bool FontClient::Plugin::IsColorGlyph( FontId fontId, GlyphIndex glyphIndex )
+{
+  FT_Error error = -1;
+
+#ifdef FREETYPE_BITMAP_SUPPORT
+  if( ( fontId > 0 ) &&
+      ( fontId - 1u < mFontCache.size() ) )
+  {
+    const FontFaceCacheItem& item = mFontCache[fontId - 1u];
+    FT_Face ftFace = item.mFreeTypeFace;
+
+    // Check to see if this is fixed size bitmap
+    if( item.mIsFixedSizeBitmap )
+    {
+      error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
+    }
+  }
+#endif
+
+  return FT_Err_Ok == error;
+}
+
 void FontClient::Plugin::InitSystemFonts()
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::InitSystemFonts \n");
@@ -1056,6 +1091,7 @@ bool FontClient::Plugin::MatchFontDescriptionToPattern( FcPattern* pattern, Dali
     fontDescription.width = IntToWidthType( width );
     fontDescription.weight = IntToWeightType( weight );
     fontDescription.slant = IntToSlantType( slant );
+
     // destroyed the matched pattern
     FcPatternDestroy( match );
     ret = true;
@@ -1073,9 +1109,30 @@ FcPattern* FontClient::Plugin::CreateFontFamilyPattern( const FontDescription& f
   // add a property to the pattern for the font family
   FcPatternAddString( fontFamilyPattern, FC_FAMILY, reinterpret_cast<const FcChar8*>( fontDescription.family.c_str() ) );
 
-  FcPatternAddInteger( fontFamilyPattern, FC_WIDTH, FONT_WIDTH_TYPE_TO_INT[fontDescription.width] );
-  FcPatternAddInteger( fontFamilyPattern, FC_WEIGHT, FONT_WEIGHT_TYPE_TO_INT[fontDescription.weight] );
-  FcPatternAddInteger( fontFamilyPattern, FC_SLANT, FONT_SLANT_TYPE_TO_INT[fontDescription.slant] );
+  int width = FONT_WIDTH_TYPE_TO_INT[fontDescription.width];
+  if( width < 0 )
+  {
+    // Use default.
+    width = DEFAULT_FONT_WIDTH;
+  }
+
+  int weight = FONT_WEIGHT_TYPE_TO_INT[fontDescription.weight];
+  if( weight < 0 )
+  {
+    // Use default.
+    weight = DEFAULT_FONT_WEIGHT;
+  }
+
+  int slant = FONT_SLANT_TYPE_TO_INT[fontDescription.slant];
+  if( slant < 0 )
+  {
+    // Use default.
+    slant = DEFAULT_FONT_SLANT;
+  }
+
+  FcPatternAddInteger( fontFamilyPattern, FC_WIDTH, width );
+  FcPatternAddInteger( fontFamilyPattern, FC_WEIGHT, weight );
+  FcPatternAddInteger( fontFamilyPattern, FC_SLANT, slant );
 
   // Add a property of the pattern, to say we want to match TrueType fonts
   FcPatternAddString( fontFamilyPattern , FC_FONTFORMAT, reinterpret_cast<const FcChar8*>( FONT_FORMAT.c_str() ) );
@@ -1197,7 +1254,7 @@ FontId FontClient::Plugin::CreateFont( const FontPath& path,
                                  0.0f,
                                  0.0f );
 
-            mFontCache.push_back( CacheItem( ftFace, path, requestedPointSize, faceIndex, metrics, fixedWidth, fixedHeight ) );
+            mFontCache.push_back( FontFaceCacheItem( ftFace, path, requestedPointSize, faceIndex, metrics, fixedWidth, fixedHeight ) );
             id = mFontCache.size();
 
             if( cacheDescription )
@@ -1242,7 +1299,7 @@ FontId FontClient::Plugin::CreateFont( const FontPath& path,
                              static_cast< float >( ftFace->underline_position ) * FROM_266,
                              static_cast< float >( ftFace->underline_thickness ) * FROM_266 );
 
-        mFontCache.push_back( CacheItem( ftFace, path, requestedPointSize, faceIndex, metrics ) );
+        mFontCache.push_back( FontFaceCacheItem( ftFace, path, requestedPointSize, faceIndex, metrics ) );
         id = mFontCache.size();
 
         if( cacheDescription )
@@ -1264,8 +1321,7 @@ FontId FontClient::Plugin::CreateFont( const FontPath& path,
   return id;
 }
 
-void FontClient::Plugin::ConvertBitmap( PixelData& destBitmap,
-                                        FT_Bitmap srcBitmap )
+void FontClient::Plugin::ConvertBitmap( TextAbstraction::FontClient::GlyphBufferData& data, FT_Bitmap srcBitmap )
 {
   if( srcBitmap.width*srcBitmap.rows > 0 )
   {
@@ -1273,12 +1329,14 @@ void FontClient::Plugin::ConvertBitmap( PixelData& destBitmap,
     {
       case FT_PIXEL_MODE_GRAY:
       {
-        if( srcBitmap.pitch == static_cast< int >( srcBitmap.width ) )
+        if( srcBitmap.pitch == static_cast<int>( srcBitmap.width ) )
         {
-          unsigned int bufferSize( srcBitmap.width * srcBitmap.rows );
-          unsigned char* buffer = new unsigned char[bufferSize];
-          memcpy( buffer, srcBitmap.buffer,bufferSize );
-          destBitmap = PixelData::New( buffer, bufferSize, srcBitmap.width, srcBitmap.rows, Pixel::L8, PixelData::DELETE_ARRAY );
+          const unsigned int bufferSize = srcBitmap.width * srcBitmap.rows;
+          data.buffer = new unsigned char[bufferSize];
+          data.width = srcBitmap.width;
+          data.height = srcBitmap.rows;
+          data.format = Pixel::L8;
+          memcpy( data.buffer, srcBitmap.buffer, bufferSize );
         }
         break;
       }
@@ -1286,12 +1344,14 @@ void FontClient::Plugin::ConvertBitmap( PixelData& destBitmap,
 #ifdef FREETYPE_BITMAP_SUPPORT
       case FT_PIXEL_MODE_BGRA:
       {
-        if ( srcBitmap.pitch == static_cast< int >( srcBitmap.width << 2 ) )
+        if( srcBitmap.pitch == static_cast<int>( srcBitmap.width << 2u ) )
         {
-          unsigned int bufferSize( srcBitmap.width * srcBitmap.rows * 4 );
-          unsigned char* buffer = new unsigned char[bufferSize];
-          memcpy( buffer, srcBitmap.buffer,bufferSize );
-          destBitmap = PixelData::New( buffer, bufferSize, srcBitmap.width, srcBitmap.rows, Pixel::BGRA8888, PixelData::DELETE_ARRAY );
+          const unsigned int bufferSize = srcBitmap.width * srcBitmap.rows * 4u;
+          data.buffer = new unsigned char[bufferSize];
+          data.width = srcBitmap.width;
+          data.height = srcBitmap.rows;
+          data.format = Pixel::BGRA8888;
+          memcpy( data.buffer, srcBitmap.buffer, bufferSize );
         }
         break;
       }
@@ -1311,12 +1371,12 @@ bool FontClient::Plugin::FindFont( const FontPath& path,
                                    FontId& fontId ) const
 {
   fontId = 0u;
-  for( std::vector<CacheItem>::const_iterator it = mFontCache.begin(),
+  for( std::vector<FontFaceCacheItem>::const_iterator it = mFontCache.begin(),
          endIt = mFontCache.end();
        it != endIt;
        ++it, ++fontId )
   {
-    const CacheItem& cacheItem = *it;
+    const FontFaceCacheItem& cacheItem = *it;
 
     if( cacheItem.mRequestedPointSize == requestedPointSize &&
         cacheItem.mFaceIndex == faceIndex &&
@@ -1524,9 +1584,9 @@ void FontClient::Plugin::CacheFontPath( FT_Face ftFace, FontId id, PointSize26Do
   FontDescription description;
   description.path = path;
   description.family = FontFamily( ftFace->family_name );
-  description.weight = FontWeight::NORMAL;
-  description.width = FontWidth::NORMAL;
-  description.slant = FontSlant::NORMAL;
+  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 )