Fix for font validation. 38/64838/3
authorVictor Cebollada <v.cebollada@samsung.com>
Tue, 5 Apr 2016 08:40:49 +0000 (09:40 +0100)
committerVíctor Cebollada <v.cebollada@samsung.com>
Wed, 6 Apr 2016 06:02:53 +0000 (23:02 -0700)
Bug fixed when:
 * There are different texts.
 * No font's family is set to the texts.
 * Texts are not supported by the default font.
 * Texts are set different sizes.

Only one default font (with only one size) was cached per script.

Change-Id: Ifdc1691b797432521c16f236769c127ab1848433
Signed-off-by: Victor Cebollada <v.cebollada@samsung.com>
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp
dali-toolkit/internal/text/multi-language-support-impl.cpp
dali-toolkit/internal/text/multi-language-support-impl.h

index 7fc8f71..eea51a6 100644 (file)
@@ -1243,15 +1243,26 @@ int UtcDaliTextMultiLanguageValidateFonts01(void)
   const std::string pathName( pathNamePtr );
   free( pathNamePtr );
 
   const std::string pathName( pathNamePtr );
   free( pathNamePtr );
 
+  const PointSize26Dot6 pointSize01 = static_cast<PointSize26Dot6>( 21.f * 64.f );
+  const PointSize26Dot6 pointSize02 = static_cast<PointSize26Dot6>( 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 );
   // 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 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<FontRun> fontRuns01;
   Vector<FontDescriptionRun> fontDescriptions01;
 
   Vector<FontRun> fontRuns01;
   Vector<FontDescriptionRun> fontDescriptions01;
@@ -1262,7 +1273,7 @@ int UtcDaliTextMultiLanguageValidateFonts01(void)
       0u,
       11u
     },
       0u,
       11u
     },
-    4u
+    8u
   };
   Vector<FontRun> fontRuns02;
   fontRuns02.PushBack( fontRun0201 );
   };
   Vector<FontRun> fontRuns02;
   fontRuns02.PushBack( fontRun0201 );
@@ -1294,7 +1305,7 @@ int UtcDaliTextMultiLanguageValidateFonts01(void)
       0u,
       12u
     },
       0u,
       12u
     },
-    4u
+    8u
   };
   FontRun fontRun0302 =
   {
   };
   FontRun fontRun0302 =
   {
@@ -1302,7 +1313,7 @@ int UtcDaliTextMultiLanguageValidateFonts01(void)
       12u,
       12u
     },
       12u,
       12u
     },
-    4u
+    8u
   };
   FontRun fontRun0303 =
   {
   };
   FontRun fontRun0303 =
   {
@@ -1310,7 +1321,7 @@ int UtcDaliTextMultiLanguageValidateFonts01(void)
       24u,
       4u
     },
       24u,
       4u
     },
-    4u
+    8u
   };
   Vector<FontRun> fontRuns03;
   fontRuns03.PushBack( fontRun0301 );
   };
   Vector<FontRun> fontRuns03;
   fontRuns03.PushBack( fontRun0301 );
@@ -1333,7 +1344,7 @@ int UtcDaliTextMultiLanguageValidateFonts01(void)
       4u,
       1u
     },
       4u,
       1u
     },
-    4u
+    8u
   };
   FontRun fontRun0703 =
   {
   };
   FontRun fontRun0703 =
   {
@@ -1433,6 +1444,122 @@ int UtcDaliTextMultiLanguageValidateFonts01(void)
   };
   fontDescriptions09.PushBack( fontDescription0901 );
 
   };
   fontDescriptions09.PushBack( fontDescription0901 );
 
