From: David Steele Date: Fri, 29 Oct 2021 11:04:43 +0000 (+0000) Subject: Merge "Moved font client plugin to new folder" into devel/master X-Git-Tag: dali_2.0.51~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a492566891d85da8b55f1d1ef956a7885c74a509;hp=2981cbc4aa20933a54dc71bf83a436ad0fd6d3c6;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git Merge "Moved font client plugin to new folder" into devel/master --- diff --git a/automated-tests/build.sh b/automated-tests/build.sh index 2f92135..6db52c3 100755 --- a/automated-tests/build.sh +++ b/automated-tests/build.sh @@ -32,7 +32,7 @@ function build (cd src/$1; ../../scripts/tcheadgen.sh tct-$1-core.h) if [ $? -ne 0 ]; then echo "Aborting..."; exit 1; fi fi - (cd build ; cmake .. -DMODULE=$1 ; make -j7 ) + (cd build ; cmake .. -DCMAKE_VERBOSE_MAKEFILE=ON -DMODULE=$1 ; make -j7 ) } if [ -n "$1" ] ; then diff --git a/automated-tests/src/dali-adaptor-internal/CMakeLists.txt b/automated-tests/src/dali-adaptor-internal/CMakeLists.txt index 3fe5502..0a8e771 100644 --- a/automated-tests/src/dali-adaptor-internal/CMakeLists.txt +++ b/automated-tests/src/dali-adaptor-internal/CMakeLists.txt @@ -51,16 +51,16 @@ PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED dali2-core dali2-adaptor ecore + freetype2>=9.16.3 ) + + ADD_COMPILE_OPTIONS( -O0 -ggdb --coverage -Wall -Werror ) ADD_COMPILE_OPTIONS( ${${CAPI_LIB}_CFLAGS_OTHER} ) -# Shouldn't have to do this! -# But CMake's new auto-escape quote policy doesn't work right. -CMAKE_POLICY(SET CMP0005 OLD) -ADD_DEFINITIONS(-DTEST_IMAGE_DIR=\"\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../images\\\"\" ) -ADD_DEFINITIONS(-DADDON_LIBS_PATH=\"\\\"${CMAKE_CURRENT_BINARY_DIR}\\\"\" ) +ADD_DEFINITIONS(-DTEST_IMAGE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/../../images\" ) +ADD_DEFINITIONS(-DADDON_LIBS_PATH=\"${CMAKE_CURRENT_BINARY_DIR}\" ) FOREACH(directory ${${CAPI_LIB}_LIBRARY_DIRS}) diff --git a/automated-tests/src/dali-adaptor-internal/utc-Dali-FontClient.cpp b/automated-tests/src/dali-adaptor-internal/utc-Dali-FontClient.cpp index c1e804f..ce9cfab 100644 --- a/automated-tests/src/dali-adaptor-internal/utc-Dali-FontClient.cpp +++ b/automated-tests/src/dali-adaptor-internal/utc-Dali-FontClient.cpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/automated-tests/src/dali-platform-abstraction/CMakeLists.txt b/automated-tests/src/dali-platform-abstraction/CMakeLists.txt index a7bb879..22f69f3 100644 --- a/automated-tests/src/dali-platform-abstraction/CMakeLists.txt +++ b/automated-tests/src/dali-platform-abstraction/CMakeLists.txt @@ -45,10 +45,7 @@ PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED ADD_COMPILE_OPTIONS(-O0 -ggdb --coverage -Wall -Werror) ADD_COMPILE_OPTIONS( ${${CAPI_LIB}_CFLAGS_OTHER} ) -# Shouldn't have to do this! -# But CMake's new auto-escape quote policy doesn't work right. -CMAKE_POLICY(SET CMP0005 OLD) -ADD_DEFINITIONS(-DTEST_IMAGE_DIR=\"\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../images\\\"\" ) +ADD_DEFINITIONS(-DTEST_IMAGE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/../../images\" ) FOREACH(directory ${${CAPI_LIB}_LIBRARY_DIRS}) SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -L${directory}") diff --git a/dali/internal/text/file.list b/dali/internal/text/file.list index 1a420de..fd617e2 100644 --- a/dali/internal/text/file.list +++ b/dali/internal/text/file.list @@ -3,12 +3,11 @@ SET( adaptor_text_common_src_files ${adaptor_text_dir}/text-abstraction/bidirectional-support-impl.cpp ${adaptor_text_dir}/text-abstraction/cairo-renderer.cpp - ${adaptor_text_dir}/text-abstraction/font-client-helper.cpp ${adaptor_text_dir}/text-abstraction/font-client-impl.cpp - ${adaptor_text_dir}/text-abstraction/font-client-plugin-impl.cpp ${adaptor_text_dir}/text-abstraction/segmentation-impl.cpp ${adaptor_text_dir}/text-abstraction/shaping-impl.cpp ${adaptor_text_dir}/text-abstraction/text-renderer-impl.cpp ${adaptor_text_dir}/text-abstraction/hyphenation-impl.cpp + ${adaptor_text_dir}/text-abstraction/plugin/font-client-utils.cpp + ${adaptor_text_dir}/text-abstraction/plugin/font-client-plugin-impl.cpp ) - diff --git a/dali/internal/text/text-abstraction/font-client-helper.cpp b/dali/internal/text/text-abstraction/font-client-helper.cpp deleted file mode 100644 index b5e4b91..0000000 --- a/dali/internal/text/text-abstraction/font-client-helper.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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. - * - */ - -// CLASS HEADER -#include - -// INTERNAL INCLUDES - -#include - -namespace -{ -#if defined(DEBUG_ENABLED) -Dali::Integration::Log::Filter* gLogFilter = Dali::Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_FONT_CLIENT_VALUE_TO_INDEX"); -#endif -} // namespace - -namespace Dali -{ -namespace TextAbstraction -{ -namespace Internal -{ -int ValueToIndex(int value, const int* const table, unsigned int maxIndex) -{ - DALI_LOG_INFO(gLogFilter, Debug::Verbose, "-->FontClient::Plugin::ValueToIndex value(%d)\n", value); - - if(NULL == table) - { - // Return an invalid index if there is no table. - return -1; - } - - if(value <= table[0]) - { - return 0; - } - - if(value >= table[maxIndex]) - { - return maxIndex; - } - - for(unsigned int index = 0u; index < maxIndex; ++index) - { - const int v1 = table[index]; - const unsigned int indexPlus = index + 1u; - const int v2 = table[indexPlus]; - if((v1 < value) && (value <= v2)) - { - const int result = ((v1 > 0) && ((value - v1) < (v2 - value))) ? index : indexPlus; - DALI_LOG_INFO(gLogFilter, Debug::Verbose, "FontClient::Plugin::ValueToIndex result(%d)\n", result); - return result; - } - } - - DALI_LOG_INFO(gLogFilter, Debug::Verbose, "FontClient::Plugin::ValueToIndex exit 0 <-- \n"); - - return 0; -} - -} // namespace Internal - -} // namespace TextAbstraction - -} // namespace Dali diff --git a/dali/internal/text/text-abstraction/font-client-helper.h b/dali/internal/text/text-abstraction/font-client-helper.h deleted file mode 100644 index 6916ae6..0000000 --- a/dali/internal/text/text-abstraction/font-client-helper.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_HELPER_H -#define DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_HELPER_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. - * - */ - -namespace Dali -{ -namespace TextAbstraction -{ -namespace Internal -{ -/** - * @brief Retrieves a table index for a given value. - * - * @param[in] value The value. - * @param[in] table The table. - * @param[in] maxIndex The maximum valid index of the table. - * - * @return The index to the closest available value - */ -int ValueToIndex(int value, const int* const table, unsigned int maxIndex); - -} // namespace Internal - -} // namespace TextAbstraction - -} // namespace Dali - -#endif // DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_HELPER_H diff --git a/dali/internal/text/text-abstraction/font-client-impl.cpp b/dali/internal/text/text-abstraction/font-client-impl.cpp index e6e93fc..70678ca 100644 --- a/dali/internal/text/text-abstraction/font-client-impl.cpp +++ b/dali/internal/text/text-abstraction/font-client-impl.cpp @@ -25,7 +25,7 @@ // INTERNAL INCLUDES #include -#include +#include #include diff --git a/dali/internal/text/text-abstraction/font-client-plugin-impl.cpp b/dali/internal/text/text-abstraction/plugin/font-client-plugin-impl.cpp similarity index 89% rename from dali/internal/text/text-abstraction/font-client-plugin-impl.cpp rename to dali/internal/text/text-abstraction/plugin/font-client-plugin-impl.cpp index 802431c..a7e025c 100644 --- a/dali/internal/text/text-abstraction/font-client-plugin-impl.cpp +++ b/dali/internal/text/text-abstraction/plugin/font-client-plugin-impl.cpp @@ -16,7 +16,7 @@ */ // CLASS HEADER -#include +#include // INTERNAL INCLUDES #include @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include @@ -35,8 +35,6 @@ #include #include -namespace -{ #if defined(DEBUG_ENABLED) // Note, to turn on trace and verbose logging, use "export LOG_FONT_CLIENT=3,true" @@ -73,6 +71,8 @@ Dali::Integration::Log::Filter* gFontClientLogFilter = Dali::Integration::Log::F #endif +namespace +{ /** * Conversion from Fractional26.6 to float */ @@ -80,49 +80,9 @@ const float FROM_266 = 1.0f / 64.0f; const float POINTS_PER_INCH = 72.f; const std::string DEFAULT_FONT_FAMILY_NAME("Tizen"); -const int DEFAULT_FONT_WIDTH = 100; // normal -const int DEFAULT_FONT_WEIGHT = 80; // normal -const int DEFAULT_FONT_SLANT = 0; // normal const uint32_t ELLIPSIS_CHARACTER = 0x2026; -// http://www.freedesktop.org/software/fontconfig/fontconfig-user.html - -// NONE -1 --> DEFAULT_FONT_WIDTH (NORMAL) will be used. -// ULTRA_CONDENSED 50 -// EXTRA_CONDENSED 63 -// CONDENSED 75 -// SEMI_CONDENSED 87 -// NORMAL 100 -// SEMI_EXPANDED 113 -// EXPANDED 125 -// EXTRA_EXPANDED 150 -// ULTRA_EXPANDED 200 -const int FONT_WIDTH_TYPE_TO_INT[] = {-1, 50, 63, 75, 87, 100, 113, 125, 150, 200}; -const unsigned int NUM_FONT_WIDTH_TYPE = sizeof(FONT_WIDTH_TYPE_TO_INT) / sizeof(int); - -// NONE -1 --> DEFAULT_FONT_WEIGHT (NORMAL) will be used. -// THIN 0 -// ULTRA_LIGHT, EXTRA_LIGHT 40 -// LIGHT 50 -// DEMI_LIGHT, SEMI_LIGHT 55 -// BOOK 75 -// NORMAL, REGULAR 80 -// MEDIUM 100 -// DEMI_BOLD, SEMI_BOLD 180 -// BOLD 200 -// ULTRA_BOLD, EXTRA_BOLD 205 -// BLACK, HEAVY, EXTRA_BLACK 210 -const int FONT_WEIGHT_TYPE_TO_INT[] = {-1, 0, 40, 50, 55, 75, 80, 100, 180, 200, 205, 210}; -const unsigned int NUM_FONT_WEIGHT_TYPE = sizeof(FONT_WEIGHT_TYPE_TO_INT) / sizeof(int); - -// NONE -1 --> DEFAULT_FONT_SLANT (NORMAL) will be used. -// NORMAL, ROMAN 0 -// ITALIC 100 -// OBLIQUE 110 -const int FONT_SLANT_TYPE_TO_INT[] = {-1, 0, 100, 110}; -const unsigned int NUM_FONT_SLANT_TYPE = sizeof(FONT_SLANT_TYPE_TO_INT) / sizeof(int); - } // namespace using Dali::Vector; @@ -135,42 +95,6 @@ namespace TextAbstraction namespace Internal { /** - * @brief Returns the FontWidth's enum index for the given width value. - * - * @param[in] width The width value. - * - * @return The FontWidth's enum index. - */ -FontWidth::Type IntToWidthType(int width) -{ - return static_cast(ValueToIndex(width, FONT_WIDTH_TYPE_TO_INT, NUM_FONT_WIDTH_TYPE - 1u)); -} - -/** - * @brief Returns the FontWeight's enum index for the given weight value. - * - * @param[in] weight The weight value. - * - * @return The FontWeight's enum index. - */ -FontWeight::Type IntToWeightType(int weight) -{ - return static_cast(ValueToIndex(weight, FONT_WEIGHT_TYPE_TO_INT, NUM_FONT_WEIGHT_TYPE - 1u)); -} - -/** - * @brief Returns the FontSlant's enum index for the given slant value. - * - * @param[in] slant The slant value. - * - * @return The FontSlant's enum index. - */ -FontSlant::Type IntToSlantType(int slant) -{ - return static_cast(ValueToIndex(slant, FONT_SLANT_TYPE_TO_INT, NUM_FONT_SLANT_TYPE - 1u)); -} - -/** * @brief Free the resources allocated by the FcCharSet objects. * * @param[in] characterSets The vector of character sets. @@ -553,9 +477,9 @@ void FontClient::Plugin::GetDefaultFonts(FontList& defaultFonts) { FontDescription fontDescription; fontDescription.family = DEFAULT_FONT_FAMILY_NAME; // todo This could be set to the Platform font - fontDescription.width = IntToWidthType(DEFAULT_FONT_WIDTH); - fontDescription.weight = IntToWeightType(DEFAULT_FONT_WEIGHT); - fontDescription.slant = IntToSlantType(DEFAULT_FONT_SLANT); + fontDescription.width = DefaultFontWidth(); + fontDescription.weight = DefaultFontWeight(); + fontDescription.slant = DefaultFontSlant(); SetFontList(fontDescription, mDefaultFonts, mDefaultFontCharacterSets); } @@ -899,9 +823,9 @@ FontId FontClient::Plugin::FindDefaultFont(Character charcode, { FontDescription fontDescription; fontDescription.family = DEFAULT_FONT_FAMILY_NAME; - fontDescription.width = IntToWidthType(DEFAULT_FONT_WIDTH); - fontDescription.weight = IntToWeightType(DEFAULT_FONT_WEIGHT); - fontDescription.slant = IntToSlantType(DEFAULT_FONT_SLANT); + fontDescription.width = DefaultFontWidth(); + fontDescription.weight = DefaultFontWeight(); + fontDescription.slant = DefaultFontSlant(); SetFontList(fontDescription, mDefaultFonts, mDefaultFontCharacterSets); } @@ -930,9 +854,9 @@ FontId FontClient::Plugin::FindFallbackFont(Character charcode, // Fill the font description with the preferred font description and complete with the defaults. fontDescription.family = preferredFontDescription.family.empty() ? DEFAULT_FONT_FAMILY_NAME : preferredFontDescription.family; - fontDescription.weight = ((FontWeight::NONE == preferredFontDescription.weight) ? IntToWeightType(DEFAULT_FONT_WEIGHT) : preferredFontDescription.weight); - fontDescription.width = ((FontWidth::NONE == preferredFontDescription.width) ? IntToWidthType(DEFAULT_FONT_WIDTH) : preferredFontDescription.width); - fontDescription.slant = ((FontSlant::NONE == preferredFontDescription.slant) ? IntToSlantType(DEFAULT_FONT_SLANT) : preferredFontDescription.slant); + fontDescription.weight = ((FontWeight::NONE == preferredFontDescription.weight) ? DefaultFontWeight() : preferredFontDescription.weight); + fontDescription.width = ((FontWidth::NONE == preferredFontDescription.width) ? DefaultFontWidth() : preferredFontDescription.width); + fontDescription.slant = ((FontSlant::NONE == preferredFontDescription.slant) ? DefaultFontSlant() : preferredFontDescription.slant); DALI_LOG_INFO(gFontClientLogFilter, Debug::General, " preferredFontDescription --> fontDescription\n"); DALI_LOG_INFO(gFontClientLogFilter, Debug::General, " [%s] --> [%s]\n", preferredFontDescription.family.c_str(), fontDescription.family.c_str()); @@ -1970,7 +1894,6 @@ GlyphIndex FontClient::Plugin::CreateEmbeddedItem(const TextAbstraction::FontCli return mEmbeddedItemCache.Count(); } -//SHS void FontClient::Plugin::EnableAtlasLimitation(bool enabled) { @@ -2100,62 +2023,6 @@ bool FontClient::Plugin::MatchFontDescriptionToPattern(FcPattern* pattern, Dali: return matched; } -FcPattern* FontClient::Plugin::CreateFontFamilyPattern(const FontDescription& fontDescription) const -{ - // create the cached font family lookup pattern - // a pattern holds a set of names, each name refers to a property of the font - FcPattern* fontFamilyPattern = FcPatternCreate(); // FcPatternCreate creates a new pattern that needs to be destroyed by calling FcPatternDestroy. - - if(!fontFamilyPattern) - { - return nullptr; - } - - // add a property to the pattern for the font family - FcPatternAddString(fontFamilyPattern, FC_FAMILY, reinterpret_cast(fontDescription.family.c_str())); - - // add a property to the pattern for local setting. - const char* locale = setlocale(LC_MESSAGES, nullptr); - if(locale != nullptr) - { - FcPatternAddString(fontFamilyPattern, FC_LANG, reinterpret_cast(locale)); - } - - int width = FONT_WIDTH_TYPE_TO_INT[fontDescription.width]; - if(width < 0) - { - // Use default. - width = DEFAULT_FONT_WIDTH; - } - - int weight = FONT_WEIGHT_TYPE_TO_INT[fontDescription.weight]; - if(weight < 0) - { - // Use default. - weight = DEFAULT_FONT_WEIGHT; - } - - int slant = FONT_SLANT_TYPE_TO_INT[fontDescription.slant]; - if(slant < 0) - { - // Use default. - slant = DEFAULT_FONT_SLANT; - } - - FcPatternAddInteger(fontFamilyPattern, FC_WIDTH, width); - FcPatternAddInteger(fontFamilyPattern, FC_WEIGHT, weight); - FcPatternAddInteger(fontFamilyPattern, FC_SLANT, slant); - - // modify the config, with the mFontFamilyPatterm - FcConfigSubstitute(nullptr /* use default configure */, fontFamilyPattern, FcMatchPattern); - - // provide default values for unspecified properties in the font pattern - // e.g. patterns without a specified style or weight are set to Medium - FcDefaultSubstitute(fontFamilyPattern); - - return fontFamilyPattern; -} - _FcFontSet* FontClient::Plugin::GetFcFontSet() const { FcFontSet* fontset = nullptr; @@ -2399,138 +2266,6 @@ FontId FontClient::Plugin::CreateFont(const FontPath& path, return id; } -void FontClient::Plugin::ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, unsigned int srcWidth, unsigned int srcHeight, const unsigned char* const srcBuffer) -{ - // Set the input dimensions. - const ImageDimensions inputDimensions(srcWidth, srcHeight); - - // Set the output dimensions. - // If the output dimension is not given, the input dimension is set - // and won't be downscaling. - data.width = (data.width == 0) ? srcWidth : data.width; - data.height = (data.height == 0) ? srcHeight : data.height; - const ImageDimensions desiredDimensions(data.width, data.height); - - // Creates the output buffer - const unsigned int bufferSize = data.width * data.height * 4u; - data.buffer = new unsigned char[bufferSize]; // @note The caller is responsible for deallocating the bitmap data using delete[]. - - if(inputDimensions == desiredDimensions) - { - // There isn't downscaling. - memcpy(data.buffer, srcBuffer, bufferSize); - } - else - { - Dali::Internal::Platform::LanczosSample4BPP(srcBuffer, - inputDimensions, - data.buffer, - desiredDimensions); - } -} - -void FontClient::Plugin::ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, FT_Bitmap srcBitmap, bool isShearRequired) -{ - if(srcBitmap.width * srcBitmap.rows > 0) - { - switch(srcBitmap.pixel_mode) - { - case FT_PIXEL_MODE_GRAY: - { - if(srcBitmap.pitch == static_cast(srcBitmap.width)) - { - uint8_t* pixelsIn = srcBitmap.buffer; - unsigned int width = srcBitmap.width; - unsigned height = srcBitmap.rows; - - std::unique_ptr pixelsOutPtr(nullptr, free); - - if(isShearRequired) - { - /** - * Glyphs' bitmaps with no slant retrieved from FreeType: - * __________ ____ - * |XXXXXXXX| |XX| - * | XX | |XX| - * | XX | |XX| - * | XX | |XX| - * | XX | |XX| - * | XX | |XX| - * ---------- ---- - * - * Expected glyphs' bitmaps with italic slant: - * ____________ ______ - * | XXXXXXXX| | XX| - * | XX | | XX| - * | XX | | XX | - * | XX | | XX | - * | XX | |XX | - * | XX | |XX | - * ------------ ------ - * - * Glyphs' bitmaps with software italic slant retrieved from FreeType: - * __________ ______ - * |XXXXXXXX| | XX| - * | XX | | XX| - * | XX | | XX | - * | XX | | XX | - * | XX | |XX | - * | XX | |XX | - * ---------- ------ - * - * This difference in some bitmaps' width causes an overlap of some glyphs. This is the reason why a shear operation is done here instead of relying on the experimental FT_GlyphSlot_Oblique() implementation. - */ - unsigned int widthOut = 0u; - unsigned int heightOut = 0u; - uint8_t* pixelsOut = nullptr; - - Dali::Internal::Platform::HorizontalShear(pixelsIn, - width, - height, - 1u, - -TextAbstraction::FontClient::DEFAULT_ITALIC_ANGLE, - pixelsOut, - widthOut, - heightOut); - - width = widthOut; - height = heightOut; - pixelsIn = pixelsOut; - pixelsOutPtr.reset(pixelsOut); - } - - const unsigned int bufferSize = width * height; - data.buffer = new unsigned char[bufferSize]; // @note The caller is responsible for deallocating the bitmap data using delete[]. - data.width = width; - data.height = height; - data.format = Pixel::L8; // Sets the pixel format. - memcpy(data.buffer, pixelsIn, bufferSize); - } - break; - } - -#ifdef FREETYPE_BITMAP_SUPPORT - case FT_PIXEL_MODE_BGRA: - { - if(srcBitmap.pitch == static_cast(srcBitmap.width << 2u)) - { - ConvertBitmap(data, srcBitmap.width, srcBitmap.rows, srcBitmap.buffer); - - // Sets the pixel format. - data.format = Pixel::BGRA8888; - } - break; - } -#endif - default: - { - DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "FontClient::Plugin::ConvertBitmap. FontClient Unable to create Bitmap of this PixelType\n"); - break; - } - } - } -} - bool FontClient::Plugin::FindFont(const FontPath& path, PointSize26Dot6 requestedPointSize, FaceIndex faceIndex, @@ -2848,27 +2583,6 @@ void FontClient::Plugin::CacheFontPath(FT_Face ftFace, FontId id, PointSize26Dot } } -FcCharSet* FontClient::Plugin::CreateCharacterSetFromDescription(const FontDescription& description) -{ - FcCharSet* characterSet = nullptr; - - FcPattern* pattern = CreateFontFamilyPattern(description); // Creates a new pattern that needs to be destroyed by calling FcPatternDestroy. - - if(nullptr != pattern) - { - FcResult result = FcResultMatch; - FcPattern* match = FcFontMatch(nullptr, pattern, &result); // FcFontMatch creates a new pattern that needs to be destroyed by calling FcPatternDestroy. - - FcPatternGetCharSet(match, FC_CHARSET, 0u, &characterSet); - - // Destroys the created patterns. - FcPatternDestroy(match); - FcPatternDestroy(pattern); - } - - return characterSet; -} - void FontClient::Plugin::ClearFallbackCache(std::vector& fallbackCache) { for(auto& item : fallbackCache) diff --git a/dali/internal/text/text-abstraction/font-client-plugin-impl.h b/dali/internal/text/text-abstraction/plugin/font-client-plugin-impl.h similarity index 94% rename from dali/internal/text/text-abstraction/font-client-plugin-impl.h rename to dali/internal/text/text-abstraction/plugin/font-client-plugin-impl.h index acd4be1..a8de931 100644 --- a/dali/internal/text/text-abstraction/font-client-plugin-impl.h +++ b/dali/internal/text/text-abstraction/plugin/font-client-plugin-impl.h @@ -35,7 +35,6 @@ class VectorFontCache; #include #include FT_FREETYPE_H #include FT_GLYPH_H -#include FT_OUTLINE_H #include FT_STROKER_H #include FT_SYNTHESIS_H @@ -461,17 +460,6 @@ private: bool MatchFontDescriptionToPattern(_FcPattern* pattern, Dali::TextAbstraction::FontDescription& fontDescription, _FcCharSet** characterSet); /** - * @brief Creates a font family pattern used to match fonts. - * - * @note Need to call FcPatternDestroy to free the resources. - * - * @param[in] fontDescription The font to cache. - * - * @return The pattern. - */ - _FcPattern* CreateFontFamilyPattern(const FontDescription& fontDescription) const; - - /** * @brief Retrieves the fonts present in the platform. * * @note Need to call FcFontSetDestroy to free the allocated resources. @@ -518,25 +506,6 @@ private: bool cacheDescription); /** - * @brief Copy the color bitmap given in @p srcBuffer to @p data. - * - * @param[out] data The bitmap data. - * @param[in] srcWidth The width of the bitmap. - * @param[in] srcHeight The height of the bitmap. - * @param[in] srcBuffer The buffer of the bitmap. - */ - void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, unsigned int srcWidth, unsigned int srcHeight, const unsigned char* const srcBuffer); - - /** - * @brief Copy the FreeType bitmap to the given buffer. - * - * @param[out] data The bitmap data. - * @param[in] srcBitmap The FreeType bitmap. - * @param[in] isShearRequired Whether the bitmap needs a shear transform (for software italics). - */ - void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, FT_Bitmap srcBitmap, bool isShearRequired); - - /** * @brief Finds in the cache if there is a triplet with the path to the font file name, the font point size and the face index. * If there is one , if writes the font identifier in the param @p fontId. * @@ -627,17 +596,6 @@ private: void CacheFontPath(FT_Face ftFace, FontId id, PointSize26Dot6 requestedPointSize, const FontPath& path); /** - * @brief Creates a character set from a given font's @p description. - * - * @note Need to call FcCharSetDestroy to free the resources. - * - * @param[in] description The font's description. - * - * @return A character set. - */ - _FcCharSet* CreateCharacterSetFromDescription(const FontDescription& description); - - /** * @brief Free the resources allocated in the fallback cache. * * @param[in] fallbackCache The fallback cache. diff --git a/dali/internal/text/text-abstraction/plugin/font-client-utils.cpp b/dali/internal/text/text-abstraction/plugin/font-client-utils.cpp new file mode 100644 index 0000000..d257d53 --- /dev/null +++ b/dali/internal/text/text-abstraction/plugin/font-client-utils.cpp @@ -0,0 +1,346 @@ +/* + * 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. + */ + +#include + +#include +#include + +#include + +extern Dali::Integration::Log::Filter* gFontClientLogFilter; + +namespace Dali::TextAbstraction::Internal +{ +namespace +{ +// http://www.freedesktop.org/software/fontconfig/fontconfig-user.html + +// NONE -1 --> DEFAULT_FONT_WIDTH (NORMAL) will be used. +// ULTRA_CONDENSED 50 +// EXTRA_CONDENSED 63 +// CONDENSED 75 +// SEMI_CONDENSED 87 +// NORMAL 100 +// SEMI_EXPANDED 113 +// EXPANDED 125 +// EXTRA_EXPANDED 150 +// ULTRA_EXPANDED 200 +const int FONT_WIDTH_TYPE_TO_INT[] = {-1, 50, 63, 75, 87, 100, 113, 125, 150, 200}; +const unsigned int NUM_FONT_WIDTH_TYPE = sizeof(FONT_WIDTH_TYPE_TO_INT) / sizeof(int); + +// NONE -1 --> DEFAULT_FONT_WEIGHT (NORMAL) will be used. +// THIN 0 +// ULTRA_LIGHT, EXTRA_LIGHT 40 +// LIGHT 50 +// DEMI_LIGHT, SEMI_LIGHT 55 +// BOOK 75 +// NORMAL, REGULAR 80 +// MEDIUM 100 +// DEMI_BOLD, SEMI_BOLD 180 +// BOLD 200 +// ULTRA_BOLD, EXTRA_BOLD 205 +// BLACK, HEAVY, EXTRA_BLACK 210 +const int FONT_WEIGHT_TYPE_TO_INT[] = {-1, 0, 40, 50, 55, 75, 80, 100, 180, 200, 205, 210}; +const unsigned int NUM_FONT_WEIGHT_TYPE = sizeof(FONT_WEIGHT_TYPE_TO_INT) / sizeof(int); + +// NONE -1 --> DEFAULT_FONT_SLANT (NORMAL) will be used. +// NORMAL, ROMAN 0 +// ITALIC 100 +// OBLIQUE 110 +const int FONT_SLANT_TYPE_TO_INT[] = {-1, 0, 100, 110}; +const unsigned int NUM_FONT_SLANT_TYPE = sizeof(FONT_SLANT_TYPE_TO_INT) / sizeof(int); + +} // namespace + +/** + * @brief Returns the FontWidth's enum index for the given width value. + * + * @param[in] width The width value. + * + * @return The FontWidth's enum index. + */ +const FontWidth::Type IntToWidthType(int width) +{ + return static_cast(ValueToIndex(width, FONT_WIDTH_TYPE_TO_INT, NUM_FONT_WIDTH_TYPE - 1u)); +} + +/** + * @brief Returns the FontWeight's enum index for the given weight value. + * + * @param[in] weight The weight value. + * + * @return The FontWeight's enum index. + */ +const FontWeight::Type IntToWeightType(int weight) +{ + return static_cast(ValueToIndex(weight, FONT_WEIGHT_TYPE_TO_INT, NUM_FONT_WEIGHT_TYPE - 1u)); +} + +/** + * @brief Returns the FontSlant's enum index for the given slant value. + * + * @param[in] slant The slant value. + * + * @return The FontSlant's enum index. + */ +const FontSlant::Type IntToSlantType(int slant) +{ + return static_cast(ValueToIndex(slant, FONT_SLANT_TYPE_TO_INT, NUM_FONT_SLANT_TYPE - 1u)); +} + +const int DEFAULT_FONT_WIDTH(100); +const int DEFAULT_FONT_WEIGHT(80); +const int DEFAULT_FONT_SLANT(0); + +const FontWidth::Type DefaultFontWidth() +{ + return IntToWidthType(DEFAULT_FONT_WIDTH); +} +const FontWeight::Type DefaultFontWeight() +{ + return IntToWeightType(DEFAULT_FONT_WEIGHT); +} +const FontSlant::Type DefaultFontSlant() +{ + return IntToSlantType(DEFAULT_FONT_SLANT); +} + +/** + * @brief Copy the color bitmap given in @p srcBuffer to @p data. + * + * @param[out] data The bitmap data. + * @param[in] srcWidth The width of the bitmap. + * @param[in] srcHeight The height of the bitmap. + * @param[in] srcBuffer The buffer of the bitmap. + */ +void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, unsigned int srcWidth, unsigned int srcHeight, const unsigned char* const srcBuffer) +{ + // Set the input dimensions. + const ImageDimensions inputDimensions(srcWidth, srcHeight); + + // Set the output dimensions. + // If the output dimension is not given, the input dimension is set + // and won't be downscaling. + data.width = (data.width == 0) ? srcWidth : data.width; + data.height = (data.height == 0) ? srcHeight : data.height; + const ImageDimensions desiredDimensions(data.width, data.height); + + // Creates the output buffer + const unsigned int bufferSize = data.width * data.height * 4u; + data.buffer = new unsigned char[bufferSize]; // @note The caller is responsible for deallocating the bitmap data using delete[]. + + if(inputDimensions == desiredDimensions) + { + // There isn't downscaling. + memcpy(data.buffer, srcBuffer, bufferSize); + } + else + { + Dali::Internal::Platform::LanczosSample4BPP(srcBuffer, + inputDimensions, + data.buffer, + desiredDimensions); + } +} + +/** + * @brief Copy the FreeType bitmap to the given buffer. + * + * @param[out] data The bitmap data. + * @param[in] srcBitmap The FreeType bitmap. + * @param[in] isShearRequired Whether the bitmap needs a shear transform (for software italics). + */ +void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, FT_Bitmap srcBitmap, bool isShearRequired) +{ + if(srcBitmap.width * srcBitmap.rows > 0) + { + switch(srcBitmap.pixel_mode) + { + case FT_PIXEL_MODE_GRAY: + { + if(srcBitmap.pitch == static_cast(srcBitmap.width)) + { + uint8_t* pixelsIn = srcBitmap.buffer; + unsigned int width = srcBitmap.width; + unsigned height = srcBitmap.rows; + + std::unique_ptr pixelsOutPtr(nullptr, free); + + if(isShearRequired) + { + /** + * Glyphs' bitmaps with no slant retrieved from FreeType: + * __________ ____ + * |XXXXXXXX| |XX| + * | XX | |XX| + * | XX | |XX| + * | XX | |XX| + * | XX | |XX| + * | XX | |XX| + * ---------- ---- + * + * Expected glyphs' bitmaps with italic slant: + * ____________ ______ + * | XXXXXXXX| | XX| + * | XX | | XX| + * | XX | | XX | + * | XX | | XX | + * | XX | |XX | + * | XX | |XX | + * ------------ ------ + * + * Glyphs' bitmaps with software italic slant retrieved from FreeType: + * __________ ______ + * |XXXXXXXX| | XX| + * | XX | | XX| + * | XX | | XX | + * | XX | | XX | + * | XX | |XX | + * | XX | |XX | + * ---------- ------ + * + * This difference in some bitmaps' width causes an overlap of some glyphs. This is the reason why a shear operation is done here instead of relying on the experimental FT_GlyphSlot_Oblique() implementation. + */ + unsigned int widthOut = 0u; + unsigned int heightOut = 0u; + uint8_t* pixelsOut = nullptr; + + Dali::Internal::Platform::HorizontalShear(pixelsIn, + width, + height, + 1u, + -TextAbstraction::FontClient::DEFAULT_ITALIC_ANGLE, + pixelsOut, + widthOut, + heightOut); + + width = widthOut; + height = heightOut; + pixelsIn = pixelsOut; + pixelsOutPtr.reset(pixelsOut); + } + + const unsigned int bufferSize = width * height; + data.buffer = new unsigned char[bufferSize]; // @note The caller is responsible for deallocating the bitmap data using delete[]. + data.width = width; + data.height = height; + data.format = Pixel::L8; // Sets the pixel format. + memcpy(data.buffer, pixelsIn, bufferSize); + } + break; + } + +#ifdef FREETYPE_BITMAP_SUPPORT + case FT_PIXEL_MODE_BGRA: + { + if(srcBitmap.pitch == static_cast(srcBitmap.width << 2u)) + { + ConvertBitmap(data, srcBitmap.width, srcBitmap.rows, srcBitmap.buffer); + + // Sets the pixel format. + data.format = Pixel::BGRA8888; + } + break; + } +#endif + default: + { + DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "FontClient::Plugin::ConvertBitmap. FontClient Unable to create Bitmap of this PixelType\n"); + break; + } + } + } +} + +FcPattern* CreateFontFamilyPattern(const FontDescription& fontDescription) +{ + // create the cached font family lookup pattern + // a pattern holds a set of names, each name refers to a property of the font + FcPattern* fontFamilyPattern = FcPatternCreate(); // FcPatternCreate creates a new pattern that needs to be destroyed by calling FcPatternDestroy. + + if(!fontFamilyPattern) + { + return nullptr; + } + + // add a property to the pattern for the font family + FcPatternAddString(fontFamilyPattern, FC_FAMILY, reinterpret_cast(fontDescription.family.c_str())); + + // add a property to the pattern for local setting. + const char* locale = setlocale(LC_MESSAGES, nullptr); + if(locale != nullptr) + { + FcPatternAddString(fontFamilyPattern, FC_LANG, reinterpret_cast(locale)); + } + + int width = FONT_WIDTH_TYPE_TO_INT[fontDescription.width]; + if(width < 0) + { + // Use default. + width = DEFAULT_FONT_WIDTH; + } + + int weight = FONT_WEIGHT_TYPE_TO_INT[fontDescription.weight]; + if(weight < 0) + { + // Use default. + weight = DEFAULT_FONT_WEIGHT; + } + + int slant = FONT_SLANT_TYPE_TO_INT[fontDescription.slant]; + if(slant < 0) + { + // Use default. + slant = DEFAULT_FONT_SLANT; + } + + FcPatternAddInteger(fontFamilyPattern, FC_WIDTH, width); + FcPatternAddInteger(fontFamilyPattern, FC_WEIGHT, weight); + FcPatternAddInteger(fontFamilyPattern, FC_SLANT, slant); + + // modify the config, with the mFontFamilyPatterm + FcConfigSubstitute(nullptr /* use default configure */, fontFamilyPattern, FcMatchPattern); + + // provide default values for unspecified properties in the font pattern + // e.g. patterns without a specified style or weight are set to Medium + FcDefaultSubstitute(fontFamilyPattern); + + return fontFamilyPattern; +} + +FcCharSet* CreateCharacterSetFromDescription(const FontDescription& description) +{ + FcCharSet* characterSet = nullptr; + + FcPattern* pattern = CreateFontFamilyPattern(description); // Creates a new pattern that needs to be destroyed by calling FcPatternDestroy. + + if(nullptr != pattern) + { + FcResult result = FcResultMatch; + FcPattern* match = FcFontMatch(nullptr, pattern, &result); // FcFontMatch creates a new pattern that needs to be destroyed by calling FcPatternDestroy. + + FcPatternGetCharSet(match, FC_CHARSET, 0u, &characterSet); + + // Destroys the created patterns. + FcPatternDestroy(match); + FcPatternDestroy(pattern); + } + + return characterSet; +} + +} // namespace Dali::TextAbstraction::Internal diff --git a/dali/internal/text/text-abstraction/plugin/font-client-utils.h b/dali/internal/text/text-abstraction/plugin/font-client-utils.h new file mode 100644 index 0000000..4465521 --- /dev/null +++ b/dali/internal/text/text-abstraction/plugin/font-client-utils.h @@ -0,0 +1,127 @@ +#ifndef DALI_TEST_ABSTRACTION_INTERNAL_FONT_CLIENT_UTILS_H +#define DALI_TEST_ABSTRACTION_INTERNAL_FONT_CLIENT_UTILS_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 + +// EXTERNAL INCLUDES +#include + +#include +#include FT_FREETYPE_H + +namespace Dali::TextAbstraction::Internal +{ +void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, + unsigned int srcWidth, + unsigned int srcHeight, + const unsigned char* const srcBuffer); + +void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, + FT_Bitmap srcBitmap, + bool isShearRequired); + +/** + * @brief Creates a font family pattern used to match fonts. + * + * @note Need to call FcPatternDestroy to free the resources. + * + * @param[in] fontDescription The font to cache. + * + * @return The pattern. + */ +FcPattern* CreateFontFamilyPattern(const FontDescription& fontDescription); + +/** + * @brief Creates a character set from a given font's @p description. + * + * @note Need to call FcCharSetDestroy to free the resources. + * + * @param[in] description The font's description. + * + * @return A character set. + */ +FcCharSet* CreateCharacterSetFromDescription(const FontDescription& description); + +constexpr int ValueToIndex(int value, const int* const table, unsigned int maxIndex) +{ + if(nullptr == table) + { + // Return an invalid index if there is no table. + return -1; + } + + if(value <= table[0]) + { + return 0; + } + + if(value >= table[maxIndex]) + { + return maxIndex; + } + + for(unsigned int index = 0u; index < maxIndex; ++index) + { + const int v1 = table[index]; + const unsigned int indexPlus = index + 1u; + const int v2 = table[indexPlus]; + if((v1 < value) && (value <= v2)) + { + const int result = ((v1 > 0) && ((value - v1) < (v2 - value))) ? index : indexPlus; + return result; + } + } + return 0; +} + +/** + * @brief Returns the FontWidth's enum index for the given width value. + * + * @param[in] width The width value. + * + * @return The FontWidth's enum index. + */ +const FontWidth::Type IntToWidthType(int width); + +/** + * @brief Returns the FontWeight's enum index for the given weight value. + * + * @param[in] weight The weight value. + * + * @return The FontWeight's enum index. + */ +const FontWeight::Type IntToWeightType(int weight); + +/** + * @brief Returns the FontSlant's enum index for the given slant value. + * + * @param[in] slant The slant value. + * + * @return The FontSlant's enum index. + */ +const FontSlant::Type IntToSlantType(int slant); + +const FontWidth::Type DefaultFontWidth(); +const FontWeight::Type DefaultFontWeight(); +const FontSlant::Type DefaultFontSlant(); + +} // namespace Dali::TextAbstraction::Internal + +#endif // DALI_TEST_ABSTRACTION_INTERNAL_FONT_CLIENT_UTILS_H