2 * Copyright (c) 2023 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>
23 #if defined(VCONF_ENABLED)
28 #include <dali/devel-api/common/singleton-service.h>
29 #include <dali/internal/system/common/logging.h>
30 #include <dali/internal/text/text-abstraction/plugin/font-client-plugin-impl.h>
31 #include <dali/internal/window-system/common/window-system.h>
33 #include <dali/devel-api/text-abstraction/glyph-info.h>
35 #define FONT_LOG_MESSAGE(level, format, ...) \
39 int result = std::snprintf(buffer, sizeof(buffer), format, ##__VA_ARGS__); \
40 if(result >= static_cast<int>(sizeof(buffer))) \
42 std::string log("Font log message is too long to fit in the buffer.\n"); \
43 Dali::TizenPlatform::LogMessage(Dali::Integration::Log::ERROR, log); \
46 std::string log(buffer); \
47 Dali::TizenPlatform::LogMessage(level, log); \
52 namespace TextAbstraction
56 Dali::TextAbstraction::FontClient FontClient::gPreInitializedFontClient(NULL);
57 Dali::TextAbstraction::FontClient FontClient::gPreCachedFontClient(NULL);
58 std::thread gPreCacheThread;
59 /* TODO: This is to prevent duplicate calls of font pre-cache.
60 * We may support this later, but currently we can't guarantee the behaviour
61 * if there is a pre-cache call from the user after the font client has been created. */
62 bool gFontPreCacheAvailable = true;
64 FontClient::FontClient()
71 FontClient::~FontClient()
76 Dali::TextAbstraction::FontClient FontClient::Get()
78 Dali::TextAbstraction::FontClient fontClientHandle;
80 Dali::SingletonService service(SingletonService::Get());
83 // Check whether the singleton is already created
84 Dali::BaseHandle handle = service.GetSingleton(typeid(Dali::TextAbstraction::FontClient));
87 // If so, downcast the handle
88 FontClient* impl = dynamic_cast<Dali::TextAbstraction::Internal::FontClient*>(handle.GetObjectPtr());
89 fontClientHandle = Dali::TextAbstraction::FontClient(impl);
91 else // create and register the object
93 if(gPreCacheThread.joinable())
95 gPreCacheThread.join();
96 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache thread join\n");
99 if(gPreInitializedFontClient)
101 fontClientHandle = gPreInitializedFontClient;
102 gPreInitializedFontClient.Reset(); // No longer needed
104 else if(gPreCachedFontClient)
106 // TODO: Currently font pre-caching is not available in the candidate process.
107 fontClientHandle = gPreCachedFontClient;
108 gPreCachedFontClient.Reset(); // No longer needed
112 fontClientHandle = Dali::TextAbstraction::FontClient(new FontClient);
114 // Make DefaultFontDescription cached
115 Dali::TextAbstraction::FontDescription defaultFontDescription;
116 fontClientHandle.GetDefaultPlatformFontDescription(defaultFontDescription);
119 gFontPreCacheAvailable = false;
121 uint32_t horizontalDpi, verticalDpi;
122 fontClientHandle.GetDpi(horizontalDpi, verticalDpi);
123 if(horizontalDpi == 0u || verticalDpi == 0u)
125 horizontalDpi = verticalDpi = 0u;
126 Dali::Internal::Adaptor::WindowSystem::GetDpi(horizontalDpi, verticalDpi);
127 fontClientHandle.SetDpi(horizontalDpi, verticalDpi);
130 service.Register(typeid(fontClientHandle), fontClientHandle);
134 return fontClientHandle;
137 Dali::TextAbstraction::FontClient FontClient::PreInitialize()
139 gPreInitializedFontClient = Dali::TextAbstraction::FontClient(new FontClient);
141 // Make DefaultFontDescription cached
142 Dali::TextAbstraction::FontDescription defaultFontDescription;
143 gPreInitializedFontClient.GetDefaultPlatformFontDescription(defaultFontDescription);
145 return gPreInitializedFontClient;
148 void FontClient::PreCacheRun(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily)
150 if(!gPreCachedFontClient)
152 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "BEGIN: DALI_TEXT_PRECACHE_RUN\n");
153 Dali::TextAbstraction::FontClient fontClient = Dali::TextAbstraction::FontClient(new FontClient);
154 GetImplementation(fontClient).FontPreCache(fallbackFamilyList, extraFamilyList, localeFamily);
155 gPreCachedFontClient = fontClient;
156 gFontPreCacheAvailable = false;
157 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "END: DALI_TEXT_PRECACHE_RUN\n");
161 FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient pre-cache run failed, as a pre-cached font client already exists.\n");
165 void FontClient::PreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool useThread)
167 if(!gFontPreCacheAvailable)
169 FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient pre-cache has been completed or the font client has already been created.\n");
173 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache fallbackFamilyList : %zu\n", fallbackFamilyList.size());
174 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache extraFamilyList : %zu\n", extraFamilyList.size());
175 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache localeFamily : %s\n", localeFamily.c_str());
176 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache useThread : %d\n", useThread);
178 if(gPreCacheThread.joinable())
180 FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient pre-cache thread already running.\n");
186 gPreCacheThread = std::thread(PreCacheRun, fallbackFamilyList, extraFamilyList, localeFamily);
190 PreCacheRun(fallbackFamilyList, extraFamilyList, localeFamily);
195 void FontClient::ClearCache()
199 mPlugin->ClearCache();
203 void FontClient::SetDpi(unsigned int horizontalDpi, unsigned int verticalDpi)
205 mDpiHorizontal = horizontalDpi;
206 mDpiVertical = verticalDpi;
208 // Allow DPI to be set without loading plugin
211 mPlugin->SetDpi(horizontalDpi, verticalDpi);
215 void FontClient::GetDpi(unsigned int& horizontalDpi, unsigned int& verticalDpi)
217 horizontalDpi = mDpiHorizontal;
218 verticalDpi = mDpiVertical;
221 int FontClient::GetDefaultFontSize()
225 #if defined(VCONF_ENABLED)
226 vconf_get_int(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, &fontSize);
232 void FontClient::ResetSystemDefaults()
236 mPlugin->ResetSystemDefaults();
239 void FontClient::GetDefaultFonts(FontList& defaultFonts)
243 mPlugin->GetDefaultFonts(defaultFonts);
246 void FontClient::FontPreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily)
250 mPlugin->FontPreCache(fallbackFamilyList, extraFamilyList, localeFamily);
253 void FontClient::GetDefaultPlatformFontDescription(FontDescription& fontDescription)
257 mPlugin->GetDefaultPlatformFontDescription(fontDescription);
260 void FontClient::GetDescription(FontId fontId, FontDescription& fontDescription)
264 mPlugin->GetDescription(fontId, fontDescription);
267 PointSize26Dot6 FontClient::GetPointSize(FontId fontId)
271 return mPlugin->GetPointSize(fontId);
274 bool FontClient::IsCharacterSupportedByFont(FontId fontId, Character character)
278 return mPlugin->IsCharacterSupportedByFont(fontId, character);
281 void FontClient::GetSystemFonts(FontList& systemFonts)
285 mPlugin->GetSystemFonts(systemFonts);
288 FontId FontClient::FindDefaultFont(Character charcode,
289 PointSize26Dot6 requestedPointSize,
294 return mPlugin->FindDefaultFont(charcode,
299 FontId FontClient::FindFallbackFont(Character charcode,
300 const FontDescription& preferredFontDescription,
301 PointSize26Dot6 requestedPointSize,
306 return mPlugin->FindFallbackFont(charcode,
307 preferredFontDescription,
312 bool FontClient::IsScalable(const FontPath& path)
316 return mPlugin->IsScalable(path);
319 bool FontClient::IsScalable(const FontDescription& fontDescription)
323 return mPlugin->IsScalable(fontDescription);
326 void FontClient::GetFixedSizes(const FontPath& path, Dali::Vector<PointSize26Dot6>& sizes)
330 mPlugin->GetFixedSizes(path, sizes);
333 void FontClient::GetFixedSizes(const FontDescription& fontDescription,
334 Dali::Vector<PointSize26Dot6>& sizes)
338 mPlugin->GetFixedSizes(fontDescription, sizes);
341 bool FontClient::HasItalicStyle(FontId fontId) const
347 return mPlugin->HasItalicStyle(fontId);
350 FontId FontClient::GetFontId(const FontPath& path, PointSize26Dot6 requestedPointSize, FaceIndex faceIndex)
354 return mPlugin->GetFontIdByPath(path,
360 FontId FontClient::GetFontId(const FontDescription& fontDescription,
361 PointSize26Dot6 requestedPointSize,
366 return mPlugin->GetFontId(fontDescription,
371 FontId FontClient::GetFontId(const BitmapFont& bitmapFont)
375 return mPlugin->GetFontId(bitmapFont);
378 void FontClient::GetFontMetrics(FontId fontId, FontMetrics& metrics)
382 mPlugin->GetFontMetrics(fontId, metrics);
385 GlyphIndex FontClient::GetGlyphIndex(FontId fontId, Character charcode)
389 return mPlugin->GetGlyphIndex(fontId, charcode);
392 GlyphIndex FontClient::GetGlyphIndex(FontId fontId, Character charcode, Character variantSelector)
396 return mPlugin->GetGlyphIndex(fontId, charcode, variantSelector);
399 bool FontClient::GetGlyphMetrics(GlyphInfo* array, uint32_t size, GlyphType type, bool horizontal)
403 return mPlugin->GetGlyphMetrics(array, size, type, horizontal);
406 void FontClient::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, bool isItalicRequired, bool isBoldRequired, Dali::TextAbstraction::GlyphBufferData& data, int outlineWidth)
410 mPlugin->CreateBitmap(fontId, glyphIndex, isItalicRequired, isBoldRequired, data, outlineWidth);
413 PixelData FontClient::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, int outlineWidth)
417 return mPlugin->CreateBitmap(fontId, glyphIndex, outlineWidth);
420 void FontClient::CreateVectorBlob(FontId fontId, GlyphIndex glyphIndex, VectorBlob*& blob, unsigned int& blobLength, unsigned int& nominalWidth, unsigned int& nominalHeight)
424 mPlugin->CreateVectorBlob(fontId, glyphIndex, blob, blobLength, nominalWidth, nominalHeight);
427 const GlyphInfo& FontClient::GetEllipsisGlyph(PointSize26Dot6 requestedPointSize)
431 return mPlugin->GetEllipsisGlyph(requestedPointSize);
434 bool FontClient::IsColorGlyph(FontId fontId, GlyphIndex glyphIndex)
438 return mPlugin->IsColorGlyph(fontId, glyphIndex);
441 GlyphIndex FontClient::CreateEmbeddedItem(const TextAbstraction::FontClient::EmbeddedItemDescription& description, Pixel::Format& pixelFormat)
445 return mPlugin->CreateEmbeddedItem(description, pixelFormat);
448 void FontClient::EnableAtlasLimitation(bool enabled)
451 return mPlugin->EnableAtlasLimitation(enabled);
454 bool FontClient::IsAtlasLimitationEnabled() const
458 return mPlugin->IsAtlasLimitationEnabled();
460 return TextAbstraction::FontClient::DEFAULT_ATLAS_LIMITATION_ENABLED;
463 Size FontClient::GetMaximumTextAtlasSize() const
467 return mPlugin->GetMaximumTextAtlasSize();
469 return TextAbstraction::FontClient::MAX_TEXT_ATLAS_SIZE;
472 Size FontClient::GetDefaultTextAtlasSize() const
476 return mPlugin->GetDefaultTextAtlasSize();
478 return TextAbstraction::FontClient::DEFAULT_TEXT_ATLAS_SIZE;
481 Size FontClient::GetCurrentMaximumBlockSizeFitInAtlas() const
485 return mPlugin->GetCurrentMaximumBlockSizeFitInAtlas();
487 return TextAbstraction::FontClient::DEFAULT_TEXT_ATLAS_SIZE;
490 bool FontClient::SetCurrentMaximumBlockSizeFitInAtlas(const Size& currentMaximumBlockSizeFitInAtlas)
493 return mPlugin->SetCurrentMaximumBlockSizeFitInAtlas(currentMaximumBlockSizeFitInAtlas);
496 uint32_t FontClient::GetNumberOfPointsPerOneUnitOfPointSize() const
500 return mPlugin->GetNumberOfPointsPerOneUnitOfPointSize();
502 return TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;
506 FT_FaceRec_* FontClient::GetFreetypeFace(FontId fontId)
510 return mPlugin->GetFreetypeFace(fontId);
513 FontDescription::Type FontClient::GetFontType(FontId fontId)
517 return mPlugin->GetFontType(fontId);
520 bool FontClient::AddCustomFontDirectory(const FontPath& path)
524 return mPlugin->AddCustomFontDirectory(path);
527 HarfBuzzFontHandle FontClient::GetHarfBuzzFont(FontId fontId)
531 return mPlugin->GetHarfBuzzFont(fontId);
534 void FontClient::CreatePlugin()
538 mPlugin = new Plugin(mDpiHorizontal, mDpiVertical);
542 } // namespace Internal
544 } // namespace TextAbstraction