+  FontRun fontRun1001 =
+  {
+    {
+      0u,
+      13u
+    },
+    4u
+  };
+  FontRun fontRun1002 =
+  {
+    {
+      13u,
+      9u
+    },
+    6u
+  };
+  FontRun fontRun1003 =
+  {
+    {
+      22u,
+      15u
+    },
+    5u
+  };
+  FontRun fontRun1004 =
+  {
+    {
+      37u,
+      9u
+    },
+    7u
+  };
+  Vector<FontRun> fontRuns10;
+  fontRuns10.PushBack( fontRun1001 );
+  fontRuns10.PushBack( fontRun1002 );
+  fontRuns10.PushBack( fontRun1003 );
+  fontRuns10.PushBack( fontRun1004 );
+
+  FontDescriptionRun fontDescription1001 =
+  {
+    {
+      0u,
+      13u
+    },
+    const_cast<char*>( "TizenSans" ),
+    9u,
+    TextAbstraction::FontWeight::NORMAL,
+    TextAbstraction::FontWidth::NORMAL,
+    TextAbstraction::FontSlant::NORMAL,
+    pointSize01,
+    true,
+    false,
+    false,
+    false,
+    true
+  };
+  FontDescriptionRun fontDescription1002 =
+  {
+    {
+      13u,
+      9u
+    },
+    const_cast<char*>( "TizenSansHebrew" ),
+    15u,
+    TextAbstraction::FontWeight::NORMAL,
+    TextAbstraction::FontWidth::NORMAL,
+    TextAbstraction::FontSlant::NORMAL,
+    pointSize01,
+    true,
+    false,
+    false,
+    false,
+    true
+  };
+  FontDescriptionRun fontDescription1003 =
+  {
+    {
+      22u,
+      15u
+    },
+    const_cast<char*>( "TizenSans" ),
+    9u,
+    TextAbstraction::FontWeight::NORMAL,
+    TextAbstraction::FontWidth::NORMAL,
+    TextAbstraction::FontSlant::NORMAL,
+    pointSize02,
+    true,
+    false,
+    false,
+    false,
+    true
+  };
+  FontDescriptionRun fontDescription1004 =
+  {
+    {
+      37u,
+      9u
+    },
+    const_cast<char*>( "TizenSansHebrew" ),
+    15u,
+    TextAbstraction::FontWeight::NORMAL,
+    TextAbstraction::FontWidth::NORMAL,
+    TextAbstraction::FontSlant::NORMAL,
+    pointSize02,
+    true,
+    false,
+    false,
+    false,
+    true
+  };
+  Vector<FontDescriptionRun> fontDescriptions10;
+  fontDescriptions10.PushBack( fontDescription1001 );
+  fontDescriptions10.PushBack( fontDescription1002 );
+  fontDescriptions10.PushBack( fontDescription1003 );
+  fontDescriptions10.PushBack( fontDescription1004 );
+
   const ValidateFontsData data[] =
   {
     {
   const ValidateFontsData data[] =
   {
     {
@@ -1525,8 +1652,18 @@ int UtcDaliTextMultiLanguageValidateFonts01(void)
       fontDescriptions09,
       fontRuns09
     },
       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 )
   {
 
   for( unsigned int index = 0u; index < numberOfTests; ++index )
   {
index 81598d9..ec9167b 100644 (file)
@@ -63,13 +63,30 @@ bool ValidateFontsPerScript::FindValidFont( FontId fontId ) const
   return false;
 }
 
   return false;
 }
 
+FontId DefaultFonts::FindFont( TextAbstraction::FontClient& fontClient, PointSize26Dot6 size ) const
+{
+  for( Vector<FontId>::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.
 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.
 
   // 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()
 {
 
 MultilanguageSupport::~MultilanguageSupport()
 {
-  // Destroy the valid fonts per script cache.
+  // Destroy the default font per script cache.
+  for( Vector<DefaultFonts*>::Iterator it = mDefaultFontPerScriptCache.Begin(),
+         endIt = mDefaultFontPerScriptCache.End();
+       it != endIt;
+       ++it )
+  {
+    delete *it;
+  }
 
 
+  // Destroy the valid fonts per script cache.
   for( Vector<ValidateFontsPerScript*>::Iterator it = mValidFontsPerScriptCache.Begin(),
          endIt = mValidFontsPerScriptCache.End();
        it != endIt;
   for( Vector<ValidateFontsPerScript*>::Iterator it = mValidFontsPerScriptCache.Begin(),
          endIt = mValidFontsPerScriptCache.End();
        it != endIt;
@@ -363,7 +388,7 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
   // Traverse the characters and validate/set the fonts.
 
   // Get the caches.
   // 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.
   ValidateFontsPerScript** validFontsPerScriptCacheBuffer = mValidFontsPerScriptCache.Begin();
 
   // Stores the validated font runs.
@@ -403,6 +428,9 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
   Vector<ScriptRun>::ConstIterator scriptRunEndIt = scripts.End();
   bool isNewParagraphCharacter = false;
 
   Vector<ScriptRun>::ConstIterator scriptRunEndIt = scripts.End();
   bool isNewParagraphCharacter = false;
 
+  PointSize26Dot6 currentPointSize = defaultPointSize;
+  FontId currentFontId = 0u;
+
   CharacterIndex lastCharacter = startIndex + numberOfCharacters;
   for( Length index = startIndex; index < lastCharacter; ++index )
   {
   CharacterIndex lastCharacter = startIndex + numberOfCharacters;
   for( Length index = startIndex; index < lastCharacter; ++index )
   {
@@ -417,6 +445,13 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
                                scriptRunIt,
                                scriptRunEndIt );
 
                                scriptRunIt,
                                scriptRunEndIt );
 
+    // Get the current point size.
+    if( currentFontId != fontId )
+    {
+      currentPointSize = fontClient.GetPointSize( fontId );
+      currentFontId = fontId;
+    }
+
 #ifdef DEBUG_ENABLED
     {
       Dali::TextAbstraction::FontDescription description;
 #ifdef DEBUG_ENABLED
     {
       Dali::TextAbstraction::FontDescription description;
@@ -438,8 +473,15 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
 
     // Check first in the caches.
 
 
     // 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.
     // 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 );
     {
       // Check in the valid fonts cache.
       ValidateFontsPerScript* validateFontsPerScript = *( validFontsPerScriptCacheBuffer + script );
@@ -508,7 +550,7 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
     if( 0u == fontId )
     {
       // The character has no font assigned. Get a default one from the cache
     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 )
 
       // 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<Character>& text,
         bool preferColor = ( TextAbstraction::EMOJI == script );
 
         // Find a fallback-font.
         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
 
         // If the system does not support a suitable font, fallback to Latin
+        DefaultFonts* latinDefaults = NULL;
         if( 0u == fontId )
         {
         if( 0u == fontId )
         {
-          fontId = *( defaultFontPerScriptCacheBuffer + TextAbstraction::LATIN );
+          latinDefaults = *( defaultFontPerScriptCacheBuffer + TextAbstraction::LATIN );
+          if( NULL != latinDefaults )
+          {
+            fontId = latinDefaults->FindFont( fontClient, currentPointSize );
+          }
         }
         }
+
         if( 0u == fontId )
         {
         if( 0u == fontId )
         {
-          fontId = fontClient.FindDefaultFont( UTF32_A, defaultPointSize );
+          fontId = fontClient.FindDefaultFont( UTF32_A, currentPointSize );
         }
 
         // Cache the font.
         }
 
         // Cache the font.
-        *( defaultFontPerScriptCacheBuffer + script ) = fontId;
+        if( NULL == latinDefaults )
+        {
+          latinDefaults = new DefaultFonts();
+          *( defaultFontPerScriptCacheBuffer + script ) = latinDefaults;
+        }
+        latinDefaults->mFonts.PushBack( fontId );
       }
     }
 
       }
     }
 
index 781aed5..283b021 100644 (file)
 namespace Dali
 {
 
 namespace Dali
 {
 
+namespace TextAbstraction
+{
+//Forward declaration
+class FontClient;
+}
+
 namespace Toolkit
 {
 
 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<FontId> mFonts;
+};
+
+/**
  * @brief Multi-language support implementation. @see Text::MultilanguageSupport.
  */
 class MultilanguageSupport : public BaseObject
  * @brief Multi-language support implementation. @see Text::MultilanguageSupport.
  */
 class MultilanguageSupport : public BaseObject
@@ -110,7 +147,7 @@ public:
                       Vector<FontRun>& fonts );
 
 private:
                       Vector<FontRun>& fonts );
 
 private:
-  Vector<FontId>                  mDefaultFontPerScriptCache; ///< Caches the default font for a script.
+  Vector<DefaultFonts*>           mDefaultFontPerScriptCache; ///< Caches default fonts for a script.
   Vector<ValidateFontsPerScript*> mValidFontsPerScriptCache;  ///< Caches valid fonts for a script.
 };
 
   Vector<ValidateFontsPerScript*> mValidFontsPerScriptCache;  ///< Caches valid fonts for a script.
 };