Add trace log to check text performance
[platform/core/uifw/dali-adaptor.git] / dali / internal / text / text-abstraction / plugin / font-client-plugin-impl.cpp
index e438a53..e319b46 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
 
 // INTERNAL INCLUDES
 #include <dali/devel-api/text-abstraction/font-list.h>
-
-#include <dali/devel-api/adaptor-framework/image-loading.h>
 #include <dali/integration-api/debug.h>
+#include <dali/integration-api/trace.h>
 #include <dali/integration-api/platform-abstraction.h>
 #include <dali/internal/adaptor/common/adaptor-impl.h>
 #include <dali/internal/imaging/common/image-operations.h>
 #include <dali/internal/text/text-abstraction/plugin/bitmap-font-cache-item.h>
 #include <dali/internal/text/text-abstraction/plugin/embedded-item.h>
+#include <dali/internal/text/text-abstraction/plugin/font-client-plugin-cache-handler.h>
 #include <dali/internal/text/text-abstraction/plugin/font-client-utils.h>
 #include <dali/internal/text/text-abstraction/plugin/font-face-cache-item.h>
 #include <dali/public-api/common/dali-vector.h>
@@ -76,39 +76,25 @@ Dali::Integration::Log::Filter* gFontClientLogFilter = Dali::Integration::Log::F
 
 namespace
 {
+
+DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_FONT_PERFORMANCE_MARKER, false);
+
 /**
  * Conversion from Fractional26.6 to float
  */
 const float FROM_266        = 1.0f / 64.0f;
 const float POINTS_PER_INCH = 72.f;
 
-const std::string DEFAULT_FONT_FAMILY_NAME("Tizen");
-
 const uint32_t ELLIPSIS_CHARACTER = 0x2026;
 
 } // namespace
 
 using Dali::Vector;
-using namespace std;
 
 namespace Dali::TextAbstraction::Internal
 {
-/**
- * @brief Free the resources allocated by the FcCharSet objects.
- *
- * @param[in] characterSets The vector of character sets.
- */
-void DestroyCharacterSets(CharacterSetList& characterSets)
+namespace
 {
-  for(auto& item : characterSets)
-  {
-    if(item)
-    {
-      FcCharSetDestroy(item);
-    }
-  }
-}
-
 /**
  * @brief Check if @p ftFace and @p requestedPointSize produces block that fit into atlas block
  *
@@ -227,57 +213,17 @@ int SearchOnProperPointSize(FT_Face& ftFace, const unsigned int& horizontalDpi,
   return error;
 }
 
-FontClient::Plugin::FallbackCacheItem::FallbackCacheItem(FontDescription&& font, FontList* fallbackFonts, CharacterSetList* characterSets)
-: fontDescription{std::move(font)},
-  fallbackFonts{fallbackFonts},
-  characterSets{characterSets}
-{
-}
-
-FontClient::Plugin::FontDescriptionCacheItem::FontDescriptionCacheItem(const FontDescription& fontDescription,
-                                                                       FontDescriptionId      index)
-: fontDescription{fontDescription},
-  index{index}
-{
-}
-
-FontClient::Plugin::FontDescriptionCacheItem::FontDescriptionCacheItem(FontDescription&& fontDescription,
-                                                                       FontDescriptionId index)
-: fontDescription{std::move(fontDescription)},
-  index{index}
-{
-}
-
-FontClient::Plugin::FontDescriptionSizeCacheItem::FontDescriptionSizeCacheItem(FontDescriptionId validatedFontId,
-                                                                               PointSize26Dot6   requestedPointSize,
-                                                                               FontId            fontId)
-: validatedFontId(validatedFontId),
-  requestedPointSize(requestedPointSize),
-  fontId(fontId)
-{
-}
+} // namespace
 
 FontClient::Plugin::Plugin(unsigned int horizontalDpi,
                            unsigned int verticalDpi)
 : mFreeTypeLibrary(nullptr),
   mDpiHorizontal(horizontalDpi),
   mDpiVertical(verticalDpi),
-  mDefaultFontDescription(),
-  mSystemFonts(),
-  mDefaultFonts(),
-  mFontIdCache(),
-  mFontFaceCache(),
-  mValidatedFontCache(),
-  mFontDescriptionCache(),
-  mCharacterSetCache(),
-  mFontDescriptionSizeCache(),
-  mVectorFontCache(nullptr),
-  mEllipsisCache(),
-  mEmbeddedItemCache(),
-  mDefaultFontDescriptionCached(false),
   mIsAtlasLimitationEnabled(TextAbstraction::FontClient::DEFAULT_ATLAS_LIMITATION_ENABLED),
-  mCurrentMaximumBlockSizeFitInAtlas(TextAbstraction::FontClient::MAX_SIZE_FIT_IN_ATLAS)
-
+  mCurrentMaximumBlockSizeFitInAtlas(TextAbstraction::FontClient::MAX_SIZE_FIT_IN_ATLAS),
+  mVectorFontCache(nullptr),
+  mCacheHandler(new CacheHandler())
 {
   int error = FT_Init_FreeType(&mFreeTypeLibrary);
   if(FT_Err_Ok != error)
@@ -292,51 +238,19 @@ FontClient::Plugin::Plugin(unsigned int horizontalDpi,
 
 FontClient::Plugin::~Plugin()
 {
-  ClearFallbackCache(mFallbackCache);
-
-  // Free the resources allocated by the FcCharSet objects.
-  DestroyCharacterSets(mDefaultFontCharacterSets);
-  DestroyCharacterSets(mCharacterSetCache);
-  ClearCharacterSetFromFontFaceCache();
+  // Delete cache hanlder before remove mFreeTypeLibrary
+  delete mCacheHandler;
 
 #ifdef ENABLE_VECTOR_BASED_TEXT_RENDERING
   delete mVectorFontCache;
 #endif
+
   FT_Done_FreeType(mFreeTypeLibrary);
 }
 
-void FontClient::Plugin::ClearCache()
+void FontClient::Plugin::ClearCache() const
 {
-  mDefaultFontDescription = FontDescription();
-
-  mSystemFonts.clear();
-  mDefaultFonts.clear();
-
-  DestroyCharacterSets(mDefaultFontCharacterSets);
-  mDefaultFontCharacterSets.Clear();
-
-  ClearFallbackCache(mFallbackCache);
-  mFallbackCache.clear();
-
-  mFontIdCache.Clear();
-
-  ClearCharacterSetFromFontFaceCache();
-  mFontFaceCache.clear();
-
-  mValidatedFontCache.clear();
-  mFontDescriptionCache.clear();
-
-  DestroyCharacterSets(mCharacterSetCache);
-  mCharacterSetCache.Clear();
-
-  mFontDescriptionSizeCache.clear();
-
-  mEllipsisCache.Clear();
-  mPixelBufferCache.clear();
-  mEmbeddedItemCache.Clear();
-  mBitmapFontCache.clear();
-
-  mDefaultFontDescriptionCached = false;
+  mCacheHandler->ClearCache();
 }
 
 void FontClient::Plugin::SetDpi(unsigned int horizontalDpi,
@@ -346,218 +260,59 @@ void FontClient::Plugin::SetDpi(unsigned int horizontalDpi,
   mDpiVertical   = verticalDpi;
 }
 
-void FontClient::Plugin::ResetSystemDefaults()
-{
-  mDefaultFontDescriptionCached = false;
-}
-
-void FontClient::Plugin::SetFontList(const FontDescription& fontDescription, FontList& fontList, CharacterSetList& characterSetList)
+void FontClient::Plugin::ResetSystemDefaults() const
 {
-  DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
-  FONT_LOG_DESCRIPTION(fontDescription, "");
-  fontList.clear();
-
-  FcPattern* fontFamilyPattern = CreateFontFamilyPattern(fontDescription); // Creates a pattern that needs to be destroyed by calling FcPatternDestroy.
-
-  FcResult result = FcResultMatch;
-
-  // Match the pattern.
-  FcFontSet* fontSet = FcFontSort(nullptr /* use default configure */,
-                                  fontFamilyPattern,
-                                  false /* don't trim */,
-                                  nullptr,
-                                  &result); // FcFontSort creates a font set that needs to be destroyed by calling FcFontSetDestroy.
-
-  if(nullptr != fontSet)
-  {
-    DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  number of fonts found : [%d]\n", fontSet->nfont);
-    // Reserve some space to avoid reallocations.
-    fontList.reserve(fontSet->nfont);
-
-    for(int i = 0u; i < fontSet->nfont; ++i)
-    {
-      FcPattern* fontPattern = fontSet->fonts[i];
-
-      FontPath path;
-
-      // Skip fonts with no path
-      if(GetFcString(fontPattern, FC_FILE, path))
-      {
-        // Retrieve the character set. Need to call FcCharSetDestroy to free the resources.
-        FcCharSet* characterSet = nullptr;
-        FcPatternGetCharSet(fontPattern, FC_CHARSET, 0u, &characterSet);
-
-        // Increase the reference counter of the character set.
-        characterSetList.PushBack(FcCharSetCopy(characterSet));
-
-        fontList.push_back(FontDescription());
-        FontDescription& newFontDescription = fontList.back();
-
-        newFontDescription.path = std::move(path);
-
-        int width  = 0;
-        int weight = 0;
-        int slant  = 0;
-        GetFcString(fontPattern, FC_FAMILY, newFontDescription.family);
-        GetFcInt(fontPattern, FC_WIDTH, width);
-        GetFcInt(fontPattern, FC_WEIGHT, weight);
-        GetFcInt(fontPattern, FC_SLANT, slant);
-        newFontDescription.width  = IntToWidthType(width);
-        newFontDescription.weight = IntToWeightType(weight);
-        newFontDescription.slant  = IntToSlantType(slant);
-
-        FONT_LOG_DESCRIPTION(newFontDescription, "");
-      }
-    }
-
-    // Destroys the font set created by FcFontSort.
-    FcFontSetDestroy(fontSet);
-  }
-  else
-  {
-    DALI_LOG_INFO(gFontClientLogFilter, Debug::Verbose, "  No fonts found.\n");
-  }
-
-  // Destroys the pattern created by FcPatternCreate in CreateFontFamilyPattern.
-  FcPatternDestroy(fontFamilyPattern);
+  mCacheHandler->ResetSystemDefaults();
 }
 
