Merge "Fixed indentation." into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / text / text-abstraction / font-client-plugin-impl.cpp
index 0bccb96..1fb9c67 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/devel-api/text-abstraction/font-list.h>
+
 #include <dali/public-api/common/dali-vector.h>
 #include <dali/public-api/common/vector-wrapper.h>
 #include <dali/integration-api/debug.h>
@@ -274,6 +275,42 @@ FontClient::Plugin::~Plugin()
   FT_Done_FreeType( mFreeTypeLibrary );
 }
 
+void FontClient::Plugin::ClearCache()
+{
+  mDefaultFontDescription = FontDescription();
+
+  mSystemFonts.clear();
+  mDefaultFonts.clear();
+
+  DestroyCharacterSets( mDefaultFontCharacterSets );
+  mDefaultFontCharacterSets.Clear();
+
+  ClearFallbackCache( mFallbackCache );
+  mFallbackCache.clear();
+
+  mFontIdCache.Clear();
+
+  ClearCharacterSetFromFontFaceCache();
+  mFontFaceCache.clear();
+
+  mValidatedFontCache.clear();
+  mFontDescriptionCache.clear();
+  mFontDescriptionCache.resize( 1u );
+
+  DestroyCharacterSets( mCharacterSetCache );
+  mCharacterSetCache.Clear();
+  mCharacterSetCache.Resize( 1u );
+
+  mFontDescriptionSizeCache.clear();
+
+  mEllipsisCache.Clear();
+  mPixelBufferCache.clear();
+  mEmbeddedItemCache.Clear();
+  mBitmapFontCache.clear();
+
+  mDefaultFontDescriptionCached = false;
+}
+
 void FontClient::Plugin::SetDpi( unsigned int horizontalDpi,
                                  unsigned int verticalDpi )
 {
@@ -913,7 +950,7 @@ FontId FontClient::Plugin::GetFontId( const FontDescription& fontDescription,
                         false );
 
     fontFaceId = mFontIdCache[fontId-1u].id;
-    mFontFaceCache[fontFaceId].mCharacterSet = mCharacterSetCache[validatedFontId];
+    mFontFaceCache[fontFaceId].mCharacterSet = FcCharSetCopy( mCharacterSetCache[validatedFontId] );
 
     // Cache the pair 'validatedFontId, requestedPointSize' to improve the following queries.
     mFontDescriptionSizeCache.push_back( FontDescriptionSizeCacheItem( validatedFontId,
@@ -1158,108 +1195,108 @@ bool FontClient::Plugin::GetBitmapMetrics( GlyphInfo* array,
 
       switch( fontIdCacheItem.type )
       {
-      case FontDescription::FACE_FONT:
-      {
-        const FontFaceCacheItem& font = mFontFaceCache[fontIdCacheItem.id];
+        case FontDescription::FACE_FONT:
+        {
+          const FontFaceCacheItem& font = mFontFaceCache[fontIdCacheItem.id];
 
-        FT_Face ftFace = font.mFreeTypeFace;
+          FT_Face ftFace = font.mFreeTypeFace;
 
 #ifdef FREETYPE_BITMAP_SUPPORT
-        // Check to see if we should be loading a Fixed Size bitmap?
-        if( font.mIsFixedSizeBitmap )
-        {
-          FT_Select_Size( ftFace, font.mFixedSizeIndex ); ///< @todo: needs to be investigated why it's needed to select the size again.
-          int error = FT_Load_Glyph( ftFace, glyph.index, FT_LOAD_COLOR );
-          if ( FT_Err_Ok == error )
+          // Check to see if we should be loading a Fixed Size bitmap?
+          if( font.mIsFixedSizeBitmap )
           {
-            glyph.width = font.mFixedWidthPixels;
-            glyph.height = font.mFixedHeightPixels;
-            glyph.advance = font.mFixedWidthPixels;
-            glyph.xBearing = 0.0f;
-            glyph.yBearing = font.mFixedHeightPixels;
+            FT_Select_Size( ftFace, font.mFixedSizeIndex ); ///< @todo: needs to be investigated why it's needed to select the size again.
+            int error = FT_Load_Glyph( ftFace, glyph.index, FT_LOAD_COLOR );
+            if ( FT_Err_Ok == error )
+            {
+              glyph.width = font.mFixedWidthPixels;
+              glyph.height = font.mFixedHeightPixels;
+              glyph.advance = font.mFixedWidthPixels;
+              glyph.xBearing = 0.0f;
+              glyph.yBearing = font.mFixedHeightPixels;
 
-            // Adjust the metrics if the fixed-size font should be down-scaled
-            const float desiredFixedSize =  static_cast<float>( font.mRequestedPointSize ) * FROM_266 / POINTS_PER_INCH * mDpiVertical;
+              // Adjust the metrics if the fixed-size font should be down-scaled
+              const float desiredFixedSize =  static_cast<float>( font.mRequestedPointSize ) * FROM_266 / POINTS_PER_INCH * mDpiVertical;
 
-            if( desiredFixedSize > 0.f )
-            {
-              const float scaleFactor = desiredFixedSize / font.mFixedHeightPixels;
+              if( desiredFixedSize > 0.f )
+              {
+                const float scaleFactor = desiredFixedSize / font.mFixedHeightPixels;
 
-              glyph.width = glyph.width * scaleFactor ;
-              glyph.height = glyph.height * scaleFactor;
-              glyph.advance = glyph.advance * scaleFactor;
-              glyph.xBearing = glyph.xBearing * scaleFactor;
-              glyph.yBearing = glyph.yBearing * scaleFactor;
+                glyph.width = glyph.width * scaleFactor ;
+                glyph.height = glyph.height * scaleFactor;
+                glyph.advance = glyph.advance * scaleFactor;
+                glyph.xBearing = glyph.xBearing * scaleFactor;
+                glyph.yBearing = glyph.yBearing * scaleFactor;
 
-              glyph.scaleFactor = scaleFactor;
+                glyph.scaleFactor = scaleFactor;
+              }
+            }
+            else
+            {
+              DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::GetBitmapMetrics. FreeType Bitmap Load_Glyph error %d\n", error );
+              success = false;
             }
           }
           else
-          {
-            DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::GetBitmapMetrics. FreeType Bitmap Load_Glyph error %d\n", error );
-            success = false;
-          }
-        }
-        else
 #endif
-        {
-          int error = FT_Load_Glyph( ftFace, glyph.index, FT_LOAD_NO_AUTOHINT );
-
-          if( FT_Err_Ok == error )
           {
-            glyph.width  = static_cast< float >( ftFace->glyph->metrics.width ) * FROM_266;
-            glyph.height = static_cast< float >( ftFace->glyph->metrics.height ) * FROM_266 ;
-            if( horizontal )
+            int error = FT_Load_Glyph( ftFace, glyph.index, FT_LOAD_NO_AUTOHINT );
+
+            if( FT_Err_Ok == error )
             {
-              glyph.xBearing += static_cast< float >( ftFace->glyph->metrics.horiBearingX ) * FROM_266;
-              glyph.yBearing += static_cast< float >( ftFace->glyph->metrics.horiBearingY ) * FROM_266;
+              glyph.width  = static_cast< float >( ftFace->glyph->metrics.width ) * FROM_266;
+              glyph.height = static_cast< float >( ftFace->glyph->metrics.height ) * FROM_266 ;
+              if( horizontal )
+              {
+                glyph.xBearing += static_cast< float >( ftFace->glyph->metrics.horiBearingX ) * FROM_266;
+                glyph.yBearing += static_cast< float >( ftFace->glyph->metrics.horiBearingY ) * FROM_266;
+              }
+              else
+              {
+                glyph.xBearing += static_cast< float >( ftFace->glyph->metrics.vertBearingX ) * FROM_266;
+                glyph.yBearing += static_cast< float >( ftFace->glyph->metrics.vertBearingY ) * FROM_266;
+              }
             }
             else
             {
-              glyph.xBearing += static_cast< float >( ftFace->glyph->metrics.vertBearingX ) * FROM_266;
-              glyph.yBearing += static_cast< float >( ftFace->glyph->metrics.vertBearingY ) * FROM_266;
+              success = false;
             }
           }
-          else
-          {
-            success = false;
-          }
+          break;
         }
-        break;
-      }
-      case FontDescription::BITMAP_FONT:
-      {
-        BitmapFontCacheItem& bitmapFontCacheItem = mBitmapFontCache[fontIdCacheItem.id];
-
-        unsigned int index = 0u;
-        for( auto& item : bitmapFontCacheItem.font.glyphs )
+        case FontDescription::BITMAP_FONT:
         {
-          if( item.utf32 == glyph.index )
+          BitmapFontCacheItem& bitmapFontCacheItem = mBitmapFontCache[fontIdCacheItem.id];
+
+          unsigned int index = 0u;
+          for( auto& item : bitmapFontCacheItem.font.glyphs )
           {
-            Devel::PixelBuffer& pixelBuffer = bitmapFontCacheItem.pixelBuffers[index];
-            if( !pixelBuffer )
+            if( item.utf32 == glyph.index )
             {
-              pixelBuffer = LoadImageFromFile( item.url );
-            }
+              Devel::PixelBuffer& pixelBuffer = bitmapFontCacheItem.pixelBuffers[index];
+              if( !pixelBuffer )
+              {
+                pixelBuffer = LoadImageFromFile( item.url );
+              }
 
-            glyph.width  = static_cast< float >( pixelBuffer.GetWidth() );
-            glyph.height = static_cast< float >( pixelBuffer.GetHeight() );
-            glyph.xBearing = 0.f;
-            glyph.yBearing = glyph.height + item.descender;
-            glyph.advance = glyph.width;
-            glyph.scaleFactor = 1.f;
-            break;
+              glyph.width  = static_cast< float >( pixelBuffer.GetWidth() );
+              glyph.height = static_cast< float >( pixelBuffer.GetHeight() );
+              glyph.xBearing = 0.f;
+              glyph.yBearing = glyph.height + item.descender;
+              glyph.advance = glyph.width;
+              glyph.scaleFactor = 1.f;
+              break;
+            }
+            ++index;
           }
-          ++index;
-        }
 
-        success = true;
-        break;
-      }
-      default:
-      {
-        DALI_LOG_INFO(gLogFilter, Debug::General, "  Invalid type of font\n");
-      }
+          success = true;
+          break;
+        }
+        default:
+        {
+          DALI_LOG_INFO(gLogFilter, Debug::General, "  Invalid type of font\n");
+        }
       }
     }
     else
@@ -1336,138 +1373,145 @@ void FontClient::Plugin::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, boo
   if( ( fontId > 0u ) &&
       ( index < mFontIdCache.Count() ) )
   {
+    data.isColorBitmap = false;
+    data.isColorEmoji = false;
+
     const FontIdCacheItem& fontIdCacheItem = mFontIdCache[index];
 
     switch( fontIdCacheItem.type )
     {
-    case FontDescription::FACE_FONT:
-    {
-      // For the software italics.
-      bool isShearRequired = false;
+      case FontDescription::FACE_FONT:
+      {
+        // For the software italics.
+        bool isShearRequired = false;
 
-      const FontFaceCacheItem& fontFaceCacheItem = mFontFaceCache[fontIdCacheItem.id];
-      FT_Face ftFace = fontFaceCacheItem.mFreeTypeFace;
+        const FontFaceCacheItem& fontFaceCacheItem = mFontFaceCache[fontIdCacheItem.id];
+        FT_Face ftFace = fontFaceCacheItem.mFreeTypeFace;
 
-      FT_Error error;
+        FT_Error error;
 
 #ifdef FREETYPE_BITMAP_SUPPORT
-      // Check to see if this is fixed size bitmap
-      if( fontFaceCacheItem.mIsFixedSizeBitmap )
-      {
-        error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
-      }
-      else
-#endif
-      {
-        error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_NO_AUTOHINT );
-      }
-      if( FT_Err_Ok == error )
-      {
-        if( isBoldRequired && !( ftFace->style_flags & FT_STYLE_FLAG_BOLD ) )
+        // Check to see if this is fixed size bitmap
+        if( fontFaceCacheItem.mIsFixedSizeBitmap )
         {
-          // Does the software bold.
-          FT_GlyphSlot_Embolden( ftFace->glyph );
+          error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
         }
-
-        if( isItalicRequired && !( ftFace->style_flags & FT_STYLE_FLAG_ITALIC ) )
+        else
+#endif
         {
-          // Will do the software italic.
-          isShearRequired = true;
+          error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_NO_AUTOHINT );
         }
+        if( FT_Err_Ok == error )
+        {
+          if( isBoldRequired && !( ftFace->style_flags & FT_STYLE_FLAG_BOLD ) )
+          {
+            // Does the software bold.
+            FT_GlyphSlot_Embolden( ftFace->glyph );
+          }
+
+          if( isItalicRequired && !( ftFace->style_flags & FT_STYLE_FLAG_ITALIC ) )
+          {
+            // Will do the software italic.
+            isShearRequired = true;
+          }
 
-        FT_Glyph glyph;
-        error = FT_Get_Glyph( ftFace->glyph, &glyph );
+          FT_Glyph glyph;
+          error = FT_Get_Glyph( ftFace->glyph, &glyph );
 
-        // Convert to bitmap if necessary
-        if ( FT_Err_Ok == error )
-        {
-          if( glyph->format != FT_GLYPH_FORMAT_BITMAP )
+          // Convert to bitmap if necessary
+          if( FT_Err_Ok == error )
           {
-            // Check whether we should create a bitmap for the outline
-            if( glyph->format == FT_GLYPH_FORMAT_OUTLINE && outlineWidth > 0 )
+            if( glyph->format != FT_GLYPH_FORMAT_BITMAP )
             {
-              // Set up a stroker
-              FT_Stroker stroker;
-              error = FT_Stroker_New( mFreeTypeLibrary, &stroker );
-
-              if( FT_Err_Ok == error )
+              // Check whether we should create a bitmap for the outline
+              if( glyph->format == FT_GLYPH_FORMAT_OUTLINE && outlineWidth > 0 )
               {
-                FT_Stroker_Set( stroker, outlineWidth * 64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0 );
-                error = FT_Glyph_StrokeBorder( &glyph, stroker, 0, 1 );
+                // Set up a stroker
+                FT_Stroker stroker;
+                error = FT_Stroker_New( mFreeTypeLibrary, &stroker );
 
                 if( FT_Err_Ok == error )
                 {
-                  FT_Stroker_Done( stroker );
+                  FT_Stroker_Set( stroker, outlineWidth * 64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0 );
+                  error = FT_Glyph_StrokeBorder( &glyph, stroker, 0, 1 );
+
+                  if( FT_Err_Ok == error )
+                  {
+                    FT_Stroker_Done( stroker );
+                  }
+                  else
+                  {
+                    DALI_LOG_ERROR( "FT_Glyph_StrokeBorder Failed with error: %d\n", error );
+                  }
                 }
                 else
                 {
-                  DALI_LOG_ERROR( "FT_Glyph_StrokeBorder Failed with error: %d\n", error );
+                  DALI_LOG_ERROR( "FT_Stroker_New Failed with error: %d\n", error );
                 }
               }
+
+              error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, 0, 1 );
+              if( FT_Err_Ok == error )
+              {
+                FT_BitmapGlyph bitmapGlyph = reinterpret_cast< FT_BitmapGlyph >( glyph );
+                ConvertBitmap( data, bitmapGlyph->bitmap, isShearRequired );
+              }
               else
               {
-                DALI_LOG_ERROR( "FT_Stroker_New Failed with error: %d\n", error );
+                DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::CreateBitmap. FT_Get_Glyph Failed with error: %d\n", error );
               }
             }
-
-            error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, 0, 1 );
-            if( FT_Err_Ok == error )
-            {
-              FT_BitmapGlyph bitmapGlyph = reinterpret_cast< FT_BitmapGlyph >( glyph );
-              ConvertBitmap( data, bitmapGlyph->bitmap, isShearRequired );
-            }
             else
             {
-              DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::CreateBitmap. FT_Get_Glyph Failed with error: %d\n", error );
+              ConvertBitmap( data, ftFace->glyph->bitmap, isShearRequired );
             }
-          }
-          else
-          {
-            ConvertBitmap( data, ftFace->glyph->bitmap, isShearRequired );
-          }
 
-          // Created FT_Glyph object must be released with FT_Done_Glyph
-          FT_Done_Glyph( glyph );
+            data.isColorEmoji = fontFaceCacheItem.mIsFixedSizeBitmap;
+
+            // Created FT_Glyph object must be released with FT_Done_Glyph
+            FT_Done_Glyph( glyph );
+          }
+        }
+        else
+        {
+          DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::CreateBitmap. FT_Load_Glyph Failed with error: %d\n", error );
         }
+        break;
       }
-      else
+      case FontDescription::BITMAP_FONT:
       {
-        DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::CreateBitmap. FT_Load_Glyph Failed with error: %d\n", error );
-      }
-      break;
-    }
-    case FontDescription::BITMAP_FONT:
-    {
-      BitmapFontCacheItem& bitmapFontCacheItem = mBitmapFontCache[fontIdCacheItem.id];
+        BitmapFontCacheItem& bitmapFontCacheItem = mBitmapFontCache[fontIdCacheItem.id];
 
-      unsigned int index = 0u;
-      for( auto& item : bitmapFontCacheItem.font.glyphs )
-      {
-        if( item.utf32 == glyphIndex )
+        unsigned int index = 0u;
+        for( auto& item : bitmapFontCacheItem.font.glyphs )
         {
-          Devel::PixelBuffer& pixelBuffer = bitmapFontCacheItem.pixelBuffers[index];
-          if( !pixelBuffer )
+          if( item.utf32 == glyphIndex )
           {
-            pixelBuffer = LoadImageFromFile( item.url );
-          }
+            Devel::PixelBuffer& pixelBuffer = bitmapFontCacheItem.pixelBuffers[index];
+            if( !pixelBuffer )
+            {
+              pixelBuffer = LoadImageFromFile( item.url );
+            }
 
-          data.width = pixelBuffer.GetWidth();
-          data.height = pixelBuffer.GetHeight();
+            data.width = pixelBuffer.GetWidth();
+            data.height = pixelBuffer.GetHeight();
 
-          ConvertBitmap( data, data.width, data.height, pixelBuffer.GetBuffer() );
+            data.isColorBitmap = bitmapFontCacheItem.font.isColorFont;
 
-          // Sets the pixel format.
-          data.format = pixelBuffer.GetPixelFormat();
-          break;
+            ConvertBitmap( data, data.width, data.height, pixelBuffer.GetBuffer() );
+
+            // Sets the pixel format.
+            data.format = pixelBuffer.GetPixelFormat();
+            break;
+          }
+          ++index;
         }
-        ++index;
+        break;
+      }
+      default:
+      {
+        DALI_LOG_INFO(gLogFilter, Debug::General, "  Invalid type of font\n");
       }
-      break;
-    }
-    default:
-    {
-      DALI_LOG_INFO(gLogFilter, Debug::General, "  Invalid type of font\n");
-    }
     }
   }
   else
