Add support for FontClientFontPreLoad API
[platform/core/uifw/dali-adaptor.git] / dali / devel-api / text-abstraction / font-client.cpp
index 747ce2d..5d9f175 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
 #include <dali/devel-api/text-abstraction/font-client.h>
 
 // INTERNAL INCLUDES
-#include <dali/internal/imaging/common/image-operations.h>
 #include <dali/internal/text/text-abstraction/font-client-impl.h>
 
 namespace Dali
 {
 namespace TextAbstraction
 {
+// FontClient static const value definition.
+
 const PointSize26Dot6 FontClient::DEFAULT_POINT_SIZE   = 768u;                           // 12*64
 const float           FontClient::DEFAULT_ITALIC_ANGLE = 12.f * Dali::Math::PI_OVER_180; // FreeType documentation states the software italic is done by doing a horizontal shear of 12 degrees (file ftsynth.h).
 
@@ -49,534 +50,6 @@ const Size FontClient::MAX_SIZE_FIT_IN_ATLAS(MAX_TEXT_ATLAS_WIDTH - PADDING_TEXT
 
 const uint32_t FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE = 64u; //Found this value from toolkit
 
-// FontClient::GlyphBufferData
-
-FontClient::GlyphBufferData::GlyphBufferData()
-: buffer{nullptr},
-  width{0u},
-  height{0u},
-  outlineOffsetX{0},
-  outlineOffsetY{0},
-  format{Pixel::A8},
-  compressType(CompressType::NO_COMPRESS),
-  isColorEmoji{false},
-  isColorBitmap{false},
-  isBufferOwned{false}
-{
-}
-
-FontClient::GlyphBufferData::~GlyphBufferData()
-{
-  if(isBufferOwned)
-  {
-    free(buffer);
-  }
-}
-
-size_t FontClient::GlyphBufferData::Compress(const uint8_t* const __restrict__ inBuffer, GlyphBufferData& __restrict__ outBufferData)
-{
-  size_t bufferSize                       = 0u;
-  uint8_t*& __restrict__ compressedBuffer = outBufferData.buffer;
-  switch(outBufferData.compressType)
-  {
-    case TextAbstraction::FontClient::GlyphBufferData::CompressType::NO_COMPRESS:
-    {
-      bufferSize = outBufferData.width * outBufferData.height * Pixel::GetBytesPerPixel(outBufferData.format);
-
-      compressedBuffer = (uint8_t*)malloc(bufferSize);
-      if(DALI_UNLIKELY(compressedBuffer == nullptr))
-      {
-        return 0u;
-      }
-      outBufferData.isBufferOwned = true;
-
-      // Copy buffer without compress
-      memcpy(compressedBuffer, inBuffer, bufferSize);
-      break;
-    }
-    case TextAbstraction::FontClient::GlyphBufferData::CompressType::BIT_PER_PIXEL_4:
-    {
-      const uint32_t widthByte       = outBufferData.width * Pixel::GetBytesPerPixel(outBufferData.format);
-      const uint32_t componentCount  = (widthByte >> 1);
-      const bool     considerPadding = (widthByte & 1) ? true : false;
-
-      // For BIT_PER_PIXEL_4 type, we can know final compressed buffer size immediatly.
-      bufferSize       = outBufferData.height * (componentCount + (considerPadding ? 1 : 0));
-      compressedBuffer = (uint8_t*)malloc(bufferSize);
-      if(DALI_UNLIKELY(compressedBuffer == nullptr))
-      {
-        return 0u;
-      }
-      outBufferData.isBufferOwned = true;
-
-      uint8_t* __restrict__ outBufferPtr      = compressedBuffer;
-      const uint8_t* __restrict__ inBufferPtr = inBuffer;
-
-      // Compress for each line
-      for(uint32_t y = 0; y < outBufferData.height; ++y)
-      {
-        for(uint32_t x = 0; x < componentCount; ++x)
-        {
-          const uint8_t v0 = Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++));
-          const uint8_t v1 = Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++));
-
-          *(outBufferPtr++) = (v0 << 4) | v1;
-        }
-        if(considerPadding)
-        {
-          *(outBufferPtr++) = Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++));
-        }
-      }
-      break;
-    }
-    case TextAbstraction::FontClient::GlyphBufferData::CompressType::COMPRESS_RLE4:
-    {
-      const uint32_t widthByte = outBufferData.width * Pixel::GetBytesPerPixel(outBufferData.format);
-
-      // Allocate temperal buffer. Note that RLE4 can be bigger than original buffer.
-      uint8_t* __restrict__ tempBuffer = (uint8_t*)malloc(outBufferData.height * (widthByte + 1));
-      if(DALI_UNLIKELY(tempBuffer == nullptr))
-      {
-        return 0u;
-      }
-
-      uint8_t* __restrict__ outBufferPtr      = tempBuffer;
-      const uint8_t* __restrict__ inBufferPtr = inBuffer;
-
-      bufferSize = 0u;
-
-      // Compress for each line
-      for(uint32_t y = 0; y < outBufferData.height; ++y)
-      {
-        uint32_t encodedByte = 0;
-        while(encodedByte < widthByte)
-        {
-          // Case 1 : Remain only 1 byte
-          if(DALI_UNLIKELY(encodedByte + 1 == widthByte))
-          {
-            const uint8_t prev0 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
-            const uint8_t v0    = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev0) & 0x0f; // Intented underflow
-            *(outBufferPtr++)   = v0;
-            ++encodedByte;
-            ++bufferSize;
-          }
-          // Case 2 : Remain only 2 byte
-          else if(DALI_UNLIKELY(encodedByte + 2 == widthByte))
-          {
-            const uint8_t prev0 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
-            const uint8_t v0    = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev0) & 0x0f; // Intented underflow
-            const uint8_t prev1 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
-            const uint8_t v1    = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev1) & 0x0f; // Intented underflow
-            encodedByte += 2;
-            if(v0 == v1)
-            {
-              *(outBufferPtr++) = 0x80 | v0;
-              ++bufferSize;
-            }
-            else
-            {
-              *(outBufferPtr++) = 0x10 | v0;
-              *(outBufferPtr++) = v1 << 4;
-              bufferSize += 2;
-            }
-          }
-          // Case 3 : Normal case. Remain byte bigger or equal than 3.
-          else
-          {
-            // Compress rule -
-            // Read 2 byte as v0 and v1.
-            // - If v0 == v1, We can compress. mark the first bit as 1. and remain 3 bit mark as the "runLength - 2".
-            //   runLength can be maximum 9.
-            // - If v0 != v1, We cannot compress. mark the first bit as 0. and remain 3 bit mark as the "(nonRunLength - 1) / 2"
-            //   Due to the BitPerPixel is 4, nonRunLength should be odd value.
-            //   nonRunLength cutted if v0 == v1.
-            //   nonRunLength can be maximum 15.
-
-            const uint8_t prev0 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
-            const uint8_t v0    = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev0) & 0x0f; // Intented underflow
-            const uint8_t prev1 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
-            const uint8_t v1    = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev1) & 0x0f; // Intented underflow
-            encodedByte += 2;
-            // We can compress by RLE
-            if(v0 == v1)
-            {
-              uint8_t runLength = 2;
-              while(encodedByte < widthByte && runLength < 9)
-              {
-                const uint8_t prev2 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
-                const uint8_t v2    = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr)) - prev2) & 0x0f; // Intented underflow
-                if(v2 == v0)
-                {
-                  ++inBufferPtr;
-                  ++encodedByte;
-                  ++runLength;
-                }
-                else
-                {
-                  break;
-                }
-              }
-
-              // Update (runLength - 2) result.
-              *(outBufferPtr++) = ((0x8 | (runLength - 2)) << 4) | v0;
-              ++bufferSize;
-            }
-            // We cannot compress by RLE.
-            else
-            {
-              // Read one more value.
-              const uint8_t prev2 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
-              const uint8_t v2    = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev2) & 0x0f; // Intented underflow
-              ++encodedByte;
-
-              uint8_t  nonRunLength          = 3;
-              uint8_t* nonRunLengthHeaderPtr = outBufferPtr;
-              *(outBufferPtr++)              = v0;
-              *(outBufferPtr++)              = (v1 << 4) | v2;
-              bufferSize += 2;
-              while(encodedByte < widthByte && nonRunLength < 15)
-              {
-                if(DALI_LIKELY(encodedByte + 1 < widthByte))
-                {
-                  const uint8_t prew0 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
-                  const uint8_t w0    = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr)) - prew0) & 0x0f; // Intented underflow
-                  const uint8_t prew1 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr + 1 - widthByte));
-                  const uint8_t w1    = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr + 1)) - prew1) & 0x0f; // Intented underflow
-                  if(w0 == w1)
-                  {
-                    // Stop non-compress logic.
-                    break;
-                  }
-                  else
-                  {
-                    ++bufferSize;
-                    *(outBufferPtr++) = (w0 << 4) | w1;
-                    inBufferPtr += 2;
-                    encodedByte += 2;
-                    nonRunLength += 2;
-                  }
-                }
-                else
-                {
-                  // Edge case. There is only one pixel remained.
-                  const uint8_t prew0 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
-                  const uint8_t w0    = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr)) - prew0) & 0x0f; // Intented underflow
-                  {
-                    ++bufferSize;
-                    *(outBufferPtr++) = (w0 << 4);
-                    ++encodedByte;
-                    ++inBufferPtr;
-                    // Increase nonRunLength 2 even latest value is invalid.
-                    nonRunLength += 2;
-                  }
-                }
-              }
-
-              // Update (nonRunLength-1)/2 result into header.
-              *(nonRunLengthHeaderPtr) |= (nonRunLength >> 1) << 4;
-            }
-          }
-        }
-      }
-
-      // Allocate and copy data
-      compressedBuffer = (uint8_t*)malloc(bufferSize);
-      if(DALI_UNLIKELY(compressedBuffer == nullptr))
-      {
-        free(tempBuffer);
-        return 0u;
-      }
-      outBufferData.isBufferOwned = true;
-
-      memcpy(compressedBuffer, tempBuffer, bufferSize);
-      free(tempBuffer);
-
-      break;
-    }
-    default:
-    {
-      break;
-    }
-  }
-
-  return bufferSize;
-}
-
-void FontClient::GlyphBufferData::Decompress(const GlyphBufferData& __restrict__ inBufferData, uint8_t* __restrict__ outBuffer)
-{
-  if(DALI_UNLIKELY(outBuffer == nullptr))
-  {
-    return;
-  }
-
-  switch(inBufferData.compressType)
-  {
-    case TextAbstraction::FontClient::GlyphBufferData::CompressType::NO_COMPRESS:
-    {
-      const auto bufferSize = inBufferData.width * inBufferData.height * Pixel::GetBytesPerPixel(inBufferData.format);
-
-      // Copy buffer without compress
-      memcpy(outBuffer, inBufferData.buffer, bufferSize);
-      break;
-    }
-    case TextAbstraction::FontClient::GlyphBufferData::CompressType::BIT_PER_PIXEL_4:
-    {
-      const uint32_t widthByte       = inBufferData.width * Pixel::GetBytesPerPixel(inBufferData.format);
-      const uint32_t componentCount  = (widthByte >> 1);
-      const bool     considerPadding = (widthByte & 1) ? true : false;
-
-      uint8_t* __restrict__ outBufferPtr      = outBuffer;
-      const uint8_t* __restrict__ inBufferPtr = inBufferData.buffer;
-
-      // Compress for each line
-      for(uint32_t y = 0; y < inBufferData.height; ++y)
-      {
-        for(uint32_t x = 0; x < componentCount; ++x)
-        {
-          const uint8_t v  = *(inBufferPtr++);
-          const uint8_t v0 = (v >> 4) & 0x0f;
-          const uint8_t v1 = v & 0x0f;
-
-          *(outBufferPtr++) = (v0 << 4) | v0;
-          *(outBufferPtr++) = (v1 << 4) | v1;
-        }
-        if(considerPadding)
-        {
-          const uint8_t v   = *(inBufferPtr++);
-          *(outBufferPtr++) = (v << 4) | v;
-        }
-      }
-      break;
-    }
-    case TextAbstraction::FontClient::GlyphBufferData::CompressType::COMPRESS_RLE4:
-    {
-      const uint32_t widthByte = inBufferData.width * Pixel::GetBytesPerPixel(inBufferData.format);
-
-      uint8_t* __restrict__ outBufferPtr      = outBuffer;
-      const uint8_t* __restrict__ inBufferPtr = inBufferData.buffer;
-      // Compress for each line
-      for(uint32_t y = 0; y < inBufferData.height; ++y)
-      {
-        uint32_t x           = 0;
-        uint32_t decodedByte = 0;
-        while(decodedByte < widthByte)
-        {
-          const uint8_t v = *(inBufferPtr++);
-          ++x;
-          // Compress by RLE
-          if(v & 0x80)
-          {
-            const uint8_t runLength = ((v >> 4) & 0x07) + 2u;
-            decodedByte += runLength;
-            const uint8_t repeatValue = v & 0x0f;
-            for(uint8_t iter = 0; iter < runLength; ++iter)
-            {
-              const uint8_t prev0 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte)) & 0x0f;
-              const uint8_t v0    = (prev0 + repeatValue) & 0x0f;
-              *(outBufferPtr++)   = (v0 << 4) | v0;
-            }
-          }
-          // Not compress by RLE
-          else
-          {
-            const uint8_t nonRunLength = (((v >> 4) & 0x07) << 1u) + 1u;
-            decodedByte += nonRunLength;
-            // First value.
-            const uint8_t prev0 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte)) & 0x0f;
-            const uint8_t v0    = (prev0 + (v & 0x0f)) & 0x0f;
-            *(outBufferPtr++)   = (v0 << 4) | v0;
-
-            const bool ignoreLastValue = decodedByte > widthByte ? true : false;
-            if(DALI_UNLIKELY(ignoreLastValue))
-            {
-              --decodedByte;
-              for(uint8_t iter = 1; iter + 2 < nonRunLength; iter += 2)
-              {
-                const uint8_t w     = *(inBufferPtr++);
-                const uint8_t prew0 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte)) & 0x0f;
-                const uint8_t w0    = (prew0 + ((w >> 4) & 0x0f)) & 0x0f;
-                const uint8_t prew1 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte + 1)) & 0x0f;
-                const uint8_t w1    = (prew1 + (w & 0x0f)) & 0x0f;
-                ++x;
-
-                *(outBufferPtr++) = (w0 << 4) | w0;
-                *(outBufferPtr++) = (w1 << 4) | w1;
-              }
-              // Last value.
-              {
-                const uint8_t w     = ((*(inBufferPtr++)) >> 4) & 0x0f;
-                const uint8_t prew0 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte)) & 0x0f;
-                const uint8_t w0    = (prew0 + w) & 0x0f;
-                ++x;
-
-                *(outBufferPtr++) = (w0 << 4) | w0;
-              }
-            }
-            else
-            {
-              for(uint8_t iter = 1; iter < nonRunLength; iter += 2)
-              {
-                const uint8_t w     = *(inBufferPtr++);
-                const uint8_t prew0 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte)) & 0x0f;
-                const uint8_t w0    = (prew0 + ((w >> 4) & 0x0f)) & 0x0f;
-                const uint8_t prew1 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte + 1)) & 0x0f;
-                const uint8_t w1    = (prew1 + (w & 0x0f)) & 0x0f;
-                ++x;
-
-                *(outBufferPtr++) = (w0 << 4) | w0;
-                *(outBufferPtr++) = (w1 << 4) | w1;
-              }
-            }
-          }
-        }
-      }
-      break;
-    }
-    default:
-    {
-      break;
-    }
-  }
-}
-
-void FontClient::GlyphBufferData::DecompressScanline(const GlyphBufferData& __restrict__ inBufferData, uint8_t* __restrict__ outBuffer, uint32_t& __restrict__ offset)
-{
-  switch(inBufferData.compressType)
-  {
-    case TextAbstraction::FontClient::GlyphBufferData::CompressType::NO_COMPRESS:
-    {
-      const auto bufferSize = inBufferData.width * Pixel::GetBytesPerPixel(inBufferData.format);
-
-      // Copy buffer without compress
-      memcpy(outBuffer, inBufferData.buffer + offset, bufferSize);
-
-      // Update offset
-      offset += bufferSize;
-      break;
-    }
-    case TextAbstraction::FontClient::GlyphBufferData::CompressType::BIT_PER_PIXEL_4:
-    {
-      const uint32_t widthByte       = inBufferData.width * Pixel::GetBytesPerPixel(inBufferData.format);
-      const uint32_t componentCount  = (widthByte >> 1);
-      const bool     considerPadding = (widthByte & 1) ? true : false;
-
-      uint8_t* __restrict__ outBufferPtr      = outBuffer;
-      const uint8_t* __restrict__ inBufferPtr = inBufferData.buffer + offset;
-
-      // Decompress scanline
-      for(uint32_t x = 0; x < componentCount; ++x)
-      {
-        const uint8_t v  = *(inBufferPtr++);
-        const uint8_t v0 = (v >> 4) & 0x0f;
-        const uint8_t v1 = v & 0x0f;
-
-        *(outBufferPtr++) = (v0 << 4) | v0;
-        *(outBufferPtr++) = (v1 << 4) | v1;
-      }
-      if(considerPadding)
-      {
-        const uint8_t v   = *(inBufferPtr++);
-        *(outBufferPtr++) = (v << 4) | v;
-      }
-
-      // Update offset
-      offset += (widthByte + 1u) >> 1u;
-      break;
-    }
-    case TextAbstraction::FontClient::GlyphBufferData::CompressType::COMPRESS_RLE4:
-    {
-      const uint32_t widthByte = inBufferData.width * Pixel::GetBytesPerPixel(inBufferData.format);
-
-      uint8_t* __restrict__ outBufferPtr      = outBuffer;
-      const uint8_t* __restrict__ inBufferPtr = inBufferData.buffer + offset;
-
-      // If offset is zero, fill outBuffer as 0 first.
-      if(DALI_UNLIKELY(offset == 0))
-      {
-        memset(outBufferPtr, 0, widthByte);
-      }
-
-      // Decompress scanline
-      uint32_t decodedByte = 0;
-      while(decodedByte < widthByte)
-      {
-        const uint8_t v = *(inBufferPtr++);
-        ++offset;
-        // Compress by RLE
-        if(v & 0x80)
-        {
-          const uint8_t runLength = ((v >> 4) & 0x07) + 2u;
-          decodedByte += runLength;
-          const uint8_t repeatValue = (v & 0x0f);
-          for(uint8_t iter = 0; iter < runLength; ++iter)
-          {
-            const uint8_t prev0 = (*(outBufferPtr)) & 0x0f;
-            const uint8_t v0    = (prev0 + repeatValue) & 0x0f;
-            *(outBufferPtr++)   = (v0 << 4) | v0;
-          }
-        }
-        // Not compress by RLE
-        else
-        {
-          const uint8_t nonRunLength = (((v >> 4) & 0x07) << 1u) + 1u;
-          decodedByte += nonRunLength;
-          // First value.
-          const uint8_t prev0 = (*(outBufferPtr)) & 0x0f;
-          const uint8_t v0    = (prev0 + (v & 0x0f)) & 0x0f;
-          *(outBufferPtr++)   = (v0 << 4) | v0;
-
-          const bool ignoreLastValue = decodedByte > widthByte ? true : false;
-          if(DALI_UNLIKELY(ignoreLastValue))
-          {
-            --decodedByte;
-            for(uint8_t iter = 1; iter + 2 < nonRunLength; iter += 2)
-            {
-              const uint8_t w     = *(inBufferPtr++);
-              const uint8_t prew0 = (*(outBufferPtr)) & 0x0f;
-              const uint8_t w0    = (prew0 + ((w >> 4) & 0x0f)) & 0x0f;
-              const uint8_t prew1 = (*(outBufferPtr + 1)) & 0x0f;
-              const uint8_t w1    = (prew1 + (w & 0x0f)) & 0x0f;
-              ++offset;
-
-              *(outBufferPtr++) = (w0 << 4) | w0;
-              *(outBufferPtr++) = (w1 << 4) | w1;
-            }
-            // Last value.
-            {
-              const uint8_t w     = ((*(inBufferPtr++)) >> 4) & 0x0f;
-              const uint8_t prew0 = (*(outBufferPtr)) & 0x0f;
-              const uint8_t w0    = (prew0 + w) & 0x0f;
-              ++offset;
-
-              *(outBufferPtr++) = (w0 << 4) | w0;
-            }
-          }
-          else
-          {
-            for(uint8_t iter = 1; iter < nonRunLength; iter += 2)
-            {
-              const uint8_t w     = *(inBufferPtr++);
-              const uint8_t prew0 = (*(outBufferPtr)) & 0x0f;
-              const uint8_t w0    = (prew0 + ((w >> 4) & 0x0f)) & 0x0f;
-              const uint8_t prew1 = (*(outBufferPtr + 1)) & 0x0f;
-              const uint8_t w1    = (prew1 + (w & 0x0f)) & 0x0f;
-              ++offset;
-
-              *(outBufferPtr++) = (w0 << 4) | w0;
-              *(outBufferPtr++) = (w1 << 4) | w1;
-            }
-          }
-        }
-      }
-      break;
-    }
-    default:
-    {
-      break;
-    }
-  }
-}
-
 // FontClient
 
 FontClient FontClient::Get()
