X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Ftext%2Ftext-abstraction%2Ffont-client-impl.cpp;h=5e2b258429c80c5fcf01cf79802b1368e0844fde;hb=b59a021650a941e4c1b5a0644bdd64034a8254be;hp=6ea507220f8cf8cbc1a34b7778c29a4b6bd3903a;hpb=36aa971df1cf4e60dd9efa67158217e901fb5eef;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/dali/internal/text/text-abstraction/font-client-impl.cpp b/dali/internal/text/text-abstraction/font-client-impl.cpp index 6ea5072..5e2b258 100644 --- a/dali/internal/text/text-abstraction/font-client-impl.cpp +++ b/dali/internal/text/text-abstraction/font-client-impl.cpp @@ -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. @@ -19,16 +19,34 @@ #include // EXTERNAL INCLUDES +#include #if defined(VCONF_ENABLED) #include #endif // INTERNAL INCLUDES #include +#include #include +#include #include +#define FONT_LOG_MESSAGE(level, format, ...) \ + do \ + { \ + char buffer[256]; \ + int result = std::snprintf(buffer, sizeof(buffer), format, ##__VA_ARGS__); \ + if(result >= static_cast(sizeof(buffer))) \ + { \ + std::string log("Font log message is too long to fit in the buffer.\n"); \ + Dali::TizenPlatform::LogMessage(Dali::Integration::Log::ERROR, log); \ + break; \ + } \ + std::string log(buffer); \ + Dali::TizenPlatform::LogMessage(level, log); \ + } while(0) + namespace Dali { namespace TextAbstraction @@ -36,6 +54,12 @@ namespace TextAbstraction namespace Internal { Dali::TextAbstraction::FontClient FontClient::gPreInitializedFontClient(NULL); +Dali::TextAbstraction::FontClient FontClient::gPreCachedFontClient(NULL); +std::thread gPreCacheThread; +/* TODO: This is to prevent duplicate calls of font pre-cache. + * We may support this later, but currently we can't guarantee the behaviour + * if there is a pre-cache call from the user after the font client has been created. */ +bool gFontPreCacheAvailable = true; FontClient::FontClient() : mPlugin(nullptr), @@ -66,14 +90,41 @@ Dali::TextAbstraction::FontClient FontClient::Get() } else // create and register the object { + if(gPreCacheThread.joinable()) + { + gPreCacheThread.join(); + FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache thread join\n"); + } + if(gPreInitializedFontClient) { fontClientHandle = gPreInitializedFontClient; gPreInitializedFontClient.Reset(); // No longer needed } + else if(gPreCachedFontClient) + { + // TODO: Currently font pre-caching is not available in the candidate process. + fontClientHandle = gPreCachedFontClient; + gPreCachedFontClient.Reset(); // No longer needed + } else { fontClientHandle = Dali::TextAbstraction::FontClient(new FontClient); + + // Make DefaultFontDescription cached + Dali::TextAbstraction::FontDescription defaultFontDescription; + fontClientHandle.GetDefaultPlatformFontDescription(defaultFontDescription); + } + + gFontPreCacheAvailable = false; + + uint32_t horizontalDpi, verticalDpi; + fontClientHandle.GetDpi(horizontalDpi, verticalDpi); + if(horizontalDpi == 0u || verticalDpi == 0u) + { + horizontalDpi = verticalDpi = 0u; + Dali::Internal::Adaptor::WindowSystem::GetDpi(horizontalDpi, verticalDpi); + fontClientHandle.SetDpi(horizontalDpi, verticalDpi); } service.Register(typeid(fontClientHandle), fontClientHandle); @@ -94,6 +145,53 @@ Dali::TextAbstraction::FontClient FontClient::PreInitialize() return gPreInitializedFontClient; } +void FontClient::PreCacheRun(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily) +{ + if(!gPreCachedFontClient) + { + FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "BEGIN: DALI_TEXT_PRECACHE_RUN\n"); + Dali::TextAbstraction::FontClient fontClient = Dali::TextAbstraction::FontClient(new FontClient); + GetImplementation(fontClient).FontPreCache(fallbackFamilyList, extraFamilyList, localeFamily); + gPreCachedFontClient = fontClient; + gFontPreCacheAvailable = false; + FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "END: DALI_TEXT_PRECACHE_RUN\n"); + } + else + { + FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient pre-cache run failed, as a pre-cached font client already exists.\n"); + } +} + +void FontClient::PreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool useThread) +{ + if(!gFontPreCacheAvailable) + { + FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient pre-cache has been completed or the font client has already been created.\n"); + return; + } + + FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache fallbackFamilyList : %zu\n", fallbackFamilyList.size()); + FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache extraFamilyList : %zu\n", extraFamilyList.size()); + FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache localeFamily : %s\n", localeFamily.c_str()); + FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache useThread : %d\n", useThread); + + if(gPreCacheThread.joinable()) + { + FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient pre-cache thread already running.\n"); + } + else + { + if(useThread) + { + gPreCacheThread = std::thread(PreCacheRun, fallbackFamilyList, extraFamilyList, localeFamily); + } + else + { + PreCacheRun(fallbackFamilyList, extraFamilyList, localeFamily); + } + } +} + void FontClient::ClearCache() { if(mPlugin) @@ -145,6 +243,13 @@ void FontClient::GetDefaultFonts(FontList& defaultFonts) mPlugin->GetDefaultFonts(defaultFonts); } +void FontClient::FontPreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily) +{ + CreatePlugin(); + + mPlugin->FontPreCache(fallbackFamilyList, extraFamilyList, localeFamily); +} + void FontClient::GetDefaultPlatformFontDescription(FontDescription& fontDescription) { CreatePlugin();