-void FontClient::Plugin::GetDefaultFonts(FontList& defaultFonts)
+void FontClient::Plugin::GetDefaultPlatformFontDescription(FontDescription& fontDescription) const
 {
   DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
 
-  if(mDefaultFonts.empty())
-  {
-    FontDescription fontDescription;
-    fontDescription.family = DEFAULT_FONT_FAMILY_NAME; // todo This could be set to the Platform font
-    fontDescription.width  = DefaultFontWidth();
-    fontDescription.weight = DefaultFontWeight();
-    fontDescription.slant  = DefaultFontSlant();
-    SetFontList(fontDescription, mDefaultFonts, mDefaultFontCharacterSets);
-  }
-
-  defaultFonts = mDefaultFonts;
+  mCacheHandler->InitDefaultFontDescription();
+  fontDescription = mCacheHandler->mDefaultFontDescription;
 
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  number of default fonts : [%d]\n", mDefaultFonts.size());
+  FONT_LOG_DESCRIPTION(fontDescription, "");
 }
 
-void FontClient::Plugin::GetDefaultPlatformFontDescription(FontDescription& fontDescription)
+void FontClient::Plugin::GetDefaultFonts(FontList& defaultFonts) const
 {
   DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
 
-  if(!mDefaultFontDescriptionCached)
-  {
-    // Clear any font config stored info in the caches.
-
-    // Decrease the reference counter and eventually free the resources allocated by FcCharSet objects.
-    DestroyCharacterSets(mDefaultFontCharacterSets);
-    DestroyCharacterSets(mCharacterSetCache);
-    mDefaultFontCharacterSets.Clear();
-    mCharacterSetCache.Clear();
-
-    for(auto& item : mFallbackCache)
-    {
-      // Decrease the reference counter and eventually free the resources allocated by FcCharSet objects.
-      DestroyCharacterSets(*item.characterSets);
-
-      delete item.characterSets;
-      item.characterSets = nullptr;
-    }
-
-    // Set the character set pointer as null. Will be created again the next time IsCharacterSupportedByFont()
-    ClearCharacterSetFromFontFaceCache();
-
-    // FcInitBringUptoDate did not seem to reload config file as was still getting old default font.
-    FcInitReinitialize();
-
-    FcPattern* matchPattern = FcPatternCreate(); // Creates a pattern that needs to be destroyed by calling FcPatternDestroy.
-
-    if(nullptr != matchPattern)
-    {
-      FcConfigSubstitute(nullptr, matchPattern, FcMatchPattern);
-      FcDefaultSubstitute(matchPattern);
-
-      FcCharSet* characterSet = nullptr;
-      MatchFontDescriptionToPattern(matchPattern, mDefaultFontDescription, &characterSet);
-      // Decrease the reference counter of the character set as it's not stored.
-      FcCharSetDestroy(characterSet);
-
-      // Destroys the pattern created.
-      FcPatternDestroy(matchPattern);
-    }
-
-    // Create again the character sets as they are not valid after FcInitReinitialize()
-
-    for(const auto& description : mDefaultFonts)
-    {
-      mDefaultFontCharacterSets.PushBack(FcCharSetCopy(CreateCharacterSetFromDescription(description)));
-    }
-
-    for(const auto& description : mFontDescriptionCache)
-    {
-      mCharacterSetCache.PushBack(FcCharSetCopy(CreateCharacterSetFromDescription(description)));
-    }
-
-    for(auto& item : mFallbackCache)
-    {
-      if(nullptr != item.fallbackFonts)
-      {
-        if(nullptr == item.characterSets)
-        {
-          item.characterSets = new CharacterSetList;
-        }
-
-        for(const auto& description : *(item.fallbackFonts))
-        {
-          item.characterSets->PushBack(FcCharSetCopy(CreateCharacterSetFromDescription(description)));
-        }
-      }
-    }
-
-    mDefaultFontDescriptionCached = true;
-  }
-
-  fontDescription.path   = mDefaultFontDescription.path;
-  fontDescription.family = mDefaultFontDescription.family;
-  fontDescription.width  = mDefaultFontDescription.width;
-  fontDescription.weight = mDefaultFontDescription.weight;
-  fontDescription.slant  = mDefaultFontDescription.slant;
+  mCacheHandler->InitDefaultFonts();
+  defaultFonts = mCacheHandler->mDefaultFonts;
 
-  FONT_LOG_DESCRIPTION(fontDescription, "");
+  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  number of default fonts : [%d]\n", mCacheHandler->mDefaultFonts.size());
 }
 
-void FontClient::Plugin::GetSystemFonts(FontList& systemFonts)
+void FontClient::Plugin::GetSystemFonts(FontList& systemFonts) const
 {
   DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
 
-  if(mSystemFonts.empty())
-  {
-    InitSystemFonts();
-  }
+  mCacheHandler->InitSystemFonts();
+  systemFonts = mCacheHandler->mSystemFonts;
 
-  systemFonts = mSystemFonts;
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  number of system fonts : [%d]\n", mSystemFonts.size());
+  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  number of system fonts : [%d]\n", mCacheHandler->mSystemFonts.size());
 }
 
