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::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);
115 gFontPreCacheAvailable = false;
117 uint32_t horizontalDpi, verticalDpi;
118 fontClientHandle.GetDpi(horizontalDpi, verticalDpi);
119 if(horizontalDpi == 0u || verticalDpi == 0u)
121 horizontalDpi = verticalDpi = 0u;
122 Dali::Internal::Adaptor::WindowSystem::GetDpi(horizontalDpi, verticalDpi);
123 fontClientHandle.SetDpi(horizontalDpi, verticalDpi);
126 service.Register(typeid(fontClientHandle), fontClientHandle);
130 return fontClientHandle;
133 Dali::TextAbstraction::FontClient FontClient::PreInitialize()
135 gPreInitializedFontClient = Dali::TextAbstraction::FontClient(new FontClient);
137 // Make DefaultFontDescription cached
138 Dali::TextAbstraction::FontDescription defaultFontDescription;
139 gPreInitializedFontClient.GetDefaultPlatformFontDescription(defaultFontDescription);
141 return gPreInitializedFontClient;
144 void FontClient::PreCacheRun(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily)
146 if(!gPreCachedFontClient)
148 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "BEGIN: DALI_TEXT_PRECACHE_RUN\n");
149 Dali::TextAbstraction::FontClient fontClient = Dali::TextAbstraction::FontClient(new FontClient);
150 GetImplementation(fontClient).FontPreCache(fallbackFamilyList, extraFamilyList, localeFamily);
151 gPreCachedFontClient = fontClient;
152 gFontPreCacheAvailable = false;
153 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "END: DALI_TEXT_PRECACHE_RUN\n");
157 FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient pre-cache run failed, as a pre-cached font client already exists.\n");
161 void FontClient::PreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily, bool useThread)
163 if(!gFontPreCacheAvailable)
165 FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient pre-cache has been completed or the font client has already been created.\n");
169 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache fallbackFamilyList : %zu\n", fallbackFamilyList.size());
170 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache extraFamilyList : %zu\n", extraFamilyList.size());
171 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache localeFamily : %s\n", localeFamily.c_str());
172 FONT_LOG_MESSAGE(Dali::Integration::Log::INFO, "FontClient PreCache useThread : %d\n", useThread);
174 if(gPreCacheThread.joinable())
176 FONT_LOG_MESSAGE(Dali::Integration::Log::ERROR, "FontClient pre-cache thread already running.\n");
182 gPreCacheThread = std::thread(PreCacheRun, fallbackFamilyList, extraFamilyList, localeFamily);
186 PreCacheRun(fallbackFamilyList, extraFamilyList, localeFamily);
191 void FontClient::ClearCache()
195 mPlugin->ClearCache();
199 void FontClient::SetDpi(unsigned int horizontalDpi, unsigned int verticalDpi)
201 mDpiHorizontal = horizontalDpi;
202 mDpiVertical = verticalDpi;
204 // Allow DPI to be set without loading plugin
207 mPlugin->SetDpi(horizontalDpi, verticalDpi);
211 void FontClient::GetDpi(unsigned int& horizontalDpi, unsigned int& verticalDpi)
213 horizontalDpi = mDpiHorizontal;
214 verticalDpi = mDpiVertical;
217 int FontClient::GetDefaultFontSize()
221 #if defined(VCONF_ENABLED)
222 vconf_get_int(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, &fontSize);
228 void FontClient::ResetSystemDefaults()
232 mPlugin->ResetSystemDefaults();
235 void FontClient::GetDefaultFonts(FontList& defaultFonts)
239 mPlugin->GetDefaultFonts(defaultFonts);
242 void FontClient::FontPreCache(const FontFamilyList& fallbackFamilyList, const FontFamilyList& extraFamilyList, const FontFamily& localeFamily)
246 mPlugin->FontPreCache(fallbackFamilyList, extraFamilyList, localeFamily);
249 void FontClient::GetDefaultPlatformFontDescription(FontDescription& fontDescription)
253 mPlugin->GetDefaultPlatformFontDescription(fontDescription);
256 void FontClient::GetDescription(FontId fontId, FontDescription& fontDescription)
260 mPlugin->GetDescription(fontId, fontDescription);
263 PointSize26Dot6 FontClient::GetPointSize(FontId fontId)
267 return mPlugin->GetPointSize(fontId);
270 bool FontClient::IsCharacterSupportedByFont(FontId fontId, Character character)
274 return mPlugin->IsCharacterSupportedByFont(fontId, character);
277 void FontClient::GetSystemFonts(FontList& systemFonts)
281 mPlugin->GetSystemFonts(systemFonts);
284 FontId FontClient::FindDefaultFont(Character charcode,
285 PointSize26Dot6 requestedPointSize,
290 return mPlugin->FindDefaultFont(charcode,
295 FontId FontClient::FindFallbackFont(Character charcode,
296 const FontDescription& preferredFontDescription,
297 PointSize26Dot6 requestedPointSize,
302 return mPlugin->FindFallbackFont(charcode,
303 preferredFontDescription,
308 bool FontClient::IsScalable(const FontPath& path)
312 return mPlugin->IsScalable(path);
315 bool FontClient::IsScalable(const FontDescription& fontDescription)
319 return mPlugin->IsScalable(fontDescription);
322 void FontClient::GetFixedSizes(const FontPath& path, Dali::Vector<PointSize26Dot6>& sizes)
326 mPlugin->GetFixedSizes(path, sizes);
329 void FontClient::GetFixedSizes(const FontDescription& fontDescription,
330 Dali::Vector<PointSize26Dot6>& sizes)
334 mPlugin->GetFixedSizes(fontDescription, sizes);
337 bool FontClient::HasItalicStyle(FontId fontId) const
343 return mPlugin->HasItalicStyle(fontId);
346 FontId FontClient::GetFontId(const FontPath& path, PointSize26Dot6 requestedPointSize, FaceIndex faceIndex)
350 return mPlugin->GetFontIdByPath(path,
356 FontId FontClient::GetFontId(const FontDescription& fontDescription,
357 PointSize26Dot6 requestedPointSize,
362 return mPlugin->GetFontId(fontDescription,
367 FontId FontClient::GetFontId(const BitmapFont& bitmapFont)
371 return mPlugin->GetFontId(bitmapFont);
374 void FontClient::GetFontMetrics(FontId fontId, FontMetrics& metrics)
378 mPlugin->GetFontMetrics(fontId, metrics);
381 GlyphIndex FontClient::GetGlyphIndex(FontId fontId, Character charcode)
385 return mPlugin->GetGlyphIndex(fontId, charcode);
388 GlyphIndex FontClient::GetGlyphIndex(FontId fontId, Character charcode, Character variantSelector)
392 return mPlugin->GetGlyphIndex(fontId, charcode, variantSelector);
395 bool FontClient::GetGlyphMetrics(GlyphInfo* array, uint32_t size, GlyphType type, bool horizontal)
399 return mPlugin->GetGlyphMetrics(array, size, type, horizontal);
402 void FontClient::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, bool isItalicRequired, bool isBoldRequired, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth)
406 mPlugin->CreateBitmap(fontId, glyphIndex, isItalicRequired, isBoldRequired, data, outlineWidth);
409 PixelData FontClient::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, int outlineWidth)
413 return mPlugin->CreateBitmap(fontId, glyphIndex, outlineWidth);
416 void FontClient::CreateVectorBlob(FontId fontId, GlyphIndex glyphIndex, VectorBlob*& blob, unsigned int& blobLength, unsigned int& nominalWidth, unsigned int& nominalHeight)
420 mPlugin->CreateVectorBlob(fontId, glyphIndex, blob, blobLength, nominalWidth, nominalHeight);
423 const GlyphInfo& FontClient::GetEllipsisGlyph(PointSize26Dot6 requestedPointSize)
427 return mPlugin->GetEllipsisGlyph(requestedPointSize);
430 bool FontClient::IsColorGlyph(FontId fontId, GlyphIndex glyphIndex)
434 return mPlugin->IsColorGlyph(fontId, glyphIndex);
437 GlyphIndex FontClient::CreateEmbeddedItem(const TextAbstraction::FontClient::EmbeddedItemDescription& description, Pixel::Format& pixelFormat)
441 return mPlugin->CreateEmbeddedItem(description, pixelFormat);
444 void FontClient::EnableAtlasLimitation(bool enabled)
447 return mPlugin->EnableAtlasLimitation(enabled);
450 bool FontClient::IsAtlasLimitationEnabled() const
454 return mPlugin->IsAtlasLimitationEnabled();
456 return TextAbstraction::FontClient::DEFAULT_ATLAS_LIMITATION_ENABLED;
459 Size FontClient::GetMaximumTextAtlasSize() const
463 return mPlugin->GetMaximumTextAtlasSize();
465 return TextAbstraction::FontClient::MAX_TEXT_ATLAS_SIZE;
468 Size FontClient::GetDefaultTextAtlasSize() const
472 return mPlugin->GetDefaultTextAtlasSize();
474 return TextAbstraction::FontClient::DEFAULT_TEXT_ATLAS_SIZE;
477 Size FontClient::GetCurrentMaximumBlockSizeFitInAtlas() const
481 return mPlugin->GetCurrentMaximumBlockSizeFitInAtlas();
483 return TextAbstraction::FontClient::DEFAULT_TEXT_ATLAS_SIZE;
486 bool FontClient::SetCurrentMaximumBlockSizeFitInAtlas(const Size& currentMaximumBlockSizeFitInAtlas)
489 return mPlugin->SetCurrentMaximumBlockSizeFitInAtlas(currentMaximumBlockSizeFitInAtlas);
492 uint32_t FontClient::GetNumberOfPointsPerOneUnitOfPointSize() const
496 return mPlugin->GetNumberOfPointsPerOneUnitOfPointSize();
498 return TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;
502 FT_FaceRec_* FontClient::GetFreetypeFace(FontId fontId)
506 return mPlugin->GetFreetypeFace(fontId);
509 FontDescription::Type FontClient::GetFontType(FontId fontId)
513 return mPlugin->GetFontType(fontId);
516 bool FontClient::AddCustomFontDirectory(const FontPath& path)
520 return mPlugin->AddCustomFontDirectory(path);
523 HarfBuzzFontHandle FontClient::GetHarfBuzzFont(FontId fontId)
527 return mPlugin->GetHarfBuzzFont(fontId);
530 void FontClient::CreatePlugin()
534 mPlugin = new Plugin(mDpiHorizontal, mDpiVertical);
538 } // namespace Internal
540 } // namespace TextAbstraction