From: Paul Wisbey Date: Thu, 7 Apr 2016 09:09:34 +0000 (-0700) Subject: Merge "Fix for font validation." into devel/master X-Git-Tag: dali_1.1.29~2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=848787435a85536032861126d0feffe7b1870911;hp=7862c06931f3feb015f06a011c875014e4cd2b37 Merge "Fix for font validation." into devel/master --- diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp index 7fc8f71..eea51a6 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp @@ -1243,15 +1243,26 @@ int UtcDaliTextMultiLanguageValidateFonts01(void) const std::string pathName( pathNamePtr ); free( pathNamePtr ); + const PointSize26Dot6 pointSize01 = static_cast( 21.f * 64.f ); + const PointSize26Dot6 pointSize02 = static_cast( 35.f * 64.f ); + // Load some fonts. fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansArabicRegular.ttf" ); fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansHebrewRegular.ttf" ); fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenColorEmoji.ttf", EMOJI_FONT_SIZE ); + fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf", pointSize01 ); + fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf", pointSize02 ); + fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansHebrewRegular.ttf", pointSize01 ); + fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansHebrewRegular.ttf", pointSize02 ); // Font id 1 --> TizenSansArabicRegular.ttf // Font id 2 --> TizenSansHebrewRegular.ttf // Font id 3 --> TizenColorEmoji.ttf - // Font id 4 --> (default) + // Font id 4 --> TizenSansRegular.ttf, size 8 + // Font id 5 --> TizenSansRegular.ttf, size 16 + // Font id 6 --> TizenSansHebrewRegular.ttf, size 8 + // Font id 7 --> TizenSansHebrewRegular.ttf, size 16 + // Font id 8 --> (default) Vector fontRuns01; Vector fontDescriptions01; @@ -1262,7 +1273,7 @@ int UtcDaliTextMultiLanguageValidateFonts01(void) 0u, 11u }, - 4u + 8u }; Vector fontRuns02; fontRuns02.PushBack( fontRun0201 ); @@ -1294,7 +1305,7 @@ int UtcDaliTextMultiLanguageValidateFonts01(void) 0u, 12u }, - 4u + 8u }; FontRun fontRun0302 = { @@ -1302,7 +1313,7 @@ int UtcDaliTextMultiLanguageValidateFonts01(void) 12u, 12u }, - 4u + 8u }; FontRun fontRun0303 = { @@ -1310,7 +1321,7 @@ int UtcDaliTextMultiLanguageValidateFonts01(void) 24u, 4u }, - 4u + 8u }; Vector fontRuns03; fontRuns03.PushBack( fontRun0301 ); @@ -1333,7 +1344,7 @@ int UtcDaliTextMultiLanguageValidateFonts01(void) 4u, 1u }, - 4u + 8u }; FontRun fontRun0703 = { @@ -1433,6 +1444,122 @@ int UtcDaliTextMultiLanguageValidateFonts01(void) }; fontDescriptions09.PushBack( fontDescription0901 ); + FontRun fontRun1001 = + { + { + 0u, + 13u + }, + 4u + }; + FontRun fontRun1002 = + { + { + 13u, + 9u + }, + 6u + }; + FontRun fontRun1003 = + { + { + 22u, + 15u + }, + 5u + }; + FontRun fontRun1004 = + { + { + 37u, + 9u + }, + 7u + }; + Vector fontRuns10; + fontRuns10.PushBack( fontRun1001 ); + fontRuns10.PushBack( fontRun1002 ); + fontRuns10.PushBack( fontRun1003 ); + fontRuns10.PushBack( fontRun1004 ); + + FontDescriptionRun fontDescription1001 = + { + { + 0u, + 13u + }, + const_cast( "TizenSans" ), + 9u, + TextAbstraction::FontWeight::NORMAL, + TextAbstraction::FontWidth::NORMAL, + TextAbstraction::FontSlant::NORMAL, + pointSize01, + true, + false, + false, + false, + true + }; + FontDescriptionRun fontDescription1002 = + { + { + 13u, + 9u + }, + const_cast( "TizenSansHebrew" ), + 15u, + TextAbstraction::FontWeight::NORMAL, + TextAbstraction::FontWidth::NORMAL, + TextAbstraction::FontSlant::NORMAL, + pointSize01, + true, + false, + false, + false, + true + }; + FontDescriptionRun fontDescription1003 = + { + { + 22u, + 15u + }, + const_cast( "TizenSans" ), + 9u, + TextAbstraction::FontWeight::NORMAL, + TextAbstraction::FontWidth::NORMAL, + TextAbstraction::FontSlant::NORMAL, + pointSize02, + true, + false, + false, + false, + true + }; + FontDescriptionRun fontDescription1004 = + { + { + 37u, + 9u + }, + const_cast( "TizenSansHebrew" ), + 15u, + TextAbstraction::FontWeight::NORMAL, + TextAbstraction::FontWidth::NORMAL, + TextAbstraction::FontSlant::NORMAL, + pointSize02, + true, + false, + false, + false, + true + }; + Vector fontDescriptions10; + fontDescriptions10.PushBack( fontDescription1001 ); + fontDescriptions10.PushBack( fontDescription1002 ); + fontDescriptions10.PushBack( fontDescription1003 ); + fontDescriptions10.PushBack( fontDescription1004 ); + const ValidateFontsData data[] = { { @@ -1525,8 +1652,18 @@ int UtcDaliTextMultiLanguageValidateFonts01(void) fontDescriptions09, fontRuns09 }, + { + "Mix text. Default font: latin. Different font sizes", + "Hello world, שלום עולם, hello world, שלום עולם", + "/tizen/TizenSansRegular.ttf", + TextAbstraction::FontClient::DEFAULT_POINT_SIZE, + 0u, + 46u, + fontDescriptions10, + fontRuns10 + }, }; - const unsigned int numberOfTests = 9u; + const unsigned int numberOfTests = 10u; for( unsigned int index = 0u; index < numberOfTests; ++index ) { diff --git a/dali-toolkit/internal/text/multi-language-support-impl.cpp b/dali-toolkit/internal/text/multi-language-support-impl.cpp index 81598d9..ec9167b 100644 --- a/dali-toolkit/internal/text/multi-language-support-impl.cpp +++ b/dali-toolkit/internal/text/multi-language-support-impl.cpp @@ -63,13 +63,30 @@ bool ValidateFontsPerScript::FindValidFont( FontId fontId ) const return false; } +FontId DefaultFonts::FindFont( TextAbstraction::FontClient& fontClient, PointSize26Dot6 size ) const +{ + for( Vector::ConstIterator it = mFonts.Begin(), + endIt = mFonts.End(); + it != endIt; + ++it ) + { + const FontId fontId = *it; + if( size == fontClient.GetPointSize( fontId ) ) + { + return fontId; + } + } + + return 0u; +} + MultilanguageSupport::MultilanguageSupport() : mDefaultFontPerScriptCache(), mValidFontsPerScriptCache() { // Initializes the default font cache to zero (invalid font). // Reserves space to cache the default fonts and access them with the script as an index. - mDefaultFontPerScriptCache.Resize( TextAbstraction::UNKNOWN, 0u ); + mDefaultFontPerScriptCache.Resize( TextAbstraction::UNKNOWN, NULL ); // Initializes the valid fonts cache to NULL (no valid fonts). // Reserves space to cache the valid fonts and access them with the script as an index. @@ -78,8 +95,16 @@ MultilanguageSupport::MultilanguageSupport() MultilanguageSupport::~MultilanguageSupport() { - // Destroy the valid fonts per script cache. + // Destroy the default font per script cache. + for( Vector::Iterator it = mDefaultFontPerScriptCache.Begin(), + endIt = mDefaultFontPerScriptCache.End(); + it != endIt; + ++it ) + { + delete *it; + } + // Destroy the valid fonts per script cache. for( Vector::Iterator it = mValidFontsPerScriptCache.Begin(), endIt = mValidFontsPerScriptCache.End(); it != endIt; @@ -363,7 +388,7 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, // Traverse the characters and validate/set the fonts. // Get the caches. - FontId* defaultFontPerScriptCacheBuffer = mDefaultFontPerScriptCache.Begin(); + DefaultFonts** defaultFontPerScriptCacheBuffer = mDefaultFontPerScriptCache.Begin(); ValidateFontsPerScript** validFontsPerScriptCacheBuffer = mValidFontsPerScriptCache.Begin(); // Stores the validated font runs. @@ -403,6 +428,9 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, Vector::ConstIterator scriptRunEndIt = scripts.End(); bool isNewParagraphCharacter = false; + PointSize26Dot6 currentPointSize = defaultPointSize; + FontId currentFontId = 0u; + CharacterIndex lastCharacter = startIndex + numberOfCharacters; for( Length index = startIndex; index < lastCharacter; ++index ) { @@ -417,6 +445,13 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, scriptRunIt, scriptRunEndIt ); + // Get the current point size. + if( currentFontId != fontId ) + { + currentPointSize = fontClient.GetPointSize( fontId ); + currentFontId = fontId; + } + #ifdef DEBUG_ENABLED { Dali::TextAbstraction::FontDescription description; @@ -438,8 +473,15 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, // Check first in the caches. + DefaultFonts* defaultFonts = *( defaultFontPerScriptCacheBuffer + script ); + FontId cachedDefaultFontId = 0u; + if( NULL != defaultFonts ) + { + cachedDefaultFontId = defaultFonts->FindFont( fontClient, currentPointSize ); + } + // The user may have set the default font. Check it. Otherwise check in the valid fonts cache. - if( fontId != *( defaultFontPerScriptCacheBuffer + script ) ) + if( fontId != cachedDefaultFontId ) { // Check in the valid fonts cache. ValidateFontsPerScript* validateFontsPerScript = *( validFontsPerScriptCacheBuffer + script ); @@ -508,7 +550,7 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, if( 0u == fontId ) { // The character has no font assigned. Get a default one from the cache - fontId = *( defaultFontPerScriptCacheBuffer + script ); + fontId = cachedDefaultFontId; // If the cache has not a default font, get one from the font client. if( 0u == fontId ) @@ -517,20 +559,31 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, bool preferColor = ( TextAbstraction::EMOJI == script ); // Find a fallback-font. - fontId = fontClient.FindFallbackFont( preferredFont, character, defaultPointSize, preferColor ); + fontId = fontClient.FindFallbackFont( preferredFont, character, currentPointSize, preferColor ); // If the system does not support a suitable font, fallback to Latin + DefaultFonts* latinDefaults = NULL; if( 0u == fontId ) { - fontId = *( defaultFontPerScriptCacheBuffer + TextAbstraction::LATIN ); + latinDefaults = *( defaultFontPerScriptCacheBuffer + TextAbstraction::LATIN ); + if( NULL != latinDefaults ) + { + fontId = latinDefaults->FindFont( fontClient, currentPointSize ); + } } + if( 0u == fontId ) { - fontId = fontClient.FindDefaultFont( UTF32_A, defaultPointSize ); + fontId = fontClient.FindDefaultFont( UTF32_A, currentPointSize ); } // Cache the font. - *( defaultFontPerScriptCacheBuffer + script ) = fontId; + if( NULL == latinDefaults ) + { + latinDefaults = new DefaultFonts(); + *( defaultFontPerScriptCacheBuffer + script ) = latinDefaults; + } + latinDefaults->mFonts.PushBack( fontId ); } } diff --git a/dali-toolkit/internal/text/multi-language-support-impl.h b/dali-toolkit/internal/text/multi-language-support-impl.h index 781aed5..283b021 100644 --- a/dali-toolkit/internal/text/multi-language-support-impl.h +++ b/dali-toolkit/internal/text/multi-language-support-impl.h @@ -27,6 +27,12 @@ namespace Dali { +namespace TextAbstraction +{ +//Forward declaration +class FontClient; +} + namespace Toolkit { @@ -67,6 +73,37 @@ struct ValidateFontsPerScript }; /** + * @brief Stores default font ids per script. It can be different sizes for a default font family. + */ +struct DefaultFonts +{ + /** + * Default constructor. + */ + DefaultFonts() + : mFonts() + {} + + /** + * Default destructor. + */ + ~DefaultFonts() + {} + + /** + * @brief Finds a default font for the given @p size. + * + * @param[in] fontClient The font client. + * @param[in] size The given size. + * + * @return The font id of a default font for the given @p size. If there isn't any font cached it returns 0. + */ + FontId FindFont( TextAbstraction::FontClient& fontClient, PointSize26Dot6 size ) const; + + Vector mFonts; +}; + +/** * @brief Multi-language support implementation. @see Text::MultilanguageSupport. */ class MultilanguageSupport : public BaseObject @@ -110,7 +147,7 @@ public: Vector& fonts ); private: - Vector mDefaultFontPerScriptCache; ///< Caches the default font for a script. + Vector mDefaultFontPerScriptCache; ///< Caches default fonts for a script. Vector mValidFontsPerScriptCache; ///< Caches valid fonts for a script. };