@@ -584,25 +57,31 @@ FontClient FontClient::Get()
   return Internal::FontClient::Get();
 }
 
-FontClient::FontClient()
+FontClient FontClient::New(uint32_t horizontalDpi, uint32_t verticalDpi)
 {
-}
+  auto fontClientImpl = new Internal::FontClient();
 
-FontClient::~FontClient()
-{
+  fontClientImpl->SetDpi(horizontalDpi, verticalDpi);
+
+  return FontClient(fontClientImpl);
 }
 
-FontClient::FontClient(const FontClient& handle)
-: BaseHandle(handle)
+FontClient::FontClient()
 {
 }
 
-FontClient& FontClient::operator=(const FontClient& handle)
+FontClient::~FontClient()
 {
-  BaseHandle::operator=(handle);
-  return *this;
 }
 
+FontClient::FontClient(const FontClient& handle) = default;
+
+FontClient& FontClient::operator=(const FontClient& handle) = default;
+
+FontClient::FontClient(FontClient&& handle) = default;
+
+FontClient& FontClient::operator=(FontClient&& handle) = default;
+
 void FontClient::ClearCache()
 {
   GetImplementation(*this).ClearCache();
@@ -633,6 +112,11 @@ void FontClient::GetDefaultFonts(FontList& defaultFonts)
   GetImplementation(*this).GetDefaultFonts(defaultFonts);
 }
 
