+FT_FaceRec_* FontClient::Plugin::GetFreetypeFace(FontId fontId)
+{
+ FT_Face fontFace = nullptr;
+
+ const FontId index = fontId - 1u;
+ if((fontId > 0u) &&
+ (index < mFontIdCache.Count()))
+ {
+ const FontIdCacheItem& fontIdCacheItem = mFontIdCache[index];
+
+ if(FontDescription::FACE_FONT == fontIdCacheItem.type)
+ {
+ fontFace = mFontFaceCache[fontIdCacheItem.id].mFreeTypeFace;
+ }
+ }
+ return fontFace;
+}
+
+FontDescription::Type FontClient::Plugin::GetFontType(FontId fontId)
+{
+ const FontId index = fontId - 1u;
+ if((fontId > 0u) &&
+ (index < mFontIdCache.Count()))
+ {
+ return mFontIdCache[index].type;
+ }
+ return FontDescription::INVALID;
+}
+
+bool FontClient::Plugin::AddCustomFontDirectory(const FontPath& path)
+{
+ // nullptr as first parameter means the current configuration is used.
+ return FcConfigAppFontAddDir(nullptr, reinterpret_cast<const FcChar8*>(path.c_str()));
+}
+
+GlyphIndex FontClient::Plugin::CreateEmbeddedItem(const TextAbstraction::FontClient::EmbeddedItemDescription& description, Pixel::Format& pixelFormat)
+{
+ EmbeddedItem embeddedItem;
+
+ embeddedItem.pixelBufferId = 0u;
+ embeddedItem.width = description.width;
+ embeddedItem.height = description.height;
+
+ pixelFormat = Pixel::A8;
+
+ 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)
+ {
+ // 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();
+ }
+ else
+ {
+ // Retrieve the pixel buffer from the cache to set the pixel format.
+ pixelBuffer = mPixelBufferCache[embeddedItem.pixelBufferId - 1u].pixelBuffer;
+ }
+
+ if(pixelBuffer)
+ {
+ // Set the size of the embedded item if it has not been set.
+ if(0u == embeddedItem.width)
+ {
+ embeddedItem.width = static_cast<unsigned int>(pixelBuffer.GetWidth());
+ }
+
+ if(0u == embeddedItem.height)
+ {
+ embeddedItem.height = static_cast<unsigned int>(pixelBuffer.GetHeight());
+ }
+
+ // Set the pixel format.
+ pixelFormat = pixelBuffer.GetPixelFormat();
+ }
+ }
+
+ // Find if the same embeddedItem has already been created.
+ unsigned int index = 0u;
+ for(const auto& item : mEmbeddedItemCache)
+ {
+ ++index;
+ if((item.pixelBufferId == embeddedItem.pixelBufferId) &&
+ (item.width == embeddedItem.width) &&
+ (item.height == embeddedItem.height))
+ {
+ return index;
+ }
+ }
+
+ // Cache the embedded item.
+ mEmbeddedItemCache.PushBack(embeddedItem);
+
+ return mEmbeddedItemCache.Count();
+}
+//SHS
+
+void FontClient::Plugin::EnableAtlasLimitation(bool enabled)
+{
+ mIsAtlasLimitationEnabled = enabled;
+}
+
+bool FontClient::Plugin::IsAtlasLimitationEnabled() const
+{
+ return mIsAtlasLimitationEnabled;
+}
+
+Size FontClient::Plugin::GetMaximumTextAtlasSize() const
+{
+ return TextAbstraction::FontClient::MAX_TEXT_ATLAS_SIZE;
+}
+
+Size FontClient::Plugin::GetDefaultTextAtlasSize() const
+{
+ return TextAbstraction::FontClient::DEFAULT_TEXT_ATLAS_SIZE;
+}
+
+Size FontClient::Plugin::GetCurrentMaximumBlockSizeFitInAtlas() const
+{
+ return mCurrentMaximumBlockSizeFitInAtlas;
+}
+
+bool FontClient::Plugin::SetCurrentMaximumBlockSizeFitInAtlas(const Size& currentMaximumBlockSizeFitInAtlas)
+{
+ bool isChanged = false;
+ const Size& maxTextAtlasSize = TextAbstraction::FontClient::MAX_TEXT_ATLAS_SIZE;
+ const uint16_t& padding = TextAbstraction::FontClient::PADDING_TEXT_ATLAS_BLOCK;
+
+ if(currentMaximumBlockSizeFitInAtlas.width <= maxTextAtlasSize.width - padding
+ && currentMaximumBlockSizeFitInAtlas.height <= maxTextAtlasSize.height - padding)
+ {
+ mCurrentMaximumBlockSizeFitInAtlas = currentMaximumBlockSizeFitInAtlas;
+ isChanged = true;
+ }
+
+ return isChanged;
+}
+
+uint32_t FontClient::Plugin::GetNumberOfPointsPerOneUnitOfPointSize() const
+{
+ return TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;;
+}
+
+