+++ /dev/null
-#ifndef DALI_VECTOR_IMAGE_RENDERER_PLUGIN_H
-#define DALI_VECTOR_IMAGE_RENDERER_PLUGIN_H
-
-/*
- * Copyright (c) 2021 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
-
-namespace Dali
-{
-/**
- * VectorImageRendererPlugin is an abstract interface, used by dali-adaptor to render a vector image(SVG).
- * A concrete implementation must be created for each platform and provided as a dynamic library which
- * will be loaded at run time by the adaptor.
- */
-class VectorImageRendererPlugin
-{
-public:
- /**
- * @brief Constructor
- */
- VectorImageRendererPlugin()
- {
- }
-
- /**
- * @brief Destructor
- */
- virtual ~VectorImageRendererPlugin()
- {
- }
-
- /**
- * @brief Load vector image data directly.
- *
- * @param[in] data The memory data of vector image
- * @return True if the load success, false otherwise.
- */
- virtual bool Load(const Vector<uint8_t>& data) = 0;
-
- /**
- * @brief Rasterizes the content to the target buffer synchronously.
- *
- * @param[in] buffer The target buffer
- * @return True if the rendering succeeds, false otherwise.
- */
- virtual bool Rasterize(Dali::Devel::PixelBuffer& buffer) = 0;
-
- /**
- * @brief Gets the default size of the file.
- *
- * @param[out] width The default width of the file
- * @param[out] height The default height of the file
- */
- virtual void GetDefaultSize(uint32_t& width, uint32_t& height) const = 0;
-
- /**
- * @brief Function pointer called in adaptor to create a plugin instance.
- */
- using CreateVectorImageRendererFunction = VectorImageRendererPlugin* (*)();
-};
-
-} // namespace Dali
-
-#endif // DALI_VECTOR_IMAGE_RENDERER_PLUGIN_H
${adaptor_devel_api_dir}/adaptor-framework/vector-animation-renderer.h
${adaptor_devel_api_dir}/adaptor-framework/vector-animation-renderer-plugin.h
${adaptor_devel_api_dir}/adaptor-framework/vector-image-renderer.h
- ${adaptor_devel_api_dir}/adaptor-framework/vector-image-renderer-plugin.h
${adaptor_devel_api_dir}/adaptor-framework/video-player.h
${adaptor_devel_api_dir}/adaptor-framework/video-player-plugin.h
${adaptor_devel_api_dir}/adaptor-framework/web-engine.h
LOG_UPDATE_RENDER_TRACE;
// For thread safe
- bool uploadOnly = mUploadWithoutRendering;
+ bool uploadOnly = mUploadWithoutRendering;
+ unsigned int surfaceResized = mSurfaceResized;
// Performance statistics are logged upon a VSYNC tick so use this point for a VSync marker
AddPerformanceMarker(PerformanceInterface::VSYNC);
// Upload shared resources
mCore.PreRender(renderStatus, mForceClear);
- if(!uploadOnly)
+ if(!uploadOnly || surfaceResized)
{
// Go through each window
WindowContainer windows;
#endif
mApplicationType = type;
mCallbackManager = CallbackManager::New();
-
- char* region = nullptr;
- char* language = nullptr;
- system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_COUNTRY, ®ion);
- system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &language);
-
- if(region != nullptr)
- {
- mRegion = std::string(region);
- free(region);
- }
-
- if(language != nullptr)
- {
- mLanguage = std::string(language);
- free(language);
- }
}
~Impl()
mRegion = region;
}
- std::string GetLanguage() const
+ std::string GetLanguage()
{
+ if(mLanguage.empty())
+ {
+ char* language = nullptr;
+ system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &language);
+
+ if(language != nullptr)
+ {
+ mLanguage = std::string(language);
+ free(language);
+ }
+ }
return mLanguage;
}
- std::string GetRegion() const
+ std::string GetRegion()
{
+ if(mRegion.empty())
+ {
+ char* region = nullptr;
+ system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_COUNTRY, ®ion);
+
+ if(region != nullptr)
+ {
+ mRegion = std::string(region);
+ free(region);
+ }
+ }
return mRegion;
}
Type mApplicationType;
CallbackBase* mAbortCallBack;
CallbackManager* mCallbackManager;
- std::string mLanguage;
- std::string mRegion;
+ std::string mLanguage{};
+ std::string mRegion{};
Framework* mFramework;
AppCore::AppEventHandlerPtr handlers[5];
for(unsigned int pixel = 0, outPixel = 0; pixel <= lastPair; pixel += 2, ++outPixel)
{
- const uint32_t averaged = AveragePixelRGB565(alignedPixels[pixel], alignedPixels[pixel + 1]);
+ const uint16_t averaged = AveragePixelRGB565(alignedPixels[pixel], alignedPixels[pixel + 1]);
alignedPixels[outPixel] = averaged;
}
}
/**
* @copydoc AverageScanlines1
* @note This API average eight components in one operation.
+ * @note Only possible if each scanline pointer's address aligned
* It will give performance benifit.
*/
inline void AverageScanlinesWithEightComponents(
unsigned int component = 0;
if(DALI_LIKELY(totalComponentCount >= 8))
{
- // Jump 8 components in one step
- const std::uint64_t* const scanline18Step = reinterpret_cast<const std::uint64_t* const>(scanline1);
- const std::uint64_t* const scanline28Step = reinterpret_cast<const std::uint64_t* const>(scanline2);
- std::uint64_t* const output8step = reinterpret_cast<std::uint64_t* const>(outputScanline);
+ // Note reinsterpret_cast from uint8_t to uint64_t and read/write only allowed
+ // If pointer of data is aligned well.
+ if(((reinterpret_cast<std::ptrdiff_t>(scanline1) & (sizeof(std::uint64_t) - 1)) == 0) &&
+ ((reinterpret_cast<std::ptrdiff_t>(scanline2) & (sizeof(std::uint64_t) - 1)) == 0) &&
+ ((reinterpret_cast<std::ptrdiff_t>(outputScanline) & (sizeof(std::uint64_t) - 1)) == 0))
+ {
+ // Jump 8 components in one step
+ const std::uint64_t* const scanline18Step = reinterpret_cast<const std::uint64_t* const>(scanline1);
+ const std::uint64_t* const scanline28Step = reinterpret_cast<const std::uint64_t* const>(scanline2);
+ std::uint64_t* const output8step = reinterpret_cast<std::uint64_t* const>(outputScanline);
- const std::uint32_t totalStepCount = (totalComponentCount) >> 3;
- component = totalStepCount << 3;
+ const std::uint32_t totalStepCount = (totalComponentCount) >> 3;
+ component = totalStepCount << 3;
- // and for each step, calculate average of 8 bytes.
- for(std::uint32_t i = 0; i < totalStepCount; ++i)
- {
- const auto& c1 = *(scanline18Step + i);
- const auto& c2 = *(scanline28Step + i);
- *(output8step + i) = static_cast<std::uint64_t>((((c1 ^ c2) & 0xfefefefefefefefeull) >> 1) + (c1 & c2));
+ // and for each step, calculate average of 8 bytes.
+ for(std::uint32_t i = 0; i < totalStepCount; ++i)
+ {
+ const auto& c1 = *(scanline18Step + i);
+ const auto& c2 = *(scanline28Step + i);
+ *(output8step + i) = static_cast<std::uint64_t>((((c1 ^ c2) & 0xfefefefefefefefeull) >> 1) + (c1 & c2));
+ }
}
}
// remaining components calculate
// Find the two scanlines to blend and the weight to blend with:
const unsigned int integerY1 = inY >> 16u;
- const unsigned int integerY2 = integerY1 >= inputHeight ? integerY1 : integerY1 + 1;
+ const unsigned int integerY2 = integerY1 + 1 >= inputHeight ? integerY1 : integerY1 + 1;
const unsigned int inputYWeight = inY & 65535u;
DALI_ASSERT_DEBUG(integerY1 < inputHeight);
{
// Work out the two pixel scanline offsets for this cluster of four samples:
const unsigned int integerX1 = inX >> 16u;
- const unsigned int integerX2 = integerX1 >= inputWidth ? integerX1 : integerX1 + 1;
+ const unsigned int integerX2 = integerX1 + 1 >= inputWidth ? integerX1 : integerX1 + 1;
// Execute the loads:
const PIXEL pixel1 = inScanline1[integerX1];
* @endcode
*/
- const std::uint8_t* inputPixels = inputBufferPtr + position;
- const std::uint32_t lineByteLengthWithoutPadding = w >> 3;
- const std::uint8_t linePadding = w & 0x07;
+ const std::uint8_t* inputPixels = inputBufferPtr + position;
+ const std::uint32_t lineBitLengthWithoutPadding = (w >> 3) << 3;
for(std::uint32_t y = 0; y < h; ++y)
{
- for(std::uint32_t x = 0; x < lineByteLengthWithoutPadding; ++x)
+ std::uint32_t x = 0;
+ if((reinterpret_cast<std::ptrdiff_t>(outputPixels) & (sizeof(std::uint32_t) - 1)) == 0)
{
- // memset whole 8 bits
- // outputPixels filled 4 bytes in one operation.
- // cachedCalculation4BitTo4ByteTable calculated in compile-time.
- *(reinterpret_cast<std::uint32_t*>(outputPixels + 0)) = cachedCalculation4BitTo4ByteTable[((*inputPixels) >> 4) & 0x0f];
- *(reinterpret_cast<std::uint32_t*>(outputPixels + 4)) = cachedCalculation4BitTo4ByteTable[(*inputPixels) & 0x0f];
- outputPixels += 8;
- ++inputPixels;
+ for(; x < lineBitLengthWithoutPadding; x += 8)
+ {
+ // memset whole 8 bits
+ // outputPixels filled 4 bytes in one operation.
+ // cachedCalculation4BitTo4ByteTable calculated in compile-time.
+ *(reinterpret_cast<std::uint32_t*>(outputPixels + 0)) = cachedCalculation4BitTo4ByteTable[((*inputPixels) >> 4) & 0x0f];
+ *(reinterpret_cast<std::uint32_t*>(outputPixels + 4)) = cachedCalculation4BitTo4ByteTable[(*inputPixels) & 0x0f];
+ outputPixels += 8;
+ ++inputPixels;
+ }
}
- if(linePadding > 0)
{
// memset linePadding bits naive.
- for(std::uint8_t x = 0; x < linePadding; ++x)
+ for(; x < w; ++x)
{
const std::uint8_t offset = (0x07 - (x & 0x07));
*outputPixels = ((*inputPixels) >> offset) & 1 ? 0xff : 0x00;
++outputPixels;
+ if(offset == 0)
+ {
+ ++inputPixels;
+ }
}
- ++inputPixels;
}
}
mWebPData.bytes = mBuffer;
WebPDemuxer* demuxer = WebPDemux(&mWebPData);
- uint32_t flags = WebPDemuxGetI(demuxer, WEBP_FF_FORMAT_FLAGS);
+ uint32_t flags = WebPDemuxGetI(demuxer, WEBP_FF_FORMAT_FLAGS);
if(flags & ANIMATION_FLAG)
{
mIsAnimatedImage = true;
bool mIsLocalResource;
#ifdef DALI_WEBP_AVAILABLE
- WebPData mWebPData{0};
+ WebPData mWebPData{0};
#endif
#ifdef DALI_ANIMATED_WEBP_ENABLED
{
Dali::Devel::PixelBuffer pixelBuffer;
#ifdef DALI_ANIMATED_WEBP_ENABLED
- if(mImpl->mLatestLoadedFrame > static_cast<int32_t>(frameIndex))
+ if(mImpl->mLatestLoadedFrame >= static_cast<int32_t>(frameIndex))
{
mImpl->mLatestLoadedFrame = INITIAL_INDEX;
WebPAnimDecoderReset(mImpl->mWebPAnimDecoder);
${adaptor_text_dir}/text-abstraction/plugin/font-client-plugin-impl.cpp
${adaptor_text_dir}/text-abstraction/plugin/font-face-cache-item.cpp
${adaptor_text_dir}/text-abstraction/plugin/font-face-glyph-cache-manager.cpp
+ ${adaptor_text_dir}/text-abstraction/plugin/harfbuzz-proxy-font.cpp
)
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
return mPlugin->AddCustomFontDirectory(path);
}
+HarfBuzzFontHandle FontClient::GetHarfBuzzFont(FontId fontId)
+{
+ CreatePlugin();
+
+ return mPlugin->GetHarfBuzzFont(fontId);
+}
+
void FontClient::CreatePlugin()
{
if(!mPlugin)
#define DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_IMPL_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
{
namespace Internal
{
+using HarfBuzzFontHandle = void*; ///< @note We don't want to make other class include harfbuzz header. So we will keep harfbuzz font data as HarfBuzzFontHandle.
+
/**
* Implementation of the FontClient
*/
*/
~FontClient();
+public: // API for Dali::TextAbstraction::FontClient used.
/**
* @copydoc Dali::TextAbstraction::FontClient::Get()
*/
uint32_t GetNumberOfPointsPerOneUnitOfPointSize() const;
/**
+ * @copydoc Dali::TextAbstraction::FontClient::AddCustomFontDirectory()
+ */
+ bool AddCustomFontDirectory(const FontPath& path);
+
+public: // API for Dali::TextAbstraction::Internal::FontClient used.
+ /**
* @brief Retrieves the pointer to the FreeType Font Face for the given @p fontId.
*
* @param[in] fontId The font id.
FontDescription::Type GetFontType(FontId fontId);
/**
- * @copydoc Dali::TextAbstraction::FontClient::AddCustomFontDirectory()
+ * @brief Get the harfbuzz font data of font.
+ *
+ * @param fontId The font id.
+ * @return The harfbuzz font data, or nullptr if failed.
*/
- bool AddCustomFontDirectory(const FontPath& path);
+ HarfBuzzFontHandle GetHarfBuzzFont(FontId fontId);
private:
/**
}
/**
+ * @copydoc FontCacheItemInterface::GetHarfBuzzFont()
+ */
+ HarfBuzzFontHandle GetHarfBuzzFont(const uint32_t& horizontalDpi, const uint32_t& verticalDpi) override
+ {
+ return nullptr;
+ }
+
+ /**
* @copydoc FontCacheItemInterface::HasItalicStyle()
*/
bool HasItalicStyle() const override
* limitations under the License.
*/
+// INTERNAL INCLUDES
#include <dali/devel-api/text-abstraction/font-client.h>
#include <dali/devel-api/text-abstraction/font-metrics.h>
#include <dali/devel-api/text-abstraction/glyph-info.h>
+#include <dali/internal/text/text-abstraction/font-client-impl.h> // for HarfBuzzFontHandle
+// EXTERNAL INCLUDES
#include <ft2build.h>
#include FT_FREETYPE_H
virtual FT_Face GetTypeface() const = 0;
/**
+ * Get the harfbuzz font struct for this font.
+ *
+ * @param[in] horizontalDpi Horizontal DPI for this harfbuzz font.
+ * @param[in] verticalDpi Vertical DPI for this harfbuzz font.
+ * @return the harfbuzz font data, or nullptr if failed.
+ */
+ virtual HarfBuzzFontHandle GetHarfBuzzFont(const uint32_t& horizontalDpi, const uint32_t& verticalDpi) = 0;
+
+ /**
* @return true if this font has an italic style
*/
virtual bool HasItalicStyle() const = 0;
mVectorFontCache(nullptr),
mEllipsisCache(),
mEmbeddedItemCache(),
+ mLatestFoundFontDescription(),
+ mLatestFoundFontDescriptionId(0u),
+ mLatestFoundCacheKey(0, 0),
+ mLatestFoundCacheIndex(0u),
mDefaultFontDescriptionCached(false),
mIsAtlasLimitationEnabled(TextAbstraction::FontClient::DEFAULT_ATLAS_LIMITATION_ENABLED),
mCurrentMaximumBlockSizeFitInAtlas(TextAbstraction::FontClient::MAX_SIZE_FIT_IN_ATLAS)
mEmbeddedItemCache.Clear();
mBitmapFontCache.clear();
+ mLatestFoundFontDescription.family.clear();
+ mLatestFoundCacheKey = FontDescriptionSizeCacheKey(0, 0);
+
mDefaultFontDescriptionCached = false;
}
return FcConfigAppFontAddDir(nullptr, reinterpret_cast<const FcChar8*>(path.c_str()));
}
+HarfBuzzFontHandle FontClient::Plugin::GetHarfBuzzFont(FontId fontId)
+{
+ FontCacheItemInterface* fontCacheItem = const_cast<FontCacheItemInterface*>(GetCachedFontItem(fontId));
+ if(fontCacheItem != nullptr)
+ {
+ return fontCacheItem->GetHarfBuzzFont(mDpiHorizontal, mDpiVertical); // May cache
+ }
+ return nullptr;
+}
+
GlyphIndex FontClient::Plugin::CreateEmbeddedItem(const TextAbstraction::FontClient::EmbeddedItemDescription& description, Pixel::Format& pixelFormat)
{
EmbeddedItem embeddedItem;
fontDescriptionId = 0u;
+ // Fast cut if inputed family is empty.
+ if(DALI_UNLIKELY(fontDescription.family.empty()))
+ {
+ DALI_LOG_INFO(gFontClientLogFilter, Debug::General, " validated font description not found / fontDescription.family is empty!\n");
+ return false;
+ }
+
+ // Heuristic optimize code : Compare with latest found item.
+ if((fontDescription.width == mLatestFoundFontDescription.width) &&
+ (fontDescription.weight == mLatestFoundFontDescription.weight) &&
+ (fontDescription.slant == mLatestFoundFontDescription.slant) &&
+ (fontDescription.family == mLatestFoundFontDescription.family))
+ {
+ fontDescriptionId = mLatestFoundFontDescriptionId;
+
+ DALI_LOG_INFO(gFontClientLogFilter, Debug::General, " validated font description same as latest, id : %d\n", fontDescriptionId);
+ return true;
+ }
+
for(const auto& item : mValidatedFontCache)
{
- if(!fontDescription.family.empty() &&
- (fontDescription.family == item.fontDescription.family) &&
- (fontDescription.width == item.fontDescription.width) &&
+ if((fontDescription.width == item.fontDescription.width) &&
(fontDescription.weight == item.fontDescription.weight) &&
- (fontDescription.slant == item.fontDescription.slant))
+ (fontDescription.slant == item.fontDescription.slant) &&
+ (fontDescription.family == item.fontDescription.family))
{
fontDescriptionId = item.index;
+ mLatestFoundFontDescription = fontDescription;
+ mLatestFoundFontDescriptionId = fontDescriptionId;
+
DALI_LOG_INFO(gFontClientLogFilter, Debug::General, " validated font description found, id : %d\n", fontDescriptionId);
return true;
}
fontCacheIndex = 0u;
- FontDescriptionSizeCacheKey key(fontDescriptionId, requestedPointSize);
+ const FontDescriptionSizeCacheKey key(fontDescriptionId, requestedPointSize);
+
+ // Heuristic optimize code : Compare with latest found item.
+ if(key == mLatestFoundCacheKey)
+ {
+ fontCacheIndex = mLatestFoundCacheIndex;
+
+ DALI_LOG_INFO(gFontClientLogFilter, Debug::General, " font same as latest, index of font cache : %d\n", fontCacheIndex);
+ return true;
+ }
const auto& iter = mFontDescriptionSizeCache.find(key);
if(iter != mFontDescriptionSizeCache.cend())
{
fontCacheIndex = iter->second;
+ mLatestFoundCacheKey = key;
+ mLatestFoundCacheIndex = fontCacheIndex;
+
DALI_LOG_INFO(gFontClientLogFilter, Debug::General, " font found, index of font cache : %d\n", fontCacheIndex);
return true;
}
*/
bool AddCustomFontDirectory(const FontPath& path);
+ /**
+ * @copydoc Dali::TextAbstraction::FontClient::GetHarfBuzzFont()
+ */
+ HarfBuzzFontHandle GetHarfBuzzFont(FontId fontId);
+
private:
/**
* @brief Caches the fonts present in the platform.
Vector<EmbeddedItem> mEmbeddedItemCache; ///< Cache embedded items.
std::vector<BitmapFontCacheItem> mBitmapFontCache; ///< Stores bitmap fonts.
+ FontDescription mLatestFoundFontDescription; ///< Latest found font description and id in FindValidatedFont()
+ FontDescriptionId mLatestFoundFontDescriptionId;
+
+ FontDescriptionSizeCacheKey mLatestFoundCacheKey; ///< Latest found font description and id in FindFont()
+ FontCacheIndex mLatestFoundCacheIndex;
+
bool mDefaultFontDescriptionCached : 1; ///< Whether the default font is cached or not
bool mIsAtlasLimitationEnabled : 1; ///< Whether the validation on maximum atlas block size, then reduce block size to fit into it is enabled or not.
: mFreeTypeLibrary(freeTypeLibrary),
mFreeTypeFace(ftFace),
mGlyphCacheManager(new GlyphCacheManager(mFreeTypeFace, GetMaxNumberOfGlyphCache())),
+ mHarfBuzzProxyFont(),
mPath(path),
mRequestedPointSize(requestedPointSize),
mFaceIndex(face),
: mFreeTypeLibrary(freeTypeLibrary),
mFreeTypeFace(ftFace),
mGlyphCacheManager(new GlyphCacheManager(mFreeTypeFace, GetMaxNumberOfGlyphCache())),
+ mHarfBuzzProxyFont(),
mPath(path),
mRequestedPointSize(requestedPointSize),
mFaceIndex(face),
: mFreeTypeLibrary(rhs.mFreeTypeLibrary)
{
mFreeTypeFace = rhs.mFreeTypeFace;
- mGlyphCacheManager = rhs.mGlyphCacheManager;
+ mGlyphCacheManager = std::move(rhs.mGlyphCacheManager);
+ mHarfBuzzProxyFont = std::move(rhs.mHarfBuzzProxyFont);
mPath = std::move(rhs.mPath);
mRequestedPointSize = rhs.mRequestedPointSize;
mFaceIndex = rhs.mFaceIndex;
mIsFixedSizeBitmap = rhs.mIsFixedSizeBitmap;
mHasColorTables = rhs.mHasColorTables;
- rhs.mGlyphCacheManager = nullptr;
- rhs.mFreeTypeFace = nullptr;
+ rhs.mFreeTypeFace = nullptr;
}
FontFaceCacheItem::~FontFaceCacheItem()
// delete glyph cache manager before free face.
if(mGlyphCacheManager)
{
- delete mGlyphCacheManager;
+ mGlyphCacheManager.reset();
+ }
+
+ if(mHarfBuzzProxyFont)
+ {
+ mHarfBuzzProxyFont.reset();
}
// Free face.
return FT_Face_GetCharVariantIndex(mFreeTypeFace, character, variantSelector);
}
+HarfBuzzFontHandle FontFaceCacheItem::GetHarfBuzzFont(const uint32_t& horizontalDpi, const uint32_t& verticalDpi)
+{
+ // Create new harfbuzz font only first time or DPI changed.
+ if(DALI_UNLIKELY(!mHarfBuzzProxyFont || mHarfBuzzProxyFont->mHorizontalDpi != horizontalDpi || mHarfBuzzProxyFont->mVerticalDpi != verticalDpi))
+ {
+ mHarfBuzzProxyFont.reset(new HarfBuzzProxyFont(mFreeTypeFace, mRequestedPointSize, horizontalDpi, verticalDpi, mGlyphCacheManager.get()));
+ }
+ return mHarfBuzzProxyFont->GetHarfBuzzFont();
+}
+
} // namespace Dali::TextAbstraction::Internal
// INTERNAL INCLUDES
#include <dali/internal/text/text-abstraction/plugin/font-cache-item-interface.h>
#include <dali/internal/text/text-abstraction/plugin/font-face-glyph-cache-manager.h>
+#include <dali/internal/text/text-abstraction/plugin/harfbuzz-proxy-font.h>
// EXTERNAL INCLUDES
#include <fontconfig/fontconfig.h>
+#include <memory> // for std::unique_ptr
// EXTERNAL INCLUDES
#include <ft2build.h>
}
/**
+ * @copydoc FontCacheItemInterface::GetHarfBuzzFont()
+ */
+ HarfBuzzFontHandle GetHarfBuzzFont(const uint32_t& horizontalDpi, const uint32_t& verticalDpi) override;
+
+ /**
* @copydoc FontCacheItemInterface::HasItalicStyle()
*/
bool HasItalicStyle() const override
return (0u != (mFreeTypeFace->style_flags & FT_STYLE_FLAG_ITALIC));
}
- FT_Library& mFreeTypeLibrary; ///< A handle to a FreeType library instance.
- FT_Face mFreeTypeFace; ///< The FreeType face.
- GlyphCacheManager* mGlyphCacheManager; ///< The glyph cache manager. It will cache this face's glyphs.
- FontPath mPath; ///< The path to the font file name.
- PointSize26Dot6 mRequestedPointSize; ///< The font point size.
- FaceIndex mFaceIndex; ///< The face index.
- FontMetrics mMetrics; ///< The font metrics.
- _FcCharSet* mCharacterSet; ///< Pointer with the range of characters.
- int mFixedSizeIndex; ///< Index to the fixed size table for the requested size.
- float mFixedWidthPixels; ///< The height in pixels (fixed size bitmaps only)
- float mFixedHeightPixels; ///< The height in pixels (fixed size bitmaps only)
- unsigned int mVectorFontId; ///< The ID of the equivalent vector-based font
- FontId mFontId; ///< Index to the vector with the cache of font's ids.
- bool mIsFixedSizeBitmap : 1; ///< Whether the font has fixed size bitmaps.
- bool mHasColorTables : 1; ///< Whether the font has color tables.
+public:
+ FT_Library& mFreeTypeLibrary; ///< A handle to a FreeType library instance.
+ FT_Face mFreeTypeFace; ///< The FreeType face.
+
+ std::unique_ptr<GlyphCacheManager> mGlyphCacheManager; ///< The glyph cache manager. It will cache this face's glyphs.
+ std::unique_ptr<HarfBuzzProxyFont> mHarfBuzzProxyFont; ///< The harfbuzz font. It will store harfbuzz relate data.
+
+ FontPath mPath; ///< The path to the font file name.
+ PointSize26Dot6 mRequestedPointSize; ///< The font point size.
+ FaceIndex mFaceIndex; ///< The face index.
+ FontMetrics mMetrics; ///< The font metrics.
+ _FcCharSet* mCharacterSet; ///< Pointer with the range of characters.
+ int mFixedSizeIndex; ///< Index to the fixed size table for the requested size.
+ float mFixedWidthPixels; ///< The height in pixels (fixed size bitmaps only)
+ float mFixedHeightPixels; ///< The height in pixels (fixed size bitmaps only)
+ unsigned int mVectorFontId; ///< The ID of the equivalent vector-based font
+ FontId mFontId; ///< Index to the vector with the cache of font's ids.
+ bool mIsFixedSizeBitmap : 1; ///< Whether the font has fixed size bitmaps.
+ bool mHasColorTables : 1; ///< Whether the font has color tables.
};
} // namespace Dali::TextAbstraction::Internal
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// INTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <dali/internal/text/text-abstraction/plugin/harfbuzz-proxy-font.h>
+
+// EXTERNAL INCLUDES
+#include FT_GLYPH_H
+#include <harfbuzz/hb-ft.h>
+#include <harfbuzz/hb.h>
+
+#if defined(DEBUG_ENABLED)
+extern Dali::Integration::Log::Filter* gFontClientLogFilter;
+#endif
+
+namespace Dali::TextAbstraction::Internal
+{
+/**
+ * @brief Helper class to create and destroy harfbuzz font, and hold data in harfbuzz callback
+ * It also cache informations what harfbuzz font need to be created.
+ */
+struct HarfBuzzProxyFont::Impl
+{
+ /**
+ * @brief Constructor.
+ *
+ * @param[in] freeTypeFace The FreeType face.
+ * @param[in] glyphCacheManager Glyph caching system for this harfbuzz font. It will be used as harfbuzz callback data.
+ */
+ Impl(FT_Face freeTypeFace, GlyphCacheManager* glyphCacheManager)
+ : mFreeTypeFace(freeTypeFace),
+ mGlyphCacheManager(glyphCacheManager),
+ mHarfBuzzFont(nullptr)
+ {
+ }
+
+ // Destructor
+ ~Impl()
+ {
+ if(mHarfBuzzFont)
+ {
+ // It will reduce reference of freetype face automatically.
+ hb_font_destroy(mHarfBuzzFont);
+ }
+ }
+
+public:
+ /**
+ * @brief Create new harfbuzz font.
+ *
+ * @param[in] requestedPointSize The requiested point size of font.
+ * @param[in] horizontalDpi Horizontal DPI.
+ * @param[in] verticalDpi Vertical DPI.
+ */
+ void CreateHarfBuzzFont(const PointSize26Dot6& requestedPointSize, const uint32_t& horizontalDpi, const uint32_t& verticalDpi);
+
+private:
+ /**
+ * @brief Register harfbuzz callback functions into current harfbuzz font.
+ */
+ void SetHarfBuzzFunctions();
+
+public:
+ FT_Face mFreeTypeFace; ///< The FreeType face. Owned from font-face-cache-item.
+ GlyphCacheManager* mGlyphCacheManager; ///< Glyph caching system for this harfbuzz font. Owned from font-face-cache-item.
+
+ hb_font_t* mHarfBuzzFont; ///< Harfbuzz font handle integrated with FT_Face.
+};
+
+HarfBuzzProxyFont::HarfBuzzProxyFont(FT_Face freeTypeFace, const PointSize26Dot6& requestedPointSize, const uint32_t& horizontalDpi, const uint32_t& verticalDpi, GlyphCacheManager* glyphCacheManager)
+: mHorizontalDpi(horizontalDpi),
+ mVerticalDpi(verticalDpi),
+ mImpl(new Impl(freeTypeFace, glyphCacheManager))
+{
+ mImpl->CreateHarfBuzzFont(requestedPointSize, mHorizontalDpi, mVerticalDpi);
+}
+
+HarfBuzzProxyFont::~HarfBuzzProxyFont()
+{
+ if(mImpl)
+ {
+ delete mImpl;
+ }
+}
+
+HarfBuzzFontHandle HarfBuzzProxyFont::GetHarfBuzzFont() const
+{
+ if(mImpl)
+ {
+ return static_cast<HarfBuzzFontHandle>(mImpl->mHarfBuzzFont);
+ }
+ return nullptr;
+}
+
+// Collection of harfbuzz custom callback functions.
+// Reference : https://github.com/harfbuzz/harfbuzz/blob/main/src/hb-ft.cc
+namespace
+{
+/**
+ * @brief Get glyph informations by dali glyph cache system.
+ *
+ * @param[in] font_data HarfBuzzProxyFont::Impl pointer that register this callback as void* type.
+ * @param[in] glyphIndex Index of glyph.
+ * @param[out] glyphData The result of cached glyph data.
+ * @return True if we success to get some glyph data. False otherwise.
+ */
+static bool GetGlyphCacheData(void* font_data, const GlyphIndex& glyphIndex, GlyphCacheManager::GlyphCacheData& glyphData)
+{
+ HarfBuzzProxyFont::Impl* impl = reinterpret_cast<HarfBuzzProxyFont::Impl*>(font_data);
+
+ // Note : HarfBuzz used only FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING internally.
+ if(DALI_LIKELY(impl && impl->mGlyphCacheManager))
+ {
+ FT_Error error;
+ return impl->mGlyphCacheManager->GetGlyphCacheDataFromIndex(glyphIndex, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING, false, glyphData, error);
+ }
+ return false;
+}
+
+/**
+ * @brief Calculate font extents value both in vertical and horizontal.
+ *
+ * @param[in] font Current harfbuzz font data.
+ * @param[in] font_data HarfBuzzProxyFont::Impl pointer that register this callback as void* type.
+ * @param[out] extents Extents value of font. (scale as 26.6)
+ * @param[in] user_data Registered user data.
+ * @return True if we success to get font extents. False otherwise.
+ */
+static hb_bool_t FontExtentsFunc(hb_font_t* font, void* font_data, hb_font_extents_t* extents, void* user_data)
+{
+ HarfBuzzProxyFont::Impl* impl = reinterpret_cast<HarfBuzzProxyFont::Impl*>(font_data);
+
+ if(DALI_LIKELY(impl && impl->mFreeTypeFace))
+ {
+ FT_Size_Metrics& ftMetrics = impl->mFreeTypeFace->size->metrics;
+
+ extents->ascender = ftMetrics.ascender;
+ extents->descender = ftMetrics.descender;
+ extents->line_gap = ftMetrics.height - (extents->ascender - extents->descender);
+
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Convert from character into index of glyph.
+ *
+ * @param[in] font Current harfbuzz font data.
+ * @param[in] font_data HarfBuzzProxyFont::Impl pointer that register this callback as void* type.
+ * @param[in] character The value of character what we want to get index.
+ * @param[out] glyphIndex Index of glyph that current font face used.
+ * @param[in] user_data Registered user data.
+ * @return True if we success to convert.
+ */
+static hb_bool_t GlyphNormalIndexConvertFunc(hb_font_t* font, void* font_data, hb_codepoint_t character, hb_codepoint_t* glyphIndex, void* user_data)
+{
+ HarfBuzzProxyFont::Impl* impl = reinterpret_cast<HarfBuzzProxyFont::Impl*>(font_data);
+
+ if(DALI_LIKELY(impl && impl->mFreeTypeFace))
+ {
+ *glyphIndex = FT_Get_Char_Index(impl->mFreeTypeFace, character);
+ return *glyphIndex != 0;
+ }
+ return false;
+}
+
+/**
+ * @brief Convert from character and variant selector into index of glyph.
+ *
+ * @param[in] font Current harfbuzz font data.
+ * @param[in] font_data HarfBuzzProxyFont::Impl pointer that register this callback as void* type.
+ * @param[in] character The value of character what we want to get index.
+ * @param[in] variantSelector Variant selector.
+ * @param[out] glyphIndex Index of glyph that current font face used.
+ * @param[in] user_data Registered user data.
+ * @return True if we success to convert.
+ */
+static hb_bool_t GlyphVariantIndexConvertFunc(hb_font_t* font, void* font_data, hb_codepoint_t character, hb_codepoint_t variantSelector, hb_codepoint_t* glyphIndex, void* user_data)
+{
+ HarfBuzzProxyFont::Impl* impl = reinterpret_cast<HarfBuzzProxyFont::Impl*>(font_data);
+
+ if(DALI_LIKELY(impl && impl->mFreeTypeFace))
+ {
+ *glyphIndex = FT_Face_GetCharVariantIndex(impl->mFreeTypeFace, character, variantSelector);
+ return *glyphIndex != 0;
+ }
+ return false;
+}
+
+/**
+ * @brief Calculate glyph advance value in horizontal.
+ *
+ * @param[in] font Current harfbuzz font data.
+ * @param[in] font_data HarfBuzzProxyFont::Impl pointer that register this callback as void* type.
+ * @param[in] glyphIndex Index of glyph.
+ * @param[in] user_data Registered user data.
+ * @return Horizontal advance value of glyphIndex. (scale as 26.6)
+ */
+static hb_position_t GlyphHorizontalAdvanceFunc(hb_font_t* font, void* font_data, hb_codepoint_t glyphIndex, void* user_data)
+{
+ // Output data stored here.
+ GlyphCacheManager::GlyphCacheData glyphData;
+ if(GetGlyphCacheData(font_data, static_cast<GlyphIndex>(glyphIndex), glyphData))
+ {
+ // Note : It may return invalid value for fixed size bitmap glyph.
+ // But, Harfbuzz library also return Undefined advanced value if it is fixed size font.
+ // So we'll also ignore that case.
+ return static_cast<hb_position_t>(glyphData.mGlyphMetrics.horiAdvance);
+ }
+ return 0;
+}
+/**
+ * @brief Calculate glyph advance value in vertical.
+ *
+ * @param[in] font Current harfbuzz font data.
+ * @param[in] font_data HarfBuzzProxyFont::Impl pointer that register this callback as void* type.
+ * @param[in] glyphIndex Index of glyph.
+ * @param[in] user_data Registered user data.
+ * @return Vertical advance value of glyphIndex. (scale as 26.6)
+ */
+static hb_position_t GlyphVerticalAdvanceFunc(hb_font_t* font, void* font_data, hb_codepoint_t glyphIndex, void* user_data)
+{
+ // Output data stored here.
+ GlyphCacheManager::GlyphCacheData glyphData;
+ if(GetGlyphCacheData(font_data, static_cast<GlyphIndex>(glyphIndex), glyphData))
+ {
+ // Note : It may return invalid value for fixed size bitmap glyph.
+ // But, Harfbuzz library also return Undefined advanced value if it is fixed size font.
+ // So we'll also ignore that case.
+ return static_cast<hb_position_t>(glyphData.mGlyphMetrics.vertAdvance);
+ }
+ return 0;
+}
+
+/**
+ * @brief Calculate glyph origin position value in horizontal.
+ *
+ * @param[in] font Current harfbuzz font data.
+ * @param[in] font_data HarfBuzzProxyFont::Impl that register this callback as void* type.
+ * @param[in] glyphIndex Index of glyph.
+ * @param[out] x Origin position x (scale as 26.6)
+ * @param[out] y Origin position y (scale as 26.6)
+ * @param[in] user_data Registered user data.
+ * @return True if we get data successfully. False if some error occured.
+ */
+static hb_bool_t GlyphHorizontalOriginFunc(hb_font_t* font, void* font_data, hb_codepoint_t glyphIndex, hb_position_t* x, hb_position_t* y, void* user_data)
+{
+ // Nothing to do
+ return true;
+}
+/**
+ * @brief Calculate glyph origin position value in vertical.
+ *
+ * @param[in] font Current harfbuzz font data.
+ * @param[in] font_data HarfBuzzProxyFont::Impl pointer that register this callback as void* type.
+ * @param[in] glyphIndex Index of glyph.
+ * @param[out] x Origin position x (scale as 26.6)
+ * @param[out] y Origin position y (scale as 26.6)
+ * @param[in] user_data Registered user data.
+ * @return True if we get data successfully. False if some error occured.
+ */
+static hb_bool_t GlyphVerticalOriginFunc(hb_font_t* font, void* font_data, hb_codepoint_t glyphIndex, hb_position_t* x, hb_position_t* y, void* user_data)
+{
+ // Output data stored here.
+ GlyphCacheManager::GlyphCacheData glyphData;
+ if(GetGlyphCacheData(font_data, static_cast<GlyphIndex>(glyphIndex), glyphData))
+ {
+ *x = glyphData.mGlyphMetrics.horiBearingX - glyphData.mGlyphMetrics.vertBearingX;
+ *y = glyphData.mGlyphMetrics.horiBearingY + glyphData.mGlyphMetrics.vertBearingY;
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Calculate glyph kerning value in horizontal.
+ *
+ * @param[in] font Current harfbuzz font data.
+ * @param[in] font_data HarfBuzzProxyFont::Impl pointer that register this callback as void* type.
+ * @param[in] glyphIndex1 First index of glyph to get kerning.
+ * @param[in] glyphIndex2 Second index of glyph to get kerning.
+ * @param[in] user_data Registered user data.
+ * @return Horizontal kerning position. (scale as 26.6)
+ */
+static hb_position_t GlyphHorizontalKerningFunc(hb_font_t* font, void* font_data, hb_codepoint_t glyphIndex1, hb_codepoint_t glyphIndex2, void* user_data)
+{
+ HarfBuzzProxyFont::Impl* impl = reinterpret_cast<HarfBuzzProxyFont::Impl*>(font_data);
+
+ if(DALI_LIKELY(impl && impl->mFreeTypeFace))
+ {
+ FT_Error error;
+ FT_Vector kerning;
+
+ error = FT_Get_Kerning(impl->mFreeTypeFace, glyphIndex1, glyphIndex2, FT_KERNING_UNSCALED, &kerning);
+ if(error == FT_Err_Ok)
+ {
+ return kerning.x;
+ }
+ }
+ return 0;
+}
+/**
+ * @brief Calculate glyph kerning value in vertical.
+ *
+ * @param[in] font Current harfbuzz font data.
+ * @param[in] font_data HarfBuzzProxyFont::Impl pointer that register this callback as void* type.
+ * @param[in] glyphIndex1 First index of glyph to get kerning.
+ * @param[in] glyphIndex2 Second index of glyph to get kerning.
+ * @param[in] user_data Registered user data.
+ * @return Vertical kerning position. (scale as 26.6)
+ */
+static hb_position_t GlyphVerticalKerningFunc(hb_font_t* font, void* font_data, hb_codepoint_t glyphIndex1, hb_codepoint_t glyphIndex2, void* user_data)
+{
+ // FreeType doesn't support vertical kerning
+ return 0;
+}
+
+/**
+ * @brief Calculate glyph extents.
+ *
+ * @param[in] font Current harfbuzz font data.
+ * @param[in] font_data HarfBuzzProxyFont::Impl pointer that register this callback as void* type.
+ * @param[in] glyphIndex Index of glyph.
+ * @param[out] extents Extents value of glyph. (scale as 26.6)
+ * @param[in] user_data Registered user data.
+ * @return True if we get data successfully. False if some error occured.
+ */
+static hb_bool_t GlyphExtentsFunc(hb_font_t* font, void* font_data, hb_codepoint_t glyphIndex, hb_glyph_extents_t* extents, void* user_data)
+{
+ // Output data stored here.
+ GlyphCacheManager::GlyphCacheData glyphData;
+ if(!GetGlyphCacheData(font_data, static_cast<GlyphIndex>(glyphIndex), glyphData))
+ {
+ extents->x_bearing = glyphData.mGlyphMetrics.horiBearingX;
+ extents->y_bearing = glyphData.mGlyphMetrics.horiBearingY;
+ extents->width = glyphData.mGlyphMetrics.width;
+ extents->height = glyphData.mGlyphMetrics.height;
+ return true;
+ }
+ return false;
+}
+
+} // namespace
+
+void HarfBuzzProxyFont::Impl::CreateHarfBuzzFont(const PointSize26Dot6& requestedPointSize, const uint32_t& horizontalDpi, const uint32_t& verticalDpi)
+{
+ // Destroy previous hb_font_t if exist.
+ if(mHarfBuzzFont)
+ {
+ // It will reduce reference of freetype face automatically.
+ hb_font_destroy(mHarfBuzzFont);
+ mHarfBuzzFont = nullptr;
+ }
+
+ if(mFreeTypeFace)
+ {
+ // Before create hb_font_t, we must set FT_Char_Size
+ FT_Set_Char_Size(mFreeTypeFace,
+ 0u,
+ requestedPointSize,
+ horizontalDpi,
+ verticalDpi);
+
+ // Create font face with increase font face's reference.
+ mHarfBuzzFont = hb_ft_font_create_referenced(mFreeTypeFace);
+
+ SetHarfBuzzFunctions();
+
+ if(mHarfBuzzFont)
+ {
+ DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "FontClient::Plugin::HarfBuzzManager::GetHarfBuzzFont. Create new harfbuzz font : %p freetype face : %p. Requested point size : %u, dpi : horizon %u vertial %u\n", mHarfBuzzFont, mFreeTypeFace, requestedPointSize, horizontalDpi, verticalDpi);
+ }
+ else
+ {
+ DALI_LOG_ERROR("ERROR! failed to create harfbuzz font.");
+ }
+ }
+ else
+ {
+ DALI_LOG_ERROR("ERROR! freetype face is null! something unknown problem occured.");
+ }
+}
+
+void HarfBuzzProxyFont::Impl::SetHarfBuzzFunctions()
+{
+ if(mHarfBuzzFont)
+ {
+ hb_font_funcs_t* customFunctions = hb_font_funcs_create();
+
+ if(customFunctions)
+ {
+ // Bind custom functions here
+ hb_font_funcs_set_font_h_extents_func(customFunctions, FontExtentsFunc, 0, 0);
+ hb_font_funcs_set_font_v_extents_func(customFunctions, FontExtentsFunc, 0, 0);
+
+ hb_font_funcs_set_nominal_glyph_func(customFunctions, GlyphNormalIndexConvertFunc, 0, 0);
+ hb_font_funcs_set_variation_glyph_func(customFunctions, GlyphVariantIndexConvertFunc, 0, 0);
+
+ hb_font_funcs_set_glyph_h_advance_func(customFunctions, GlyphHorizontalAdvanceFunc, 0, 0);
+ hb_font_funcs_set_glyph_v_advance_func(customFunctions, GlyphVerticalAdvanceFunc, 0, 0);
+ hb_font_funcs_set_glyph_extents_func(customFunctions, GlyphExtentsFunc, 0, 0);
+
+ hb_font_funcs_set_glyph_h_origin_func(customFunctions, GlyphHorizontalOriginFunc, 0, 0);
+ hb_font_funcs_set_glyph_v_origin_func(customFunctions, GlyphVerticalOriginFunc, 0, 0);
+ hb_font_funcs_set_glyph_h_kerning_func(customFunctions, GlyphHorizontalKerningFunc, 0, 0);
+ hb_font_funcs_set_glyph_v_kerning_func(customFunctions, GlyphVerticalKerningFunc, 0, 0);
+
+ // Set custom functions into our own harfbuzz font
+ hb_font_set_funcs(mHarfBuzzFont, customFunctions, this, 0);
+
+ // We must release functions type what we create.
+ hb_font_funcs_destroy(customFunctions);
+ }
+ else
+ {
+ DALI_LOG_ERROR("ERROR! Fail to create custom harfbuzz functions.");
+
+ // Something wrong while create harfbuzz font. Destory it.
+ // It will reduce reference of freetype face automatically.
+ hb_font_destroy(mHarfBuzzFont);
+ mHarfBuzzFont = nullptr;
+ }
+ }
+}
+
+} // namespace Dali::TextAbstraction::Internal
--- /dev/null
+#ifndef DALI_TEXT_ABSTRACTION_INTERNAL_HARFBUZZ_PROXY_FONT_H
+#define DALI_TEXT_ABSTRACTION_INTERNAL_HARFBUZZ_PROXY_FONT_H
+
+/*
+ * Copyright (c) 2022 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// INTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
+#include <dali/internal/text/text-abstraction/font-client-impl.h> // for HarfBuzzFontHandle
+#include <dali/internal/text/text-abstraction/plugin/font-face-glyph-cache-manager.h>
+
+// EXTERNAL INCLUDES
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+namespace Dali::TextAbstraction::Internal
+{
+/**
+ * @brief Helper class to shape of FT_Face by harfbuzz library.
+ * @note Current class only be used for font face cache item.
+ */
+class HarfBuzzProxyFont
+{
+public:
+ /**
+ * @brief Constructor harfbuzz font data integrated with FreeType face and our font face cache item.
+ *
+ * @param[in] freeTypeFace The FreeType face.
+ * @param[in] requestedPointSize The requiested point size of font.
+ * @param[in] horizontalDpi Horizontal DPI.
+ * @param[in] verticalDpi Vertical DPI.
+ * @param[in] glyphCacheManager Glyph caching system for this harfbuzz font. It will be used as harfbuzz callback data.
+ */
+ HarfBuzzProxyFont(FT_Face freeTypeFace, const PointSize26Dot6& requestedPointSize, const uint32_t& horizontalDpi, const uint32_t& verticalDpi, GlyphCacheManager* glyphCacheManager);
+
+ // Destructor
+ ~HarfBuzzProxyFont();
+
+public:
+ // Public API area.
+
+ /**
+ * @brief Get the created harfbuzz font data integrated with FreeType face and our font face cache item.
+ *
+ * @return Created harfbuzz font data. or nullptr if there is something error.
+ */
+ HarfBuzzFontHandle GetHarfBuzzFont() const;
+
+private:
+ // Private API area.
+ HarfBuzzProxyFont() = delete; // Do not use default construct
+ HarfBuzzProxyFont(const HarfBuzzProxyFont& rhs) = delete; // Do not use copy construct
+ HarfBuzzProxyFont(HarfBuzzProxyFont&& rhs) = delete; // Do not use move construct
+public:
+ struct Impl; // Harfbuzz callback can access this struct.
+ uint32_t mHorizontalDpi; ///< Horizontal DPI.
+ uint32_t mVerticalDpi; ///< VerticalDPI.
+
+private:
+ // Private member value area.
+ Impl* mImpl;
+};
+
+} // namespace Dali::TextAbstraction::Internal
+
+#endif //DALI_TEXT_ABSTRACTION_INTERNAL_HARFBUZZ_PROXY_FONT_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
{
case FontDescription::FACE_FONT:
{
+ // Get our harfbuzz font struct
+ hb_font_t* harfBuzzFont = reinterpret_cast<hb_font_t*>(fontClientImpl.GetHarfBuzzFont(fontId));
+ if(nullptr == harfBuzzFont)
+ {
+ // Nothing to do if the harfBuzzFont is null.
+ return 0u;
+ }
+
// Reserve some space to avoid reallocations.
const Length numberOfGlyphs = static_cast<Length>(1.3f * static_cast<float>(numberOfCharacters));
mIndices.Reserve(numberOfGlyphs);
mCharacterMap.Reserve(numberOfGlyphs);
mOffset.Reserve(2u * numberOfGlyphs);
- // Retrieve a FreeType font's face.
- FT_Face face = fontClientImpl.GetFreetypeFace(fontId);
- if(nullptr == face)
- {
- // Nothing to do if the face is null.
- return 0u;
- }
-
- unsigned int horizontalDpi = 0u;
- unsigned int verticalDpi = 0u;
- fontClient.GetDpi(horizontalDpi, verticalDpi);
-
- FT_Set_Char_Size(face,
- 0u,
- fontClient.GetPointSize(fontId),
- horizontalDpi,
- verticalDpi);
-
- /* Get our harfbuzz font struct */
- hb_font_t* harfBuzzFont;
- harfBuzzFont = hb_ft_font_create(face, NULL);
-
/* Create a buffer for harfbuzz to use */
hb_buffer_t* harfBuzzBuffer = hb_buffer_create();
/* Cleanup */
hb_buffer_destroy(harfBuzzBuffer);
- hb_font_destroy(harfBuzzFont);
break;
}
case FontDescription::BITMAP_FONT:
mTransitionEffectEventSignal(),
mKeyboardRepeatSettingsChangedSignal(),
mAuxiliaryMessageSignal(),
- mLastKeyEevent(),
- mLastTouchEevent(),
+ mLastKeyEvent(),
+ mLastTouchEvent(),
mIsTransparent(false),
mIsFocusAcceptable(true),
mIconified(false),
void Window::OnTouchPoint(Dali::Integration::Point& point, int timeStamp)
{
- mLastTouchEevent = Dali::Integration::NewTouchEvent(timeStamp, point);
+ mLastTouchEvent = Dali::Integration::NewTouchEvent(timeStamp, point);
FeedTouchPoint(point, timeStamp);
}
void Window::OnKeyEvent(Dali::Integration::KeyEvent& keyEvent)
{
- mLastKeyEevent = Dali::DevelKeyEvent::New(keyEvent.keyName, keyEvent.logicalKey, keyEvent.keyString, keyEvent.keyCode, keyEvent.keyModifier, keyEvent.time, static_cast<Dali::KeyEvent::State>(keyEvent.state), keyEvent.compose, keyEvent.deviceName, keyEvent.deviceClass, keyEvent.deviceSubclass);
+ mLastKeyEvent = Dali::DevelKeyEvent::New(keyEvent.keyName, keyEvent.logicalKey, keyEvent.keyString, keyEvent.keyCode, keyEvent.keyModifier, keyEvent.time, static_cast<Dali::KeyEvent::State>(keyEvent.state), keyEvent.compose, keyEvent.deviceName, keyEvent.deviceClass, keyEvent.deviceSubclass);
FeedKeyEvent(keyEvent);
}
const Dali::KeyEvent& Window::GetLastKeyEvent() const
{
- return mLastKeyEevent;
+ return mLastKeyEvent;
}
const Dali::TouchEvent& Window::GetLastTouchEvent() const
{
- return mLastTouchEevent;
+ return mLastTouchEvent;
}
} // namespace Adaptor
AuxiliaryMessageSignalType mAuxiliaryMessageSignal;
AccessibilityHighlightSignalType mAccessibilityHighlightSignal;
- Dali::KeyEvent mLastKeyEevent;
- Dali::TouchEvent mLastTouchEevent;
+ Dali::KeyEvent mLastKeyEvent;
+ Dali::TouchEvent mLastTouchEvent;
bool mIsTransparent : 1;
bool mIsFocusAcceptable : 1;
{
const unsigned int ADAPTOR_MAJOR_VERSION = 2;
const unsigned int ADAPTOR_MINOR_VERSION = 1;
-const unsigned int ADAPTOR_MICRO_VERSION = 25;
+const unsigned int ADAPTOR_MICRO_VERSION = 27;
const char* const ADAPTOR_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-adaptor
Summary: The DALi Tizen Adaptor
-Version: 2.1.25
+Version: 2.1.27
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT