2 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/text/text-abstraction/font-client-impl.h>
24 #if defined(VCONF_ENABLED)
29 #include <dali/devel-api/common/singleton-service.h>
30 #include <dali/internal/system/common/logging.h>
31 #include <dali/internal/text/text-abstraction/plugin/font-client-plugin-impl.h>
32 #include <dali/internal/window-system/common/window-system.h>
34 #include <dali/devel-api/text-abstraction/glyph-info.h>
36 // Use this macro only if need to log messages before the log function is set.
37 #define FONT_LOG_MESSAGE(level, format, ...) \
41 int result = std::snprintf(buffer, sizeof(buffer), format, ##__VA_ARGS__); \
42 if(result >= static_cast<int>(sizeof(buffer))) \
44 std::string log("Font log message is too long to fit in the buffer.\n"); \
45 Dali::TizenPlatform::LogMessage(Dali::Integration::Log::ERROR, log); \
48 std::string log(buffer); \
49 Dali::TizenPlatform::LogMessage(level, log); \
54 namespace TextAbstraction
58 Dali::TextAbstraction::FontClient FontClient::gPreCreatedFontClient(NULL);
59 std::thread gPreCacheThread;
60 std::thread gPreLoadThread;
63 /* TODO: This is to prevent duplicate calls of font pre-cache.
64 * We may support this later, but currently we can't guarantee the behaviour
65 * if there is a pre-cache call from the user after the font client has been created. */
66 bool gFontPreCacheAvailable = true;
67 bool gFontPreLoadAvailable = true;
69 FontClient::FontClient()
76 FontClient::~FontClient()
81 Dali::TextAbstraction::FontClient FontClient::Get()
83 Dali::TextAbstraction::FontClient fontClientHandle;
85 Dali::SingletonService service(SingletonService::Get());
88 // Check whether the singleton is already created
89 Dali::BaseHandle handle = service.GetSingleton(typeid(Dali::TextAbstraction::FontClient));
92 // If so, downcast the handle
93 FontClient* impl = dynamic_cast<Dali::TextAbstraction::Internal::FontClient*>(handle.GetObjectPtr());
94 fontClientHandle = Dali::TextAbstraction::FontClient(impl);
96 else // create and register the object
98 if(gPreCacheThread.joinable())
100 gPreCacheThread.join();
101 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache thread join\n");
104 if(gPreLoadThread.joinable())
106 gPreLoadThread.join();
107 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreLoad thread join\n");
110 if(gPreCreatedFontClient)
112 fontClientHandle = gPreCreatedFontClient;
113 gPreCreatedFontClient.Reset(); // No longer needed
117 fontClientHandle = Dali::TextAbstraction::FontClient(new FontClient);
120 fontClientHandle.InitDefaultFontDescription();
122 gFontPreCacheAvailable = false;
123 gFontPreLoadAvailable = false;
125 uint32_t horizontalDpi, verticalDpi;
126 fontClientHandle.GetDpi(horizontalDpi, verticalDpi);
127 if(horizontalDpi == 0u || verticalDpi == 0u)
129 horizontalDpi = verticalDpi = 0u;
130 Dali::Internal::Adaptor::WindowSystem::GetDpi(horizontalDpi, verticalDpi);
131 fontClientHandle.SetDpi(horizontalDpi, verticalDpi);
134 service.Register(typeid(fontClientHandle), fontClientHandle);
138 return fontClientHandle;
141 Dali::TextAbstraction::FontClient FontClient::PreInitialize()
143 // Pre-cached font client already exists or pre-cache thread already running.
144 // Font client pre-cache includes caching of the default font description.
145 if(gPreCreatedFontClient && !gFontPreCacheAvailable)
147 return gPreCreatedFontClient;
150 if(!gPreCreatedFontClient)
152 gPreCreatedFontClient = Dali::TextAbstraction::FontClient(new FontClient);
155 gPreCreatedFontClient.InitDefaultFontDescription();
157 return gPreCreatedFontClient;
160 void FontClient::PreCacheRun(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily)
162 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "BEGIN: DALI_TEXT_PRECACHE_RUN\n");
163 GetImplementation(gPreCreatedFontClient).FontPreCache(fallbackFamilyList, extraFamilyList, localeFamily);
164 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "END: DALI_TEXT_PRECACHE_RUN\n");
167 void FontClient::PreLoadRun(const FontPathList& fontPathList, const FontPathList& memoryFontPathList)
169 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "BEGIN: DALI_TEXT_FONT_PRELOAD_RUN\n");
170 GetImplementation(gPreCreatedFontClient).FontPreLoad(fontPathList, memoryFontPathList);
171 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "END: DALI_TEXT_FONT_PRELOAD_RUN\n");
174 void FontClient::PreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool useThread)
176 if(!gFontPreCacheAvailable)
178 FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient pre-cache run failed, as a pre-cached font client already exists.\n");
182 if(gPreCacheThread.joinable())
184 FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient pre-cache thread already running.\n");
187 if(!gPreCreatedFontClient)
189 gPreCreatedFontClient = Dali::TextAbstraction::FontClient(new FontClient);
192 gFontPreCacheAvailable = false;
194 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient FontConfig PreCache fallbackFamilyList : %zu\n", fallbackFamilyList.size());
195 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient FontConfig PreCache extraFamilyList : %zu\n", extraFamilyList.size());
196 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient FontConfig PreCache localeFamily : %s\n", localeFamily.c_str());
197 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient FontConfig PreCache useThread : %d\n", useThread);
201 gPreCacheThread = std::thread(PreCacheRun, fallbackFamilyList, extraFamilyList, localeFamily);
205 PreCacheRun(fallbackFamilyList, extraFamilyList, localeFamily);
209 void FontClient::PreLoad(const FontPathList& fontPathList, const FontPathList& memoryFontPathList, bool useThread)
211 if(!gFontPreLoadAvailable)
213 FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient font pre-load run failed, as a pre-loaded font client already exists.\n");
217 if(gPreLoadThread.joinable())
219 FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient font pre-load thread already running.\n");
223 if(!gPreCreatedFontClient)
225 gPreCreatedFontClient = Dali::TextAbstraction::FontClient(new FontClient);
228 gFontPreLoadAvailable = false;
230 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient Font PreLoad fontPathList : %zu\n", fontPathList.size());
231 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient Font PreLoad memoryFontPathList : %zu\n", memoryFontPathList.size());
232 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient Font PreLoad useThread : %d\n", useThread);
236 gPreLoadThread = std::thread(PreLoadRun, fontPathList, memoryFontPathList);
240 PreLoadRun(fontPathList, memoryFontPathList);
244 void FontClient::ClearCache()
248 mPlugin->ClearCache();
252 void FontClient::SetDpi(unsigned int horizontalDpi, unsigned int verticalDpi)
254 mDpiHorizontal = horizontalDpi;
255 mDpiVertical = verticalDpi;
257 // Allow DPI to be set without loading plugin
260 mPlugin->SetDpi(horizontalDpi, verticalDpi);
264 void FontClient::GetDpi(unsigned int& horizontalDpi, unsigned int& verticalDpi)
266 horizontalDpi = mDpiHorizontal;
267 verticalDpi = mDpiVertical;
270 int FontClient::GetDefaultFontSize()
274 #if defined(VCONF_ENABLED)
275 vconf_get_int(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, &fontSize);
281 void FontClient::ResetSystemDefaults()
285 mPlugin->ResetSystemDefaults();
288 void FontClient::GetDefaultFonts(FontList& defaultFonts)
292 mPlugin->GetDefaultFonts(defaultFonts);
295 void FontClient::FontPreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily)
299 mPlugin->FontPreCache(fallbackFamilyList, extraFamilyList, localeFamily);
302 void FontClient::FontPreLoad(const FontPathList& fontPathList, const FontPathList& memoryFontPathList)
306 mPlugin->FontPreLoad(fontPathList, memoryFontPathList);
309 void FontClient::InitDefaultFontDescription()
313 mPlugin->InitDefaultFontDescription();
316 void FontClient::GetDefaultPlatformFontDescription(FontDescription& fontDescription)
320 mPlugin->GetDefaultPlatformFontDescription(fontDescription);
323 void FontClient::GetDescription(FontId fontId, FontDescription& fontDescription)
327 mPlugin->GetDescription(fontId, fontDescription);
330 PointSize26Dot6 FontClient::GetPointSize(FontId fontId)
334 return mPlugin->GetPointSize(fontId);
337 bool FontClient::IsCharacterSupportedByFont(FontId fontId, Character character)
341 return mPlugin->IsCharacterSupportedByFont(fontId, character);
344 void FontClient::GetSystemFonts(FontList& systemFonts)
348 mPlugin->GetSystemFonts(systemFonts);
351 FontId FontClient::FindDefaultFont(Character charcode,
352 PointSize26Dot6 requestedPointSize,
357 return mPlugin->FindDefaultFont(charcode,
362 FontId FontClient::FindFallbackFont(Character charcode,
363 const FontDescription& preferredFontDescription,
364 PointSize26Dot6 requestedPointSize,
369 return mPlugin->FindFallbackFont(charcode,
370 preferredFontDescription,
375 bool FontClient::IsScalable(const FontPath& path)
379 return mPlugin->IsScalable(path);
382 bool FontClient::IsScalable(const FontDescription& fontDescription)
386 return mPlugin->IsScalable(fontDescription);
389 void FontClient::GetFixedSizes(const FontPath& path, Dali::Vector<PointSize26Dot6>& sizes)
393 mPlugin->GetFixedSizes(path, sizes);
396 void FontClient::GetFixedSizes(const FontDescription& fontDescription,
397 Dali::Vector<PointSize26Dot6>& sizes)
401 mPlugin->GetFixedSizes(fontDescription, sizes);
404 bool FontClient::HasItalicStyle(FontId fontId) const
410 return mPlugin->HasItalicStyle(fontId);
413 FontId FontClient::GetFontId(const FontPath& path, PointSize26Dot6 requestedPointSize, FaceIndex faceIndex)
417 return mPlugin->GetFontIdByPath(path,
423 FontId FontClient::GetFontId(const FontDescription& fontDescription,
424 PointSize26Dot6 requestedPointSize,
429 return mPlugin->GetFontId(fontDescription,
434 FontId FontClient::GetFontId(const BitmapFont& bitmapFont)
438 return mPlugin->GetFontId(bitmapFont);
441 void FontClient::GetFontMetrics(FontId fontId, FontMetrics& metrics)
445 mPlugin->GetFontMetrics(fontId, metrics);
448 GlyphIndex FontClient::GetGlyphIndex(FontId fontId, Character charcode)
452 return mPlugin->GetGlyphIndex(fontId, charcode);
455 GlyphIndex FontClient::GetGlyphIndex(FontId fontId, Character charcode, Character variantSelector)
459 return mPlugin->GetGlyphIndex(fontId, charcode, variantSelector);
462 bool FontClient::GetGlyphMetrics(GlyphInfo* array, uint32_t size, GlyphType type, bool horizontal)
466 return mPlugin->GetGlyphMetrics(array, size, type, horizontal);
469 void FontClient::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, bool isItalicRequired, bool isBoldRequired, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth)
473 mPlugin->CreateBitmap(fontId, glyphIndex, isItalicRequired, isBoldRequired, data, outlineWidth);
476 PixelData FontClient::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, int outlineWidth)
480 return mPlugin->CreateBitmap(fontId, glyphIndex, outlineWidth);
483 void FontClient::CreateVectorBlob(FontId fontId, GlyphIndex glyphIndex, VectorBlob*& blob, unsigned int& blobLength, unsigned int& nominalWidth, unsigned int& nominalHeight)
487 mPlugin->CreateVectorBlob(fontId, glyphIndex, blob, blobLength, nominalWidth, nominalHeight);
490 const GlyphInfo& FontClient::GetEllipsisGlyph(PointSize26Dot6 requestedPointSize)
494 return mPlugin->GetEllipsisGlyph(requestedPointSize);
497 bool FontClient::IsColorGlyph(FontId fontId, GlyphIndex glyphIndex)
501 return mPlugin->IsColorGlyph(fontId, glyphIndex);
504 GlyphIndex FontClient::CreateEmbeddedItem(const TextAbstraction::FontClient::EmbeddedItemDescription& description, Pixel::Format& pixelFormat)
508 return mPlugin->CreateEmbeddedItem(description, pixelFormat);
511 void FontClient::EnableAtlasLimitation(bool enabled)
514 return mPlugin->EnableAtlasLimitation(enabled);
517 bool FontClient::IsAtlasLimitationEnabled() const
521 return mPlugin->IsAtlasLimitationEnabled();
523 return TextAbstraction::FontClient::DEFAULT_ATLAS_LIMITATION_ENABLED;
526 Size FontClient::GetMaximumTextAtlasSize() const
530 return mPlugin->GetMaximumTextAtlasSize();
532 return TextAbstraction::FontClient::MAX_TEXT_ATLAS_SIZE;
535 Size FontClient::GetDefaultTextAtlasSize() const
539 return mPlugin->GetDefaultTextAtlasSize();
541 return TextAbstraction::FontClient::DEFAULT_TEXT_ATLAS_SIZE;
544 Size FontClient::GetCurrentMaximumBlockSizeFitInAtlas() const
548 return mPlugin->GetCurrentMaximumBlockSizeFitInAtlas();
550 return TextAbstraction::FontClient::DEFAULT_TEXT_ATLAS_SIZE;
553 bool FontClient::SetCurrentMaximumBlockSizeFitInAtlas(const Size& currentMaximumBlockSizeFitInAtlas)
556 return mPlugin->SetCurrentMaximumBlockSizeFitInAtlas(currentMaximumBlockSizeFitInAtlas);
559 uint32_t FontClient::GetNumberOfPointsPerOneUnitOfPointSize() const
563 return mPlugin->GetNumberOfPointsPerOneUnitOfPointSize();
565 return TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;
569 FT_FaceRec_* FontClient::GetFreetypeFace(FontId fontId)
573 return mPlugin->GetFreetypeFace(fontId);
576 FontDescription::Type FontClient::GetFontType(FontId fontId)
580 return mPlugin->GetFontType(fontId);
583 bool FontClient::AddCustomFontDirectory(const FontPath& path)
587 return mPlugin->AddCustomFontDirectory(path);
590 HarfBuzzFontHandle FontClient::GetHarfBuzzFont(FontId fontId)
594 return mPlugin->GetHarfBuzzFont(fontId);
597 void FontClient::CreatePlugin()
599 std::scoped_lock lock(gMutex);
602 mPlugin = new Plugin(mDpiHorizontal, mDpiVertical);
606 } // namespace Internal
608 } // namespace TextAbstraction