@@ -1590,7 +1634,6 @@ bool FontClient::Plugin::IsColorGlyph( FontId fontId, GlyphIndex glyphIndex )
 
   const FontId index = fontId - 1u;
 
-#ifdef FREETYPE_BITMAP_SUPPORT
   if( ( fontId > 0u ) &&
       ( index < mFontIdCache.Count() ) )
   {
@@ -1598,30 +1641,31 @@ bool FontClient::Plugin::IsColorGlyph( FontId fontId, GlyphIndex glyphIndex )
 
     switch( fontIdCacheItem.type )
     {
-    case FontDescription::FACE_FONT:
-    {
-      const FontFaceCacheItem& item = mFontFaceCache[fontIdCacheItem.id];
-      FT_Face ftFace = item.mFreeTypeFace;
+      case FontDescription::FACE_FONT:
+      {
+#ifdef FREETYPE_BITMAP_SUPPORT
+        const FontFaceCacheItem& item = mFontFaceCache[fontIdCacheItem.id];
+        FT_Face ftFace = item.mFreeTypeFace;
 
-      // Check to see if this is fixed size bitmap
-      if( item.mHasColorTables )
+        // Check to see if this is fixed size bitmap
+        if( item.mHasColorTables )
+        {
+          error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
+        }
+#endif
+        break;
+      }
+      case FontDescription::BITMAP_FONT:
       {
-        error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
+        error = FT_Err_Ok; // Will return true;
+        break;
+      }
+      default:
+      {
+        DALI_LOG_INFO(gLogFilter, Debug::General, "  Invalid type of font\n");
       }
-      break;
-    }
-    case FontDescription::BITMAP_FONT:
-    {
-      error = FT_Err_Ok; // Will return true;
-      break;
-    }
-    default:
-    {
-      DALI_LOG_INFO(gLogFilter, Debug::General, "  Invalid type of font\n");
-    }
     }
   }