+void FontClient::InitDefaultFontDescription()
+{
+  GetImplementation(*this).InitDefaultFontDescription();
+}
+
 void FontClient::GetDefaultPlatformFontDescription(FontDescription& fontDescription)
 {
   GetImplementation(*this).GetDefaultPlatformFontDescription(fontDescription);
@@ -643,14 +127,14 @@ void FontClient::GetSystemFonts(FontList& systemFonts)
   GetImplementation(*this).GetSystemFonts(systemFonts);
 }
 
-void FontClient::GetDescription(FontId id, FontDescription& fontDescription)
+void FontClient::GetDescription(FontId fontId, FontDescription& fontDescription)
 {
-  GetImplementation(*this).GetDescription(id, fontDescription);
+  GetImplementation(*this).GetDescription(fontId, fontDescription);
 }
 
-PointSize26Dot6 FontClient::GetPointSize(FontId id)
+PointSize26Dot6 FontClient::GetPointSize(FontId fontId)
 {
-  return GetImplementation(*this).GetPointSize(id);
+  return GetImplementation(*this).GetPointSize(fontId);
 }
 
 bool FontClient::IsCharacterSupportedByFont(FontId fontId, Character character)
@@ -820,6 +304,16 @@ FontClient FontClientPreInitialize()
   return Internal::FontClient::PreInitialize();
 }
 
+void FontClientPreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool useThread)
+{
+  Internal::FontClient::PreCache(fallbackFamilyList, extraFamilyList, localeFamily, useThread);
+}
+
+void FontClientFontPreLoad(const FontPathList& fontPathList, const FontPathList& memoryFontPathList, bool useThread)
+{
+  Internal::FontClient::PreLoad(fontPathList, memoryFontPathList, useThread);
+}
+
 } // namespace TextAbstraction
 
 } // namespace Dali