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>
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::gPreCreatedFontClient(NULL);
57 std::thread gPreCacheThread;
58 /* TODO: This is to prevent duplicate calls of font pre-cache.
59 * We may support this later, but currently we can't guarantee the behaviour
60 * if there is a pre-cache call from the user after the font client has been created. */
61 bool gFontPreCacheAvailable = true;
63 FontClient::FontClient()
70 FontClient::~FontClient()
75 Dali::TextAbstraction::FontClient FontClient::Get()
77 Dali::TextAbstraction::FontClient fontClientHandle;
79 Dali::SingletonService service(SingletonService::Get());
82 // Check whether the singleton is already created
83 Dali::BaseHandle handle = service.GetSingleton(typeid(Dali::TextAbstraction::FontClient));
86 // If so, downcast the handle
87 FontClient* impl = dynamic_cast<Dali::TextAbstraction::Internal::FontClient*>(handle.GetObjectPtr());
88 fontClientHandle = Dali::TextAbstraction::FontClient(impl);
90 else // create and register the object
92 if(gPreCacheThread.joinable())
94 gPreCacheThread.join();
95 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache thread join\n");
98 if(gPreCreatedFontClient)
100 fontClientHandle = gPreCreatedFontClient;
101 gPreCreatedFontClient.Reset(); // No longer needed
105 fontClientHandle = Dali::TextAbstraction::FontClient(new FontClient);
107 // Make DefaultFontDescription cached
108 Dali::TextAbstraction::FontDescription defaultFontDescription;
109 fontClientHandle.GetDefaultPlatformFontDescription(defaultFontDescription);
112 gFontPreCacheAvailable = false;
114 uint32_t horizontalDpi, verticalDpi;
115 fontClientHandle.GetDpi(horizontalDpi, verticalDpi);
116 if(horizontalDpi == 0u || verticalDpi == 0u)
118 horizontalDpi = verticalDpi = 0u;
119 Dali::Internal::Adaptor::WindowSystem::GetDpi(horizontalDpi, verticalDpi);
120 fontClientHandle.SetDpi(horizontalDpi, verticalDpi);
123 service.Register(typeid(fontClientHandle), fontClientHandle);
127 return fontClientHandle;
130 Dali::TextAbstraction::FontClient FontClient::PreInitialize()
132 // Pre-cached font client already exists or pre-cache thread already running.
133 // Font client pre-cache includes caching of the default font description.
134 if((gPreCreatedFontClient && !gFontPreCacheAvailable) ||
135 (gPreCacheThread.joinable()))
137 return gPreCreatedFontClient;
140 gPreCreatedFontClient = Dali::TextAbstraction::FontClient(new FontClient);
142 // Make DefaultFontDescription cached
143 Dali::TextAbstraction::FontDescription defaultFontDescription;
144 gPreCreatedFontClient.GetDefaultPlatformFontDescription(defaultFontDescription);
146 return gPreCreatedFontClient;
149 void FontClient::PreCacheRun(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily)
151 if(gFontPreCacheAvailable)
153 gFontPreCacheAvailable = false;
154 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "BEGIN: DALI_TEXT_PRECACHE_RUN\n");
155 if(!gPreCreatedFontClient)
157 gPreCreatedFontClient = Dali::TextAbstraction::FontClient(new FontClient);
159 GetImplementation(gPreCreatedFontClient).FontPreCache(fallbackFamilyList, extraFamilyList, localeFamily);
160 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "END: DALI_TEXT_PRECACHE_RUN\n");
164 FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient pre-cache run failed, as a pre-cached font client already exists.\n");
168 void FontClient::PreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool useThread)
170 if(!gFontPreCacheAvailable)
172 FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient pre-cache has been completed or the font client has already been created.\n");
176 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache fallbackFamilyList : %zu\n", fallbackFamilyList.size());
177 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache extraFamilyList : %zu\n", extraFamilyList.size());
178 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache localeFamily : %s\n", localeFamily.c_str());
179 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache useThread : %d\n", useThread);
181 if(gPreCacheThread.joinable())
183 FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient pre-cache thread already running.\n");
189 gPreCacheThread = std::thread(PreCacheRun, fallbackFamilyList, extraFamilyList, localeFamily);
193 PreCacheRun(fallbackFamilyList, extraFamilyList, localeFamily);
198 void FontClient::ClearCache()
202 mPlugin->ClearCache();
206 void FontClient::SetDpi(unsigned int horizontalDpi, unsigned int verticalDpi)
208 mDpiHorizontal = horizontalDpi;
209 mDpiVertical = verticalDpi;
211 // Allow DPI to be set without loading plugin
214 mPlugin->SetDpi(horizontalDpi, verticalDpi);
218 void FontClient::GetDpi(unsigned int& horizontalDpi, unsigned int& verticalDpi)
220 horizontalDpi = mDpiHorizontal;
221 verticalDpi = mDpiVertical;
224 int FontClient::GetDefaultFontSize()
228 #if defined(VCONF_ENABLED)
229 vconf_get_int(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, &fontSize);
235 void FontClient::ResetSystemDefaults()
239 mPlugin->ResetSystemDefaults();
242 void FontClient::GetDefaultFonts(FontList& defaultFonts)
246 mPlugin->GetDefaultFonts(defaultFonts);
249 void FontClient::FontPreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily)
253 mPlugin->FontPreCache(fallbackFamilyList, extraFamilyList, localeFamily);
256 void FontClient::GetDefaultPlatformFontDescription(FontDescription& fontDescription)
260 mPlugin->GetDefaultPlatformFontDescription(fontDescription);
263 void FontClient::GetDescription(FontId fontId, FontDescription& fontDescription)
267 mPlugin->GetDescription(fontId, fontDescription);
270 PointSize26Dot6 FontClient::GetPointSize(FontId fontId)
274 return mPlugin->GetPointSize(fontId);
277 bool FontClient::IsCharacterSupportedByFont(FontId fontId, Character character)
281 return mPlugin->IsCharacterSupportedByFont(fontId, character);
284 void FontClient::GetSystemFonts(FontList& systemFonts)
288 mPlugin->GetSystemFonts(systemFonts);
291 FontId FontClient::FindDefaultFont(Character charcode,
292 PointSize26Dot6 requestedPointSize,
297 return mPlugin->FindDefaultFont(charcode,
302 FontId FontClient::FindFallbackFont(Character charcode,
303 const FontDescription& preferredFontDescription,
304 PointSize26Dot6 requestedPointSize,
309 return mPlugin->FindFallbackFont(charcode,
310 preferredFontDescription,
315 bool FontClient::IsScalable(const FontPath& path)
319 return mPlugin->IsScalable(path);
322 bool FontClient::IsScalable(const FontDescription& fontDescription)
326 return mPlugin->IsScalable(fontDescription);
329 void FontClient::GetFixedSizes(const FontPath& path, Dali::Vector<PointSize26Dot6>& sizes)
333 mPlugin->GetFixedSizes(path, sizes);
336 void FontClient::GetFixedSizes(const FontDescription& fontDescription,
337 Dali::Vector<PointSize26Dot6>& sizes)
341 mPlugin->GetFixedSizes(fontDescription, sizes);
344 bool FontClient::HasItalicStyle(FontId fontId) const
350 return mPlugin->HasItalicStyle(fontId);
353 FontId FontClient::GetFontId(const FontPath& path, PointSize26Dot6 requestedPointSize, FaceIndex faceIndex)
357 return mPlugin->GetFontIdByPath(path,
363 FontId FontClient::GetFontId(const FontDescription& fontDescription,
364 PointSize26Dot6 requestedPointSize,
369 return mPlugin->GetFontId(fontDescription,
374 FontId FontClient::GetFontId(const BitmapFont& bitmapFont)
378 return mPlugin->GetFontId(bitmapFont);
381 void FontClient::GetFontMetrics(FontId fontId, FontMetrics& metrics)
385 mPlugin->GetFontMetrics(fontId, metrics);
388 GlyphIndex FontClient::GetGlyphIndex(FontId fontId, Character charcode)
392 return mPlugin->GetGlyphIndex(fontId, charcode);
395 GlyphIndex FontClient::GetGlyphIndex(FontId fontId, Character charcode, Character variantSelector)
399 return mPlugin->GetGlyphIndex(fontId, charcode, variantSelector);
402 bool FontClient::GetGlyphMetrics(GlyphInfo* array, uint32_t size, GlyphType type, bool horizontal)
406 return mPlugin->GetGlyphMetrics(array, size, type, horizontal);
409 void FontClient::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, bool isItalicRequired, bool isBoldRequired, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth)
413 mPlugin->CreateBitmap(fontId, glyphIndex, isItalicRequired, isBoldRequired, data, outlineWidth);
416 PixelData FontClient::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, int outlineWidth)
420 return mPlugin->CreateBitmap(fontId, glyphIndex, outlineWidth);
423 void FontClient::CreateVectorBlob(FontId fontId, GlyphIndex glyphIndex, VectorBlob*& blob, unsigned int& blobLength, unsigned int& nominalWidth, unsigned int& nominalHeight)
427 mPlugin->CreateVectorBlob(fontId, glyphIndex, blob, blobLength, nominalWidth, nominalHeight);
430 const GlyphInfo& FontClient::GetEllipsisGlyph(PointSize26Dot6 requestedPointSize)
434 return mPlugin->GetEllipsisGlyph(requestedPointSize);
437 bool FontClient::IsColorGlyph(FontId fontId, GlyphIndex glyphIndex)
441 return mPlugin->IsColorGlyph(fontId, glyphIndex);
444 GlyphIndex FontClient::CreateEmbeddedItem(const TextAbstraction::FontClient::EmbeddedItemDescription& description, Pixel::Format& pixelFormat)
448 return mPlugin->CreateEmbeddedItem(description, pixelFormat);
451 void FontClient::EnableAtlasLimitation(bool enabled)
454 return mPlugin->EnableAtlasLimitation(enabled);
457 bool FontClient::IsAtlasLimitationEnabled() const
461 return mPlugin->IsAtlasLimitationEnabled();
463 return TextAbstraction::FontClient::DEFAULT_ATLAS_LIMITATION_ENABLED;
466 Size FontClient::GetMaximumTextAtlasSize() const
470 return mPlugin->GetMaximumTextAtlasSize();
472 return TextAbstraction::FontClient::MAX_TEXT_ATLAS_SIZE;
475 Size FontClient::GetDefaultTextAtlasSize() const
479 return mPlugin->GetDefaultTextAtlasSize();
481 return TextAbstraction::FontClient::DEFAULT_TEXT_ATLAS_SIZE;
484 Size FontClient::GetCurrentMaximumBlockSizeFitInAtlas() const
488 return mPlugin->GetCurrentMaximumBlockSizeFitInAtlas();
490 return TextAbstraction::FontClient::DEFAULT_TEXT_ATLAS_SIZE;
493 bool FontClient::SetCurrentMaximumBlockSizeFitInAtlas(const Size& currentMaximumBlockSizeFitInAtlas)
496 return mPlugin->SetCurrentMaximumBlockSizeFitInAtlas(currentMaximumBlockSizeFitInAtlas);
499 uint32_t FontClient::GetNumberOfPointsPerOneUnitOfPointSize() const
503 return mPlugin->GetNumberOfPointsPerOneUnitOfPointSize();
505 return TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;
509 FT_FaceRec_* FontClient::GetFreetypeFace(FontId fontId)
513 return mPlugin->GetFreetypeFace(fontId);
516 FontDescription::Type FontClient::GetFontType(FontId fontId)
520 return mPlugin->GetFontType(fontId);
523 bool FontClient::AddCustomFontDirectory(const FontPath& path)
527 return mPlugin->AddCustomFontDirectory(path);
530 HarfBuzzFontHandle FontClient::GetHarfBuzzFont(FontId fontId)
534 return mPlugin->GetHarfBuzzFont(fontId);
537 void FontClient::CreatePlugin()
541 mPlugin = new Plugin(mDpiHorizontal, mDpiVertical);
545 } // namespace Internal
547 } // namespace TextAbstraction