-#endif
 
   return FT_Err_Ok == error;
 }
@@ -1657,8 +1701,8 @@ FontDescription::Type FontClient::Plugin::GetFontType( FontId fontId )
 
 bool FontClient::Plugin::AddCustomFontDirectory( const FontPath& path )
 {
-  // NULL as first parameter means the current configuration is used.
-  return FcConfigAppFontAddDir( NULL, reinterpret_cast<const FcChar8 *>( path.c_str() ) );
+  // nullptr as first parameter means the current configuration is used.
+  return FcConfigAppFontAddDir( nullptr, reinterpret_cast<const FcChar8 *>( path.c_str() ) );
 }
 
 GlyphIndex FontClient::Plugin::CreateEmbeddedItem( const TextAbstraction::FontClient::EmbeddedItemDescription& description, Pixel::Format& pixelFormat )
@@ -1859,8 +1903,8 @@ FcPattern* FontClient::Plugin::CreateFontFamilyPattern( const FontDescription& f
   FcPatternAddString( fontFamilyPattern, FC_FAMILY, reinterpret_cast<const FcChar8*>( fontDescription.family.c_str() ) );
 
   // add a property to the pattern for local setting.
-  const char* locale = setlocale( LC_MESSAGES, NULL );
-  if( locale != NULL)
+  const char* locale = setlocale( LC_MESSAGES, nullptr );
+  if( locale != nullptr)
   {
     FcPatternAddString( fontFamilyPattern, FC_LANG, reinterpret_cast<const FcChar8*>( locale ) );
   }