-void FontClient::Plugin::GetDescription(FontId           id,
+void FontClient::Plugin::GetDescription(FontId           fontId,
                                         FontDescription& fontDescription) const
 {
   DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  font id : %d\n", id);
-  const FontId index = id - 1u;
+  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  font id : %d\n", fontId);
 
-  if((id > 0u) && (index < mFontIdCache.Count()))
+  if((fontId > 0u) && (fontId - 1u < mCacheHandler->mFontIdCache.size()))
   {
-    const FontIdCacheItem& fontIdCacheItem = mFontIdCache[index];
+    const auto& fontIdCacheItem = mCacheHandler->mFontIdCache[fontId - 1u];
     switch(fontIdCacheItem.type)
     {
       case FontDescription::FACE_FONT:
       {
-        for(const auto& item : mFontDescriptionSizeCache)
+        for(const auto& item : mCacheHandler->mFontDescriptionSizeCache)
         {
-          if(item.fontId == fontIdCacheItem.id)
+          if(item.second == fontIdCacheItem.index)
           {
-            fontDescription = *(mFontDescriptionCache.begin() + item.validatedFontId - 1u);
+            fontDescription = *(mCacheHandler->mFontDescriptionCache.begin() + item.first.fontDescriptionId - 1u);
 
             FONT_LOG_DESCRIPTION(fontDescription, "");
             return;
@@ -568,7 +323,7 @@ void FontClient::Plugin::GetDescription(FontId           id,
       case FontDescription::BITMAP_FONT:
       {
         fontDescription.type   = FontDescription::BITMAP_FONT;
-        fontDescription.family = mBitmapFontCache[fontIdCacheItem.id].font.name;
+        fontDescription.family = mCacheHandler->mBitmapFontCache[fontIdCacheItem.index].font.name;
         break;
       }
       default:
@@ -580,16 +335,16 @@ void FontClient::Plugin::GetDescription(FontId           id,
     }
   }
 
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  No description found for the font ID %d\n", id);
+  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  No description found for the font id %d\n", fontId);
 }
 
-PointSize26Dot6 FontClient::Plugin::GetPointSize(FontId id)
+PointSize26Dot6 FontClient::Plugin::GetPointSize(FontId fontId) const
 {
   DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  font id : %d\n", id);
+  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  font id : %d\n", fontId);
 
   PointSize26Dot6               pointSize     = TextAbstraction::FontClient::DEFAULT_POINT_SIZE;
-  const FontCacheItemInterface* fontCacheItem = GetCachedFontItem(id);
+  const FontCacheItemInterface* fontCacheItem = GetCachedFontItem(fontId);
   if(fontCacheItem != nullptr)
   {
     pointSize = fontCacheItem->GetPointSize();
@@ -599,7 +354,7 @@ PointSize26Dot6 FontClient::Plugin::GetPointSize(FontId id)
   return pointSize;
 }
 
-bool FontClient::Plugin::IsCharacterSupportedByFont(FontId fontId, Character character)
+bool FontClient::Plugin::IsCharacterSupportedByFont(FontId fontId, Character character) const
 {
   DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
   DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "    font id : %d\n", fontId);
@@ -616,21 +371,20 @@ bool FontClient::Plugin::IsCharacterSupportedByFont(FontId fontId, Character cha
   return isSupported;
 }
 
-const FontCacheItemInterface* FontClient::Plugin::GetCachedFontItem(FontId id) const
+const FontCacheItemInterface* FontClient::Plugin::GetCachedFontItem(FontId fontId) const
 {
-  const FontId index = id - 1u;
-  if((id > 0u) && (index < mFontIdCache.Count()))
+  if((fontId > 0u) && (fontId - 1u < mCacheHandler->mFontIdCache.size()))
   {
-    const FontIdCacheItem& fontIdCacheItem = mFontIdCache[index];
+    const auto& fontIdCacheItem = mCacheHandler->mFontIdCache[fontId - 1u];
     switch(fontIdCacheItem.type)
     {
       case FontDescription::FACE_FONT:
       {
-        return &mFontFaceCache[fontIdCacheItem.id];
+        return &mCacheHandler->mFontFaceCache[fontIdCacheItem.index];
       }
       case FontDescription::BITMAP_FONT:
       {
-        return &mBitmapFontCache[fontIdCacheItem.id];
+        return &mCacheHandler->mBitmapFontCache[fontIdCacheItem.index];
       }
       default:
       {
@@ -645,7 +399,7 @@ FontId FontClient::Plugin::FindFontForCharacter(const FontList&         fontList
                                                 const CharacterSetList& characterSetList,
                                                 Character               character,
                                                 PointSize26Dot6         requestedPointSize,
-                                                bool                    preferColor)
+                                                bool                    preferColor) const
 {
   DALI_ASSERT_DEBUG((fontList.size() == characterSetList.Count()) && "FontClient::Plugin::FindFontForCharacter. Different number of fonts and character sets.");
   DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
@@ -681,10 +435,9 @@ FontId FontClient::Plugin::FindFontForCharacter(const FontList&         fontList
 
       if(preferColor)
       {
-        if((fontId > 0) &&
-           (fontId - 1u < mFontIdCache.Count()))
+        if((fontId > 0) && (fontId - 1u < mCacheHandler->mFontIdCache.size()))
         {
-          const FontFaceCacheItem& item = mFontFaceCache[mFontIdCache[fontId - 1u].id];
+          const FontFaceCacheItem& item = mCacheHandler->mFontFaceCache[mCacheHandler->mFontIdCache[fontId - 1u].index];
 
           foundColor = item.mHasColorTables;
         }
@@ -706,7 +459,7 @@ FontId FontClient::Plugin::FindFontForCharacter(const FontList&         fontList
 
 FontId FontClient::Plugin::FindDefaultFont(Character       charcode,
                                            PointSize26Dot6 requestedPointSize,
-                                           bool            preferColor)
+                                           bool            preferColor) const
 {
   DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
   FONT_LOG_REQUEST(charcode, requestedPointSize, preferColor);
@@ -714,21 +467,12 @@ FontId FontClient::Plugin::FindDefaultFont(Character       charcode,
   FontId fontId(0);
 
   // Create the list of default fonts if it has not been created.
-  if(mDefaultFonts.empty())
-  {
-    FontDescription fontDescription;
-    fontDescription.family = DEFAULT_FONT_FAMILY_NAME;
-    fontDescription.width  = DefaultFontWidth();
-    fontDescription.weight = DefaultFontWeight();
-    fontDescription.slant  = DefaultFontSlant();
-
-    SetFontList(fontDescription, mDefaultFonts, mDefaultFontCharacterSets);
-  }
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::Verbose, "  number of default fonts : %d\n", mDefaultFonts.size());
+  mCacheHandler->InitDefaultFonts();
+  DALI_LOG_INFO(gFontClientLogFilter, Debug::Verbose, "  number of default fonts : %d\n", mCacheHandler->mDefaultFonts.size());
 
   // Traverse the list of default fonts.
   // Check for each default font if supports the character.
-  fontId = FindFontForCharacter(mDefaultFonts, mDefaultFontCharacterSets, charcode, requestedPointSize, preferColor);
+  fontId = FindFontForCharacter(mCacheHandler->mDefaultFonts, mCacheHandler->mDefaultFontCharacterSets, charcode, requestedPointSize, preferColor);
 
   DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  font id : %d\n", fontId);
   return fontId;
@@ -737,18 +481,20 @@ FontId FontClient::Plugin::FindDefaultFont(Character       charcode,
 FontId FontClient::Plugin::FindFallbackFont(Character              charcode,
                                             const FontDescription& preferredFontDescription,
                                             PointSize26Dot6        requestedPointSize,
-                                            bool                   preferColor)
+                                            bool                   preferColor) const
 {
   DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
   FONT_LOG_REQUEST(charcode, requestedPointSize, preferColor);
 
+  DALI_TRACE_SCOPE(gTraceFilter, "DALI_TEXT_FIND_FALLBACKFONT");
+
   // The font id to be returned.
   FontId fontId = 0u;
 
   FontDescription 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.family = preferredFontDescription.family.empty() ? DefaultFontFamily() : preferredFontDescription.family;
   fontDescription.weight = ((FontWeight::NONE == preferredFontDescription.weight) ? DefaultFontWeight() : preferredFontDescription.weight);
   fontDescription.width  = ((FontWidth::NONE == preferredFontDescription.width) ? DefaultFontWidth() : preferredFontDescription.width);
   fontDescription.slant  = ((FontSlant::NONE == preferredFontDescription.slant) ? DefaultFontSlant() : preferredFontDescription.slant);
@@ -759,34 +505,20 @@ FontId FontClient::Plugin::FindFallbackFont(Character              charcode,
   DALI_LOG_INFO(gFontClientLogFilter, Debug::Verbose, "  [%s] --> [%s]\n", FontWidth::Name[preferredFontDescription.width], FontWidth::Name[fontDescription.width]);
   DALI_LOG_INFO(gFontClientLogFilter, Debug::Verbose, "  [%s] --> [%s]\n", FontSlant::Name[preferredFontDescription.slant], FontSlant::Name[fontDescription.slant]);
 
+  #if defined(TRACE_ENABLED)
+  if(gTraceFilter && gTraceFilter->IsTraceEnabled())
+  {
+    DALI_LOG_DEBUG_INFO("DALI_TEXT_FIND_FALLBACKFONT : %s -> %s\n", preferredFontDescription.family.c_str(), fontDescription.family.c_str());
+  }
+  #endif
+
   // Check first if the font's description has been queried before.
   FontList*         fontList         = nullptr;
   CharacterSetList* characterSetList = nullptr;
 
-  if(!FindFallbackFontList(fontDescription, fontList, characterSetList))
+  if(!mCacheHandler->FindFallbackFontList(fontDescription, fontList, characterSetList))
   {
-    fontList         = new FontList;
-    characterSetList = new CharacterSetList;
-
-    SetFontList(fontDescription, *fontList, *characterSetList);
-#ifdef __APPLE__
-    FontDescription appleColorEmoji;
-    appleColorEmoji.family = "Apple Color Emoji";
-    appleColorEmoji.width  = fontDescription.width;
-    appleColorEmoji.weight = fontDescription.weight;
-    appleColorEmoji.slant  = fontDescription.slant;
-    FontList         emojiFontList;
-    CharacterSetList emojiCharSetList;
-    SetFontList(appleColorEmoji, emojiFontList, emojiCharSetList);
-
-    std::move(fontList->begin(), fontList->end(), std::back_inserter(emojiFontList));
-    emojiCharSetList.Insert(emojiCharSetList.End(), characterSetList->Begin(), characterSetList->End());
-    *fontList         = std::move(emojiFontList);
-    *characterSetList = std::move(emojiCharSetList);
-#endif
-
-    // Add the font-list to the cache.
-    mFallbackCache.push_back(std::move(FallbackCacheItem(std::move(fontDescription), fontList, characterSetList)));
+    mCacheHandler->CacheFallbackFontList(std::move(fontDescription), fontList, characterSetList);
   }
 
   if(fontList && characterSetList)
@@ -798,10 +530,10 @@ FontId FontClient::Plugin::FindFallbackFont(Character              charcode,
   return fontId;
 }
 
-FontId FontClient::Plugin::GetFontId(const FontPath& path,
-                                     PointSize26Dot6 requestedPointSize,
-                                     FaceIndex       faceIndex,
-                                     bool            cacheDescription)
+FontId FontClient::Plugin::GetFontIdByPath(const FontPath& path,
+                                           PointSize26Dot6 requestedPointSize,
+                                           FaceIndex       faceIndex,
+                                           bool            cacheDescription) const
 {
   DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
   DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "                path : [%s]\n", path.c_str());
@@ -812,7 +544,7 @@ FontId FontClient::Plugin::GetFontId(const FontPath& path,
   if(nullptr != mFreeTypeLibrary)
   {
     FontId foundId = 0u;
-    if(FindFont(path, requestedPointSize, faceIndex, foundId))
+    if(mCacheHandler->FindFontByPath(path, requestedPointSize, faceIndex, foundId))
     {
       id = foundId;
     }
@@ -828,10 +560,22 @@ FontId FontClient::Plugin::GetFontId(const FontPath& path,
 
 FontId FontClient::Plugin::GetFontId(const FontDescription& fontDescription,
                                      PointSize26Dot6        requestedPointSize,
-                                     FaceIndex              faceIndex)
+                                     FaceIndex              faceIndex) const
 {
   DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
   FONT_LOG_DESCRIPTION(fontDescription, "");
+
+  // Special case when font Description don't have family information.
+  // In this case, we just use default description family and path.
+  const FontDescription& realFontDescription = fontDescription.family.empty() ? FontDescription(mCacheHandler->mDefaultFontDescription.path,
+                                                                                                mCacheHandler->mDefaultFontDescription.family,
+                                                                                                fontDescription.width,
+                                                                                                fontDescription.weight,
+                                                                                                fontDescription.slant,
+                                                                                                fontDescription.type)
+                                                                              : fontDescription;
+
+  FONT_LOG_DESCRIPTION(realFontDescription, "");
   DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "   requestedPointSize : %d\n", requestedPointSize);
 
   // This method uses three vectors which caches:
@@ -856,145 +600,94 @@ FontId FontClient::Plugin::GetFontId(const FontDescription& fontDescription,
   FontId fontId = 0u;
 
   // Check first if the font description matches with a previously loaded bitmap font.
-  if(FindBitmapFont(fontDescription.family, fontId))
+  if(mCacheHandler->FindBitmapFont(realFontDescription.family, fontId))
   {
     return fontId;
   }
 
   // Check if the font's description have been validated before.
-  FontDescriptionId validatedFontId = 0u;
+  FontDescriptionId fontDescriptionId = 0u;
 
-  if(!FindValidatedFont(fontDescription,
-                        validatedFontId))
+  if(!mCacheHandler->FindValidatedFont(realFontDescription, fontDescriptionId))
   {
     // Use font config to validate the font's description.
-    ValidateFont(fontDescription,
-                 validatedFontId);
+    mCacheHandler->ValidateFont(realFontDescription, fontDescriptionId);
   }
 
-  FontId fontFaceId = 0u;
-  // Check if exists a pair 'validatedFontId, requestedPointSize' in the cache.
-  if(!FindFont(validatedFontId, requestedPointSize, fontFaceId))
+  using FontCacheIndex          = CacheHandler::FontCacheIndex;
+  FontCacheIndex fontCacheIndex = 0u;
+  // Check if exists a pair 'fontDescriptionId, requestedPointSize' in the cache.
+  if(!mCacheHandler->FindFont(fontDescriptionId, requestedPointSize, fontCacheIndex))
   {
     // Retrieve the font file name path.
-    const FontDescription& description = *(mFontDescriptionCache.begin() + validatedFontId - 1u);
+    const FontDescription& description = *(mCacheHandler->mFontDescriptionCache.begin() + fontDescriptionId - 1u);
 
     // Retrieve the font id. Do not cache the description as it has been already cached.
-    fontId = GetFontId(description.path,
-                       requestedPointSize,
-                       faceIndex,
-                       false);
-
-    fontFaceId                               = mFontIdCache[fontId - 1u].id;
-    mFontFaceCache[fontFaceId].mCharacterSet = FcCharSetCopy(mCharacterSetCache[validatedFontId - 1u]);
-
-    // Cache the pair 'validatedFontId, requestedPointSize' to improve the following queries.
-    mFontDescriptionSizeCache.push_back(FontDescriptionSizeCacheItem(validatedFontId,
-                                                                     requestedPointSize,
-                                                                     fontFaceId));
+    // Note : CacheFontPath() API call ValidateFont() + setup CharacterSet + cache the font description.
+    // So set cacheDescription=false, that we don't call CacheFontPath().
+    fontId = GetFontIdByPath(description.path, requestedPointSize, faceIndex, false);
+
+    if((fontId > 0u) && (fontId - 1u < mCacheHandler->mFontIdCache.size()))
+    {
+      fontCacheIndex                                              = mCacheHandler->mFontIdCache[fontId - 1u].index;
+      mCacheHandler->mFontFaceCache[fontCacheIndex].mCharacterSet = FcCharSetCopy(mCacheHandler->mCharacterSetCache[fontDescriptionId - 1u]);
+
+      // Cache the pair 'fontDescriptionId, requestedPointSize' to improve the following queries.
+      mCacheHandler->CacheFontDescriptionSize(fontDescriptionId, requestedPointSize, fontCacheIndex);
+    }
   }
   else
   {
-    fontId = mFontFaceCache[fontFaceId].mFontId + 1u;
+    fontId = mCacheHandler->mFontFaceCache[fontCacheIndex].mFontId + 1u;
   }
 
   DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  font id : %d\n", fontId);
   return fontId;
 }
 
-FontId FontClient::Plugin::GetFontId(const BitmapFont& bitmapFont)
+FontId FontClient::Plugin::GetFontId(const BitmapFont& bitmapFont) const
 {
-  for(const auto& item : mBitmapFontCache)
+  // The font id to be returned.
+  FontId fontId = 0u;
+  if(!mCacheHandler->FindBitmapFont(bitmapFont.name, fontId))
   {
-    if(bitmapFont.name == item.font.name)
-    {
-      return item.id + 1u;
-    }
-  }
+    BitmapFontCacheItem bitmapFontCacheItem(bitmapFont);
 
-  BitmapFontCacheItem bitmapFontCacheItem(bitmapFont, mFontIdCache.Count());
-
-  FontIdCacheItem fontIdCacheItem;
-  fontIdCacheItem.type = FontDescription::BITMAP_FONT;
-  fontIdCacheItem.id   = mBitmapFontCache.size();
-
-  mBitmapFontCache.push_back(std::move(bitmapFontCacheItem));
-  mFontIdCache.PushBack(fontIdCacheItem);
-
-  return bitmapFontCacheItem.id + 1u;
+    fontId = mCacheHandler->CacheBitmapFontCacheItem(std::move(bitmapFontCacheItem));
+  }
+  return fontId;
 }
 
-void FontClient::Plugin::ValidateFont(const FontDescription& fontDescription,
-                                      FontDescriptionId&     validatedFontId)
+void FontClient::Plugin::GetFontMetrics(FontId       fontId,
+                                        FontMetrics& metrics) const
 {
-  DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
-  FONT_LOG_DESCRIPTION(fontDescription, "");
-
-  // Create a font pattern.
-  FcPattern* fontFamilyPattern = CreateFontFamilyPattern(fontDescription);
-
-  FontDescription description;
-
-  FcCharSet* characterSet = nullptr;
-  bool       matched      = MatchFontDescriptionToPattern(fontFamilyPattern, description, &characterSet);
-  FcPatternDestroy(fontFamilyPattern);
-
-  if(matched && (nullptr != characterSet))
-  {
-    // Add the path to the cache.
-    description.type = FontDescription::FACE_FONT;
-    mFontDescriptionCache.push_back(description);
-
-    // Set the index to the vector of paths to font file names.
-    validatedFontId = mFontDescriptionCache.size();
-
-    FONT_LOG_DESCRIPTION(description, "matched");
-    DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  validatedFontId : %d\n", validatedFontId);
-
-    // The reference counter of the character set has already been increased in MatchFontDescriptionToPattern.
-    mCharacterSetCache.PushBack(characterSet);
-
-    // Cache the index and the matched font's description.
-    FontDescriptionCacheItem item(description,
-                                  validatedFontId);
-
-    mValidatedFontCache.push_back(std::move(item));
-
-    if((fontDescription.family != description.family) ||
-       (fontDescription.width != description.width) ||
-       (fontDescription.weight != description.weight) ||
-       (fontDescription.slant != description.slant))
-    {
-      // Cache the given font's description if it's different than the matched.
-      FontDescriptionCacheItem item(fontDescription,
-                                    validatedFontId);
-
-      mValidatedFontCache.push_back(std::move(item));
-    }
-  }
-  else
+  const FontCacheItemInterface* fontCacheItem = GetCachedFontItem(fontId);
+  if(fontCacheItem != nullptr)
   {
-    DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  font validation failed for font [%s]\n", fontDescription.family.c_str());
+    fontCacheItem->GetFontMetrics(metrics, mDpiVertical);
   }
 }
 
-void FontClient::Plugin::GetFontMetrics(FontId       fontId,
-                                        FontMetrics& metrics)
+GlyphIndex FontClient::Plugin::GetGlyphIndex(FontId    fontId,
+                                             Character charcode) const
 {
   const FontCacheItemInterface* fontCacheItem = GetCachedFontItem(fontId);
   if(fontCacheItem != nullptr)
   {
-    fontCacheItem->GetFontMetrics(metrics, mDpiVertical);
+    return fontCacheItem->GetGlyphIndex(charcode);
   }
+
+  return 0u;
 }
 
 GlyphIndex FontClient::Plugin::GetGlyphIndex(FontId    fontId,
-                                             Character charcode)
+                                             Character charcode,
+                                             Character variantSelector) const
 {
   const FontCacheItemInterface* fontCacheItem = GetCachedFontItem(fontId);
   if(fontCacheItem != nullptr)
   {
-    return fontCacheItem->GetGlyphIndex(charcode);
+    return fontCacheItem->GetGlyphIndex(charcode, variantSelector);
   }
 
   return 0u;
@@ -1003,7 +696,7 @@ GlyphIndex FontClient::Plugin::GetGlyphIndex(FontId    fontId,
 bool FontClient::Plugin::GetGlyphMetrics(GlyphInfo* array,
                                          uint32_t   size,
                                          GlyphType  type,
-                                         bool       horizontal)
+                                         bool       horizontal) const
 {
   if(VECTOR_GLYPH == type)
   {
@@ -1015,9 +708,9 @@ bool FontClient::Plugin::GetGlyphMetrics(GlyphInfo* array,
 
 bool FontClient::Plugin::GetBitmapMetrics(GlyphInfo* array,
                                           uint32_t   size,
-                                          bool       horizontal)
+                                          bool       horizontal) const
 {
-  bool success(false);
+  bool success(size > 0u);
 
   for(unsigned int i = 0; i < size; ++i)
   {
@@ -1026,13 +719,16 @@ bool FontClient::Plugin::GetBitmapMetrics(GlyphInfo* array,
     const FontCacheItemInterface* fontCacheItem = GetCachedFontItem(glyph.fontId);
     if(fontCacheItem != nullptr)
     {
-      success = fontCacheItem->GetGlyphMetrics(glyph, mDpiVertical, horizontal);
+      success &= fontCacheItem->GetGlyphMetrics(glyph, mDpiVertical, horizontal);
     }
     // Check if it's an embedded image.
-    else if((0u == glyph.fontId) && (0u != glyph.index) && (glyph.index <= mEmbeddedItemCache.Count()))
+    else if((0u == glyph.fontId) && (0u != glyph.index) && (glyph.index <= mCacheHandler->mEmbeddedItemCache.size()))
+    {
+      mCacheHandler->mEmbeddedItemCache[glyph.index - 1u].GetGlyphMetrics(glyph);
+    }
+    else
     {
-      mEmbeddedItemCache[glyph.index - 1u].GetGlyphMetrics(glyph);
-      success = true;
+      success = false;
     }
   }
 
@@ -1041,7 +737,7 @@ bool FontClient::Plugin::GetBitmapMetrics(GlyphInfo* array,
 
 bool FontClient::Plugin::GetVectorMetrics(GlyphInfo* array,
                                           uint32_t   size,
-                                          bool       horizontal)
+                                          bool       horizontal) const
 {
 #ifdef ENABLE_VECTOR_BASED_TEXT_RENDERING
   bool success(true);
@@ -1051,9 +747,9 @@ bool FontClient::Plugin::GetVectorMetrics(GlyphInfo* array,
     FontId fontId = array[i].fontId;
 
     if((fontId > 0u) &&
-       (fontId - 1u) < mFontIdCache.Count())
+       (fontId - 1u) < mCacheHandler->mFontIdCache.size())
     {
-      FontFaceCacheItem& font = mFontFaceCache[mFontIdCache[fontId - 1u].id];
+      FontFaceCacheItem& font = mCacheHandler->mFontFaceCache[mCacheHandler->mFontIdCache[fontId - 1u].index];
 
       if(!font.mVectorFontId)
       {
@@ -1082,7 +778,7 @@ bool FontClient::Plugin::GetVectorMetrics(GlyphInfo* array,
 #endif
 }
 
-void FontClient::Plugin::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, bool isItalicRequired, bool isBoldRequired, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth)
+void FontClient::Plugin::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, bool isItalicRequired, bool isBoldRequired, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth) const
 {
   data.isColorBitmap                          = false;
   data.isColorEmoji                           = false;
@@ -1091,95 +787,105 @@ void FontClient::Plugin::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, bool
   {
     fontCacheItem->CreateBitmap(glyphIndex, data, outlineWidth, isItalicRequired, isBoldRequired);
   }
-  else if((0u != glyphIndex) && (glyphIndex <= mEmbeddedItemCache.Count()))
+  else if((0u != glyphIndex) && (glyphIndex <= mCacheHandler->mEmbeddedItemCache.size()))
   {
     // It's an embedded item.
-    mEmbeddedItemCache[glyphIndex - 1u].CreateBitmap(mPixelBufferCache, data);
+    mCacheHandler->mEmbeddedItemCache[glyphIndex - 1u].CreateBitmap(mCacheHandler->mPixelBufferCache, data);
   }
 }
 
-PixelData FontClient::Plugin::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, int outlineWidth)
+PixelData FontClient::Plugin::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, int outlineWidth) const
 {
   TextAbstraction::FontClient::GlyphBufferData data;
 
   CreateBitmap(fontId, glyphIndex, false, false, data, outlineWidth);
 
+  // If data is compressed or not owned buffer, copy this.
+  if(!data.isBufferOwned || data.compressionType != TextAbstraction::FontClient::GlyphBufferData::CompressionType::NO_COMPRESSION)
+  {
+    uint8_t* newBuffer = (uint8_t*)malloc(data.width * data.height * Pixel::GetBytesPerPixel(data.format));
+    TextAbstraction::FontClient::GlyphBufferData::Decompress(data, newBuffer);
+    if(data.isBufferOwned)
+    {
+      free(data.buffer);
+    }
+
+    data.buffer          = newBuffer;
+    data.isBufferOwned   = true;
+    data.compressionType = TextAbstraction::FontClient::GlyphBufferData::CompressionType::NO_COMPRESSION;
+  }
+
   return PixelData::New(data.buffer,
                         data.width * data.height * Pixel::GetBytesPerPixel(data.format),
                         data.width,
                         data.height,
                         data.format,
-                        PixelData::DELETE_ARRAY);
+                        PixelData::FREE);
 }
 
-void FontClient::Plugin::CreateVectorBlob(FontId fontId, GlyphIndex glyphIndex, VectorBlob*& blob, unsigned int& blobLength, unsigned int& nominalWidth, unsigned int& nominalHeight)
+void FontClient::Plugin::CreateVectorBlob(FontId fontId, GlyphIndex glyphIndex, VectorBlob*& blob, unsigned int& blobLength, unsigned int& nominalWidth, unsigned int& nominalHeight) const
 {
   blob       = nullptr;
   blobLength = 0;
 
 #ifdef ENABLE_VECTOR_BASED_TEXT_RENDERING
   if((fontId > 0u) &&
-     (fontId - 1u < mFontIdCache.Count()))
+     (fontId - 1u < mCacheHandler->mFontIdCache.size()))
   {
-    const FontId       fontFaceId = mFontIdCache[fontId - 1u].id;
-    FontFaceCacheItem& font       = mFontFaceCache[fontFaceId];
+    using FontCacheIndex                = CacheHandler::FontCacheIndex;
+    const FontCacheIndex fontCacheIndex = mCacheHandler->mFontIdCache[fontId - 1u].index;
+    FontFaceCacheItem&   font           = mCacheHandler->mFontFaceCache[fontCacheIndex];
 
     if(!font.mVectorFontId)
     {
       font.mVectorFontId = mVectorFontCache->GetFontId(font.mPath);
     }
 
-    mVectorFontCache->GetVectorBlob(font.mVectorFontId, fontFaceId, glyphIndex, blob, blobLength, nominalWidth, nominalHeight);
+    mVectorFontCache->GetVectorBlob(font.mVectorFontId, fontCacheIndex, glyphIndex, blob, blobLength, nominalWidth, nominalHeight);
   }
 #endif
 }
 
-const GlyphInfo& FontClient::Plugin::GetEllipsisGlyph(PointSize26Dot6 requestedPointSize)
+const GlyphInfo& FontClient::Plugin::GetEllipsisGlyph(PointSize26Dot6 requestedPointSize) const
 {
-  DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  requestedPointSize %d.\n", requestedPointSize);
+  using EllipsisCacheIndex              = CacheHandler::EllipsisCacheIndex;
+  using EllipsisItem                    = CacheHandler::EllipsisItem;
+  EllipsisCacheIndex ellipsisCacheIndex = 0u;
 
-  // First look into the cache if there is an ellipsis glyph for the requested point size.
-  for(const auto& item : mEllipsisCache)
+  if(!mCacheHandler->FindEllipsis(requestedPointSize, ellipsisCacheIndex))
   {
-    if(item.requestedPointSize == requestedPointSize)
-    {
-      // Use the glyph in the cache.
-      DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  glyph id %d found in the cache.\n", item.glyph.index);
-      DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "      font %d.\n", item.glyph.fontId);
-      return item.glyph;
-    }
-  }
+    // No glyph has been found. Create one.
+    EllipsisItem item;
 
-  // No glyph has been found. Create one.
-  mEllipsisCache.PushBack(EllipsisItem());
-  EllipsisItem& item = *(mEllipsisCache.End() - 1u);
+    item.requestedPointSize = requestedPointSize;
+    item.index              = ellipsisCacheIndex;
 
-  item.requestedPointSize = requestedPointSize;
+    // Find a font for the ellipsis glyph.
+    item.glyph.fontId = FindDefaultFont(ELLIPSIS_CHARACTER,
+                                        requestedPointSize,
+                                        false);
 
-  // Find a font for the ellipsis glyph.
-  item.glyph.fontId = FindDefaultFont(ELLIPSIS_CHARACTER,
-                                      requestedPointSize,
-                                      false);
+    // Set the character index to access the glyph inside the font.
+    item.glyph.index = GetGlyphIndex(item.glyph.fontId, ELLIPSIS_CHARACTER);
 
-  // Set the character index to access the glyph inside the font.
-  item.glyph.index = FT_Get_Char_Index(mFontFaceCache[mFontIdCache[item.glyph.fontId - 1u].id].mFreeTypeFace,
-                                       ELLIPSIS_CHARACTER);
+    // Get glyph informations.
+    GetBitmapMetrics(&item.glyph, 1u, true);
 
-  GetBitmapMetrics(&item.glyph, 1u, true);
+    DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  glyph id %d found in the cache.\n", item.glyph.index);
+    DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "      font %d.\n", item.glyph.fontId);
 
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  glyph id %d found in the cache.\n", item.glyph.index);
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "      font %d.\n", item.glyph.fontId);
-  return item.glyph;
+    ellipsisCacheIndex = mCacheHandler->CacheEllipsis(std::move(item));
+  }
+  return mCacheHandler->mEllipsisCache[ellipsisCacheIndex].glyph;
 }
 
-bool FontClient::Plugin::IsColorGlyph(FontId fontId, GlyphIndex glyphIndex)
+bool FontClient::Plugin::IsColorGlyph(FontId fontId, GlyphIndex glyphIndex) const
 {
   const FontCacheItemInterface* fontCacheItem = GetCachedFontItem(fontId);
   return fontCacheItem && fontCacheItem->IsColorGlyph(glyphIndex);
 }
 
-FT_FaceRec_* FontClient::Plugin::GetFreetypeFace(FontId fontId)
+FT_FaceRec_* FontClient::Plugin::GetFreetypeFace(FontId fontId) const
 {
   const FontCacheItemInterface* fontCacheItem = GetCachedFontItem(fontId);
   if(fontCacheItem != nullptr)
@@ -1189,13 +895,12 @@ FT_FaceRec_* FontClient::Plugin::GetFreetypeFace(FontId fontId)
   return nullptr;
 }
 
-FontDescription::Type FontClient::Plugin::GetFontType(FontId fontId)
+FontDescription::Type FontClient::Plugin::GetFontType(FontId fontId) const
 {
   const FontId index = fontId - 1u;
-  if((fontId > 0u) &&
-     (index < mFontIdCache.Count()))
+  if((fontId > 0u) && (index < mCacheHandler->mFontIdCache.size()))
   {
-    return mFontIdCache[index].type;
+    return mCacheHandler->mFontIdCache[index].type;
   }
   return FontDescription::INVALID;
 }
@@ -1206,7 +911,17 @@ bool FontClient::Plugin::AddCustomFontDirectory(const FontPath& path)
   return FcConfigAppFontAddDir(nullptr, reinterpret_cast<const FcChar8*>(path.c_str()));
 }
 
-GlyphIndex FontClient::Plugin::CreateEmbeddedItem(const TextAbstraction::FontClient::EmbeddedItemDescription& description, Pixel::Format& pixelFormat)
+HarfBuzzFontHandle FontClient::Plugin::GetHarfBuzzFont(FontId fontId) const
+{
+  FontCacheItemInterface* fontCacheItem = const_cast<FontCacheItemInterface*>(GetCachedFontItem(fontId));
+  if(fontCacheItem != nullptr)
+  {
+    return fontCacheItem->GetHarfBuzzFont(mDpiHorizontal, mDpiVertical); // May cache
+  }
+  return nullptr;
+}
+
+GlyphIndex FontClient::Plugin::CreateEmbeddedItem(const TextAbstraction::FontClient::EmbeddedItemDescription& description, Pixel::Format& pixelFormat) const
 {
   EmbeddedItem embeddedItem;
 
@@ -1219,43 +934,17 @@ GlyphIndex FontClient::Plugin::CreateEmbeddedItem(const TextAbstraction::FontCli
   if(!description.url.empty())
   {
     // Check if the url is in the cache.
-    PixelBufferId index = 0u;
-
-    for(const auto& cacheItem : mPixelBufferCache)
-    {
-      ++index;
-      if(cacheItem.url == description.url)
-      {
-        // The url is in the pixel buffer cache.
-        // Set the index +1 to the vector.
-        embeddedItem.pixelBufferId = index;
-        break;
-      }
-    }
-
     Devel::PixelBuffer pixelBuffer;
-    if(0u == embeddedItem.pixelBufferId)
+    if(!mCacheHandler->FindEmbeddedPixelBufferId(description.url, embeddedItem.pixelBufferId))
     {
       // The pixel buffer is not in the cache. Create one and cache it.
-
-      // Load the image from the url.
-      pixelBuffer = LoadImageFromFile(description.url);
-
-      // Create the cache item.
-      PixelBufferCacheItem pixelBufferCacheItem;
-      pixelBufferCacheItem.pixelBuffer = pixelBuffer;
-      pixelBufferCacheItem.url         = description.url;
-
-      // Store the cache item in the cache.
-      mPixelBufferCache.push_back(std::move(pixelBufferCacheItem));
-
-      // Set the pixel buffer id to the embedded item.
-      embeddedItem.pixelBufferId = mPixelBufferCache.size();
+      embeddedItem.pixelBufferId = mCacheHandler->CacheEmbeddedPixelBuffer(description.url);
     }
-    else
+
+    if((embeddedItem.pixelBufferId > 0u) && (embeddedItem.pixelBufferId - 1u) < mCacheHandler->mPixelBufferCache.size())
     {
       // Retrieve the pixel buffer from the cache to set the pixel format.
-      pixelBuffer = mPixelBufferCache[embeddedItem.pixelBufferId - 1u].pixelBuffer;
+      pixelBuffer = mCacheHandler->mPixelBufferCache[embeddedItem.pixelBufferId - 1u].pixelBuffer;
     }
 
     if(pixelBuffer)
@@ -1277,22 +966,12 @@ GlyphIndex FontClient::Plugin::CreateEmbeddedItem(const TextAbstraction::FontCli
   }
 
   // Find if the same embeddedItem has already been created.
-  unsigned int index = 0u;
-  for(const auto& item : mEmbeddedItemCache)
+  GlyphIndex index = 0u;
+  if(!mCacheHandler->FindEmbeddedItem(embeddedItem.pixelBufferId, embeddedItem.width, embeddedItem.height, index))
   {
-    ++index;
-    if((item.pixelBufferId == embeddedItem.pixelBufferId) &&
-       (item.width == embeddedItem.width) &&
-       (item.height == embeddedItem.height))
-    {
-      return index;
-    }
+    index = mCacheHandler->CacheEmbeddedItem(std::move(embeddedItem));
   }
-
-  // Cache the embedded item.
-  mEmbeddedItemCache.PushBack(embeddedItem);
-
-  return mEmbeddedItemCache.Count();
+  return index;
 }
 
 void FontClient::Plugin::EnableAtlasLimitation(bool enabled)
@@ -1341,165 +1020,24 @@ uint32_t FontClient::Plugin::GetNumberOfPointsPerOneUnitOfPointSize() const
   ;
 }
 
-void FontClient::Plugin::InitSystemFonts()
-{
-  DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
-
-  FcFontSet* fontSet = GetFcFontSet(); // Creates a FcFontSet that needs to be destroyed by calling FcFontSetDestroy.
-
-  if(fontSet)
-  {
-    DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  number of system fonts : %d\n", fontSet->nfont);
-
-    // Reserve some space to avoid reallocations.
-    mSystemFonts.reserve(fontSet->nfont);
-
-    for(int i = 0u; i < fontSet->nfont; ++i)
-    {
-      FcPattern* fontPattern = fontSet->fonts[i];
-
-      FontPath path;
-
-      // Skip fonts with no path
-      if(GetFcString(fontPattern, FC_FILE, path))
-      {
-        mSystemFonts.push_back(FontDescription());
-        FontDescription& fontDescription = mSystemFonts.back();
-
-        fontDescription.path = std::move(path);
-
-        int width  = 0;
-        int weight = 0;
-        int slant  = 0;
-        GetFcString(fontPattern, FC_FAMILY, fontDescription.family);
-        GetFcInt(fontPattern, FC_WIDTH, width);
-        GetFcInt(fontPattern, FC_WEIGHT, weight);
-        GetFcInt(fontPattern, FC_SLANT, slant);
-        fontDescription.width  = IntToWidthType(width);
-        fontDescription.weight = IntToWeightType(weight);
-        fontDescription.slant  = IntToSlantType(slant);
-
-        FONT_LOG_DESCRIPTION(fontDescription, "");
-      }
-    }
-
-    // Destroys the font set created.
-    FcFontSetDestroy(fontSet);
-  }
-}
-
-bool FontClient::Plugin::MatchFontDescriptionToPattern(FcPattern* pattern, Dali::TextAbstraction::FontDescription& fontDescription, FcCharSet** characterSet)
-{
-  DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
-
-  FcResult   result = FcResultMatch;
-  FcPattern* match  = FcFontMatch(nullptr /* use default configure */, pattern, &result); // Creates a new font pattern that needs to be destroyed by calling FcPatternDestroy.
-
-  const bool matched = nullptr != match;
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  pattern matched : %s\n", (matched ? "true" : "false"));
-
-  if(matched)
-  {
-    int width  = 0;
-    int weight = 0;
-    int slant  = 0;
-    GetFcString(match, FC_FILE, fontDescription.path);
-    GetFcString(match, FC_FAMILY, fontDescription.family);
-    GetFcInt(match, FC_WIDTH, width);
-    GetFcInt(match, FC_WEIGHT, weight);
-    GetFcInt(match, FC_SLANT, slant);
-    fontDescription.width  = IntToWidthType(width);
-    fontDescription.weight = IntToWeightType(weight);
-    fontDescription.slant  = IntToSlantType(slant);
-
-    // Retrieve the character set and increase the reference counter.
-    FcPatternGetCharSet(match, FC_CHARSET, 0u, characterSet);
-    *characterSet = FcCharSetCopy(*characterSet);
-
-    // destroyed the matched pattern
-    FcPatternDestroy(match);
-    FONT_LOG_DESCRIPTION(fontDescription, "");
-  }
-  return matched;
-}
-
-_FcFontSet* FontClient::Plugin::GetFcFontSet() const
-{
-  FcFontSet* fontset = nullptr;
-
-  // create a new pattern.
-  // a pattern holds a set of names, each name refers to a property of the font
-  FcPattern* pattern = FcPatternCreate();
-
-  if(nullptr != pattern)
-  {
-    // create an object set used to define which properties are to be returned in the patterns from FcFontList.
-    FcObjectSet* objectSet = FcObjectSetCreate();
-
-    if(nullptr != objectSet)
-    {
-      // build an object set from a list of property names
-      FcObjectSetAdd(objectSet, FC_FILE);
-      FcObjectSetAdd(objectSet, FC_FAMILY);
-      FcObjectSetAdd(objectSet, FC_WIDTH);
-      FcObjectSetAdd(objectSet, FC_WEIGHT);
-      FcObjectSetAdd(objectSet, FC_SLANT);
-
-      // get a list of fonts
-      // creates patterns from those fonts containing only the objects in objectSet and returns the set of unique such patterns
-      fontset = FcFontList(nullptr /* the default configuration is checked to be up to date, and used */, pattern, objectSet); // Creates a FcFontSet that needs to be destroyed by calling FcFontSetDestroy.
-
-      // clear up the object set
-      FcObjectSetDestroy(objectSet);
-    }
-
-    // clear up the pattern
-    FcPatternDestroy(pattern);
-  }
-
-  return fontset;
-}
-
-bool FontClient::Plugin::GetFcString(const FcPattern* const pattern,
-                                     const char* const      n,
-                                     std::string&           string)
-{
-  FcChar8*       file   = nullptr;
-  const FcResult retVal = FcPatternGetString(pattern, n, 0u, &file);
-
-  if(FcResultMatch == retVal)
-  {
-    // Have to use reinterpret_cast because FcChar8 is unsigned char*, not a const char*.
-    string.assign(reinterpret_cast<const char*>(file));
-
-    return true;
-  }
-
-  return false;
-}
-
-bool FontClient::Plugin::GetFcInt(const _FcPattern* const pattern, const char* const n, int& intVal)
-{
-  const FcResult retVal = FcPatternGetInteger(pattern, n, 0u, &intVal);
-
-  if(FcResultMatch == retVal)
-  {
-    return true;
-  }
-
-  return false;
-}
-
 FontId FontClient::Plugin::CreateFont(const FontPath& path,
                                       PointSize26Dot6 requestedPointSize,
                                       FaceIndex       faceIndex,
-                                      bool            cacheDescription)
+                                      bool            cacheDescription) const
 {
   DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
   DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "                path : [%s]\n", path.c_str());
   DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  requestedPointSize : %d\n", requestedPointSize);
 
-  FontId id = 0u;
+  DALI_TRACE_SCOPE(gTraceFilter, "DALI_TEXT_CREATE_FONT");
+  FontId fontId = 0u;
+
+  #if defined(TRACE_ENABLED)
+  if(gTraceFilter && gTraceFilter->IsTraceEnabled())
+  {
+    DALI_LOG_DEBUG_INFO("DALI_TEXT_CREATE_FONT : FT_New_Face : %s\n", path.c_str());
+  }
+  #endif
 
   // Create & cache new font face
   FT_Face ftFace;
@@ -1514,7 +1052,6 @@ FontId FontClient::Plugin::CreateFont(const FontPath& path,
     const bool isScalable           = (0 != (ftFace->face_flags & FT_FACE_FLAG_SCALABLE));
     const bool hasFixedSizedBitmaps = (0 != (ftFace->face_flags & FT_FACE_FLAG_FIXED_SIZES)) && (0 != ftFace->num_fixed_sizes);
     const bool hasColorTables       = (0 != (ftFace->face_flags & FT_FACE_FLAG_COLOR));
-    FontId     fontFaceId           = 0u;
 
     DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "            isScalable : [%s]\n", (isScalable ? "true" : "false"));
     DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  hasFixedSizedBitmaps : [%s]\n", (hasFixedSizedBitmaps ? "true" : "false"));
@@ -1527,7 +1064,7 @@ FontId FontClient::Plugin::CreateFont(const FontPath& path,
       int             fixedSizeIndex  = 0;
       for(; fixedSizeIndex < ftFace->num_fixed_sizes; ++fixedSizeIndex)
       {
-        const PointSize26Dot6 fixedSize = ftFace->available_sizes[fixedSizeIndex].size;
+        const PointSize26Dot6 fixedSize = static_cast<PointSize26Dot6>(ftFace->available_sizes[fixedSizeIndex].size);
         DALI_LOG_INFO(gFontClientLogFilter, Debug::Verbose, "  size index : %d, size : %d\n", fixedSizeIndex, fixedSize);
 
         if(fixedSize >= requestedPointSize)
@@ -1541,7 +1078,7 @@ FontId FontClient::Plugin::CreateFont(const FontPath& path,
       {
         // The requested point size is bigger than the bigest fixed size.
         fixedSizeIndex  = ftFace->num_fixed_sizes - 1;
-        actualPointSize = ftFace->available_sizes[fixedSizeIndex].size;
+        actualPointSize = static_cast<PointSize26Dot6>(ftFace->available_sizes[fixedSizeIndex].size);
       }
 
       DALI_LOG_INFO(gFontClientLogFilter, Debug::Verbose, "  size index : %d, actual size : %d\n", fixedSizeIndex, actualPointSize);
@@ -1554,36 +1091,21 @@ FontId FontClient::Plugin::CreateFont(const FontPath& path,
       }
       else
       {
+        FT_Size_Metrics& ftMetrics = ftFace->size->metrics;
+
+        FontMetrics metrics(static_cast<float>(ftMetrics.ascender) * FROM_266,
+                            static_cast<float>(ftMetrics.descender) * FROM_266,
+                            static_cast<float>(ftMetrics.height) * FROM_266,
+                            static_cast<float>(ftFace->underline_position) * FROM_266,
+                            static_cast<float>(ftFace->underline_thickness) * FROM_266);
+
         const float fixedWidth  = static_cast<float>(ftFace->available_sizes[fixedSizeIndex].width);
         const float fixedHeight = static_cast<float>(ftFace->available_sizes[fixedSizeIndex].height);
 
-        // Indicate that the font is a fixed sized bitmap
-        FontMetrics metrics(fixedHeight, // The ascender in pixels.
-                            0.0f,
-                            fixedHeight, // The height in pixels.
-                            0.0f,
-                            0.0f);
-
         // Create the FreeType font face item to cache.
-        FontFaceCacheItem fontFaceCacheItem(mFreeTypeLibrary, ftFace, path, requestedPointSize, faceIndex, metrics, fixedSizeIndex, fixedWidth, fixedHeight, hasColorTables);
-
-        // Set the index to the font's id cache.
-        fontFaceCacheItem.mFontId = mFontIdCache.Count();
-
-        // Create the font id item to cache.
-        FontIdCacheItem fontIdCacheItem;
-        fontIdCacheItem.type = FontDescription::FACE_FONT;
+        FontFaceCacheItem fontFaceCacheItem(mFreeTypeLibrary, ftFace, mCacheHandler->GetGlyphCacheManager(), path, requestedPointSize, faceIndex, metrics, fixedSizeIndex, fixedWidth, fixedHeight, hasColorTables);
 
-        // Set the index to the FreeType font face cache.
-        fontIdCacheItem.id = mFontFaceCache.size();
-        fontFaceId         = fontIdCacheItem.id + 1u;
-
-        // Cache the items.
-        mFontFaceCache.push_back(fontFaceCacheItem);
-        mFontIdCache.PushBack(fontIdCacheItem);
-
-        // Set the font id to be returned.
-        id = mFontIdCache.Count();
+        fontId = mCacheHandler->CacheFontFaceCacheItem(std::move(fontFaceCacheItem));
       }
     }
     else
@@ -1623,25 +1145,9 @@ FontId FontClient::Plugin::CreateFont(const FontPath& path,
                             static_cast<float>(ftFace->underline_thickness) * FROM_266);
 
         // Create the FreeType font face item to cache.
-        FontFaceCacheItem fontFaceCacheItem(mFreeTypeLibrary, ftFace, path, requestedPointSize, faceIndex, metrics);
-
-        // Set the index to the font's id cache.
-        fontFaceCacheItem.mFontId = mFontIdCache.Count();
+        FontFaceCacheItem fontFaceCacheItem(mFreeTypeLibrary, ftFace, mCacheHandler->GetGlyphCacheManager(), path, requestedPointSize, faceIndex, metrics);
 
-        // Create the font id item to cache.
-        FontIdCacheItem fontIdCacheItem;
-        fontIdCacheItem.type = FontDescription::FACE_FONT;
-
-        // Set the index to the FreeType font face cache.
-        fontIdCacheItem.id = mFontFaceCache.size();
-        fontFaceId         = fontIdCacheItem.id + 1u;
-
-        // Cache the items.
-        mFontFaceCache.push_back(fontFaceCacheItem);
-        mFontIdCache.PushBack(fontIdCacheItem);
-
-        // Set the font id to be returned.
-        id = mFontIdCache.Count();
+        fontId = mCacheHandler->CacheFontFaceCacheItem(std::move(fontFaceCacheItem));
       }
       else
       {
@@ -1649,11 +1155,12 @@ FontId FontClient::Plugin::CreateFont(const FontPath& path,
       }
     }
 
-    if(0u != fontFaceId)
+    if(0u != fontId)
     {
       if(cacheDescription)
       {
-        CacheFontPath(ftFace, fontFaceId, requestedPointSize, path);
+        DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  Cache Font Path at font id : %d [%s]\n", fontId, path.c_str());
+        mCacheHandler->CacheFontPath(ftFace, fontId, requestedPointSize, path);
       }
     }
   }
@@ -1662,144 +1169,16 @@ FontId FontClient::Plugin::CreateFont(const FontPath& path,
     DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  FreeType New_Face error: %d for [%s]\n", error, path.c_str());
   }
 
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  font id : %d\n", id);
-  return id;
-}
-
-bool FontClient::Plugin::FindFont(const FontPath& path,
-                                  PointSize26Dot6 requestedPointSize,
-                                  FaceIndex       faceIndex,
-                                  FontId&         fontId) const
-{
-  DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "                path : [%s]\n", path.c_str());
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  requestedPointSize : %d\n", requestedPointSize);
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::Verbose, "  number of fonts in the cache : %d\n", mFontFaceCache.size());
-
-  fontId = 0u;
-  for(const auto& cacheItem : mFontFaceCache)
-  {
-    if(cacheItem.mRequestedPointSize == requestedPointSize &&
-       cacheItem.mFaceIndex == faceIndex &&
-       cacheItem.mPath == path)
-    {
-      fontId = cacheItem.mFontId + 1u;
-
-      DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  font found, id : %d\n", fontId);
-      return true;
-    }
-  }
-
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  font not found\n");
-  return false;
-}
-
-bool FontClient::Plugin::FindValidatedFont(const FontDescription& fontDescription,
-                                           FontDescriptionId&     validatedFontId)
-{
-  DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
-  FONT_LOG_DESCRIPTION(fontDescription, "");
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::Verbose, "  number of validated fonts in the cache : %d\n", mValidatedFontCache.size());
-
-  validatedFontId = 0u;
-
-  for(const auto& item : mValidatedFontCache)
-  {
-    if(!fontDescription.family.empty() &&
-       (fontDescription.family == item.fontDescription.family) &&
-       (fontDescription.width == item.fontDescription.width) &&
-       (fontDescription.weight == item.fontDescription.weight) &&
-       (fontDescription.slant == item.fontDescription.slant))
-    {
-      validatedFontId = item.index;
-
-      DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  validated font found, id : %d\n", validatedFontId);
-      return true;
-    }
-  }
-
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  validated font not found\n");
-  return false;
-}
-
-bool FontClient::Plugin::FindFallbackFontList(const FontDescription& fontDescription,
-                                              FontList*&             fontList,
-                                              CharacterSetList*&     characterSetList)
-{
-  DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
-  FONT_LOG_DESCRIPTION(fontDescription, "");
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::Verbose, "  number of fallback font lists in the cache : %d\n", mFallbackCache.size());
-
-  fontList = nullptr;
-
-  for(const auto& item : mFallbackCache)
-  {
-    if(!fontDescription.family.empty() &&
-       (fontDescription.family == item.fontDescription.family) &&
-       (fontDescription.width == item.fontDescription.width) &&
-       (fontDescription.weight == item.fontDescription.weight) &&
-       (fontDescription.slant == item.fontDescription.slant))
-    {
-      fontList         = item.fallbackFonts;
-      characterSetList = item.characterSets;
-
-      DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  fallback font list found.\n");
-      return true;
-    }
-  }
-
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  fallback font list not found.\n");
-  return false;
-}
-
-bool FontClient::Plugin::FindFont(FontDescriptionId validatedFontId,
-                                  PointSize26Dot6   requestedPointSize,
-                                  FontId&           fontId)
-{
-  DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "    validatedFontId  : %d\n", validatedFontId);
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  requestedPointSize : %d\n", requestedPointSize);
-
-  fontId = 0u;
-
-  for(const auto& item : mFontDescriptionSizeCache)
-  {
-    if((validatedFontId == item.validatedFontId) &&
-       (requestedPointSize == item.requestedPointSize))
-    {
-      fontId = item.fontId;
-
-      DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  font found, id : %d\n", fontId);
-      return true;
-    }
-  }
-
-  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  font not found.\n");
-  return false;
-}
-
-bool FontClient::Plugin::FindBitmapFont(const FontFamily& bitmapFont, FontId& fontId) const
-{
-  fontId = 0u;
-
-  for(const auto& item : mBitmapFontCache)
-  {
-    if(bitmapFont == item.font.name)
-    {
-      fontId = item.id + 1u;
-      return true;
-    }
-  }
-
-  return false;
+  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  font id : %d\n", fontId);
+  return fontId;
 }
 
-bool FontClient::Plugin::IsScalable(const FontPath& path)
+bool FontClient::Plugin::IsScalable(const FontPath& path) const
 {
   bool isScalable = false;
 
-  FT_Face ftFace;
-  int     error = FT_New_Face(mFreeTypeLibrary,
+  FT_Face ftFace = nullptr;
+  int     error  = FT_New_Face(mFreeTypeLibrary,
                           path.c_str(),
                           0,
                           &ftFace);
@@ -1812,10 +1191,15 @@ bool FontClient::Plugin::IsScalable(const FontPath& path)
     isScalable = ftFace->face_flags & FT_FACE_FLAG_SCALABLE;
   }
 
+  if(ftFace)
+  {
+    FT_Done_Face(ftFace);
+  }
+
   return isScalable;
 }
 
-bool FontClient::Plugin::IsScalable(const FontDescription& fontDescription)
+bool FontClient::Plugin::IsScalable(const FontDescription& fontDescription) const
 {
   // Create a font pattern.
   FcPattern* fontFamilyPattern = CreateFontFamilyPattern(fontDescription); // Creates a font pattern that needs to be destroyed by calling FcPatternDestroy.
@@ -1845,13 +1229,13 @@ bool FontClient::Plugin::IsScalable(const FontDescription& fontDescription)
   return isScalable;
 }
 
-void FontClient::Plugin::GetFixedSizes(const FontPath& path, Vector<PointSize26Dot6>& sizes)
+void FontClient::Plugin::GetFixedSizes(const FontPath& path, Vector<PointSize26Dot6>& sizes) const
 {
   // Empty the caller container
   sizes.Clear();
 
-  FT_Face ftFace;
-  int     error = FT_New_Face(mFreeTypeLibrary,
+  FT_Face ftFace = nullptr;
+  int     error  = FT_New_Face(mFreeTypeLibrary,
                           path.c_str(),
                           0,
                           &ftFace);
@@ -1860,18 +1244,23 @@ void FontClient::Plugin::GetFixedSizes(const FontPath& path, Vector<PointSize26D
     DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "FontClient::Plugin::GetFixedSizes. FreeType Cannot check font path : [%s]\n", path.c_str());
   }
 
-  // Fetch the number of fixed sizes available
-  if(ftFace->num_fixed_sizes && ftFace->available_sizes)
+  if(ftFace)
   {
-    for(int i = 0; i < ftFace->num_fixed_sizes; ++i)
+    // Fetch the number of fixed sizes available
+    if(ftFace->num_fixed_sizes && ftFace->available_sizes)
     {
-      sizes.PushBack(ftFace->available_sizes[i].size);
+      for(int i = 0; i < ftFace->num_fixed_sizes; ++i)
+      {
+        sizes.PushBack(ftFace->available_sizes[i].size);
+      }
     }
+
+    FT_Done_Face(ftFace);
   }
 }
 
 void FontClient::Plugin::GetFixedSizes(const FontDescription&   fontDescription,
-                                       Vector<PointSize26Dot6>& sizes)
+                                       Vector<PointSize26Dot6>& sizes) const
 {
   // Create a font pattern.
   FcPattern* fontFamilyPattern = CreateFontFamilyPattern(fontDescription); // Creates a font pattern that needs to be destroyed by calling FcPatternDestroy.
@@ -1908,90 +1297,4 @@ bool FontClient::Plugin::HasItalicStyle(FontId fontId) const
   return false;
 }
 
-void FontClient::Plugin::CacheFontPath(FT_Face ftFace, FontId id, PointSize26Dot6 requestedPointSize, const FontPath& path)
-{
-  FontDescription description;
-  description.path   = path;
-  description.family = std::move(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))
-  {
-    FcPattern* pattern = CreateFontFamilyPattern(description); // Creates a new pattern that needs to be destroyed by calling FcPatternDestroy.
-
-    FcResult   result = FcResultMatch;
-    FcPattern* match  = FcFontMatch(nullptr, pattern, &result); // FcFontMatch creates a new pattern that needs to be destroyed by calling FcPatternDestroy.
-
-    FcCharSet* characterSet = nullptr;
-    FcPatternGetCharSet(match, FC_CHARSET, 0u, &characterSet);
-
-    const FontId fontFaceId                  = id - 1u;
-    mFontFaceCache[fontFaceId].mCharacterSet = FcCharSetCopy(characterSet); // Increases the reference counter.
-
-    // Destroys the created patterns.
-    FcPatternDestroy(match);
-    FcPatternDestroy(pattern);
-
-    // Add the path to the cache.
-    description.type = FontDescription::FACE_FONT;
-    mFontDescriptionCache.push_back(description);
-
-    // Set the index to the vector of paths to font file names.
-    validatedFontId = mFontDescriptionCache.size();
-
-    // Increase the reference counter and add the character set to the cache.
-    mCharacterSetCache.PushBack(FcCharSetCopy(characterSet));
-
-    // Cache the index and the font's description.
-    mValidatedFontCache.push_back(std::move(FontDescriptionCacheItem(std::move(description),
-                                                                     validatedFontId)));
-
-    // Cache the pair 'validatedFontId, requestedPointSize' to improve the following queries.
-    mFontDescriptionSizeCache.push_back(FontDescriptionSizeCacheItem(validatedFontId,
-                                                                     requestedPointSize,
-                                                                     fontFaceId));
-  }
-}
-
-void FontClient::Plugin::ClearFallbackCache(std::vector<FallbackCacheItem>& fallbackCache)
-{
-  for(auto& item : fallbackCache)
-  {
-    if(nullptr != item.fallbackFonts)
-    {
-      delete item.fallbackFonts;
-    }
-
-    if(nullptr != item.characterSets)
-    {
-      // Free the resources allocated by the FcCharSet objects in the 'characterSets' vector.
-      DestroyCharacterSets(*item.characterSets);
-      delete item.characterSets;
-    }
-  }
-}
-
-void FontClient::Plugin::ClearCharacterSetFromFontFaceCache()
-{
-  for(auto& item : mFontFaceCache)
-  {
-    FcCharSetDestroy(item.mCharacterSet);
-    item.mCharacterSet = nullptr;
-  }
-}
-
 } // namespace Dali::TextAbstraction::Internal