(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
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})
#include <dali-test-suite-utils.h>
#include <dali/dali.h>
#include <dali/devel-api/text-abstraction/font-client.h>
-#include <dali/internal/text/text-abstraction/font-client-helper.h>
+#include <dali/internal/text/text-abstraction/plugin/font-client-utils.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
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}")
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
)
-
+++ /dev/null
-/*
- * 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 <dali/internal/text/text-abstraction/font-client-helper.h>
-
-// INTERNAL INCLUDES
-
-#include <dali/integration-api/debug.h>
-
-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
+++ /dev/null
-#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
// INTERNAL INCLUDES
#include <dali/devel-api/common/singleton-service.h>
-#include <dali/internal/text/text-abstraction/font-client-plugin-impl.h>
+#include <dali/internal/text/text-abstraction/plugin/font-client-plugin-impl.h>
#include <dali/devel-api/text-abstraction/glyph-info.h>
*/
// CLASS HEADER
-#include <dali/internal/text/text-abstraction/font-client-plugin-impl.h>
+#include <dali/internal/text/text-abstraction/plugin/font-client-plugin-impl.h>
// INTERNAL INCLUDES
#include <dali/devel-api/text-abstraction/font-list.h>
#include <dali/integration-api/platform-abstraction.h>
#include <dali/internal/adaptor/common/adaptor-impl.h>
#include <dali/internal/imaging/common/image-operations.h>
-#include <dali/internal/text/text-abstraction/font-client-helper.h>
+#include <dali/internal/text/text-abstraction/plugin/font-client-utils.h>
#include <dali/public-api/common/dali-vector.h>
#include <dali/public-api/common/vector-wrapper.h>
#include <algorithm>
#include <iterator>
-namespace
-{
#if defined(DEBUG_ENABLED)
// Note, to turn on trace and verbose logging, use "export LOG_FONT_CLIENT=3,true"
#endif
+namespace
+{
/**
* Conversion from Fractional26.6 to float
*/
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;
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<FontWidth::Type>(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<FontWeight::Type>(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<FontSlant::Type>(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.
{
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);
}
{
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);
}
// 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());
return mEmbeddedItemCache.Count();
}
-//SHS
void FontClient::Plugin::EnableAtlasLimitation(bool enabled)
{
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<const FcChar8*>(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<const FcChar8*>(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;
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<int>(srcBitmap.width))
- {
- uint8_t* pixelsIn = srcBitmap.buffer;
- unsigned int width = srcBitmap.width;
- unsigned height = srcBitmap.rows;
-
- std::unique_ptr<uint8_t, void (*)(void*)> 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<int>(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,
}
}
-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<FallbackCacheItem>& fallbackCache)
{
for(auto& item : fallbackCache)
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
-#include FT_OUTLINE_H
#include FT_STROKER_H
#include FT_SYNTHESIS_H
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.
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.
*
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.
--- /dev/null
+/*
+ * 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 <dali/internal/text/text-abstraction/plugin/font-client-utils.h>
+
+#include <dali/integration-api/debug.h>
+#include <dali/internal/imaging/common/image-operations.h>
+
+#include <memory>
+
+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<FontWidth::Type>(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<FontWeight::Type>(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<FontSlant::Type>(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<int>(srcBitmap.width))
+ {
+ uint8_t* pixelsIn = srcBitmap.buffer;
+ unsigned int width = srcBitmap.width;
+ unsigned height = srcBitmap.rows;
+
+ std::unique_ptr<uint8_t, void (*)(void*)> 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<int>(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<const FcChar8*>(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<const FcChar8*>(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
--- /dev/null
+#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 <dali/devel-api/text-abstraction/font-client.h>
+
+// EXTERNAL INCLUDES
+#include <fontconfig/fontconfig.h>
+
+#include <ft2build.h>
+#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