Check supported by font and find fallback font for common script. 76/191176/15
authorJoogab Yun <joogab.yun@samsung.com>
Fri, 12 Oct 2018 05:32:30 +0000 (14:32 +0900)
committerVictor Cebollada <v.cebollada@samsung.com>
Tue, 23 Oct 2018 10:25:30 +0000 (11:25 +0100)
There is an issue where '□' is displayed when you input Hangul after
inputting Tab Key.
so we need to check if it supports fonts and find fallback font.

Change-Id: Icf01d5055da7b85cc464905dde04e971f0c1f7dc

automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp [changed mode: 0644->0755]
dali-toolkit/internal/text/multi-language-support-impl.cpp [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index 94bb485..559e34e
@@ -1649,6 +1649,94 @@ int UtcDaliTextMultiLanguageValidateFonts01(void)
   Vector<FontDescriptionRun> fontDescriptions11;
   fontDescriptions11.PushBack( fontDescription1101 );
 
+  FontRun fontRun1201 =
+  {
+    {
+      0u,
+      6u
+    },
+    8u
+  };
+  FontRun fontRun1202 =
+  {
+    {
+      6u,
+      1u
+    },
+    9u
+  };
+  FontRun fontRun1203 =
+  {
+    {
+      7u,
+      5u
+    },
+    8u
+  };
+  Vector<FontRun> fontRuns12;
+  fontRuns12.PushBack( fontRun1201 );
+  fontRuns12.PushBack( fontRun1202 );
+  fontRuns12.PushBack( fontRun1203 );
+
+  FontDescriptionRun fontDescription1201 =
+  {
+    {
+      0u,
+      6u
+    },
+    const_cast<char*>( "TizenSans" ),
+    9u,
+    TextAbstraction::FontWeight::NORMAL,
+    TextAbstraction::FontWidth::NORMAL,
+    TextAbstraction::FontSlant::NORMAL,
+    0u,
+    true,
+    false,
+    false,
+    false,
+    false
+  };
+  FontDescriptionRun fontDescription1202 =
+  {
+    {
+      6u,
+      1u
+    },
+    const_cast<char*>( "TizenSans" ),
+    9u,
+    TextAbstraction::FontWeight::NORMAL,
+    TextAbstraction::FontWidth::NORMAL,
+    TextAbstraction::FontSlant::NORMAL,
+    0u,
+    true,
+    false,
+    false,
+    false,
+    false
+  };
+  FontDescriptionRun fontDescription1203 =
+  {
+    {
+      7u,
+      5u
+    },
+    const_cast<char*>( "TizenSans" ),
+    9u,
+    TextAbstraction::FontWeight::NORMAL,
+    TextAbstraction::FontWidth::NORMAL,
+    TextAbstraction::FontSlant::NORMAL,
+    0u,
+    true,
+    false,
+    false,
+    false,
+    false
+  };
+  Vector<FontDescriptionRun> fontDescriptions12;
+  fontDescriptions12.PushBack( fontDescription1201 );
+  fontDescriptions12.PushBack( fontDescription1202 );
+  fontDescriptions12.PushBack( fontDescription1203 );
+
   const ValidateFontsData data[] =
   {
     {
@@ -1761,8 +1849,18 @@ int UtcDaliTextMultiLanguageValidateFonts01(void)
       fontDescriptions11,
       fontRuns11
     },
+    {
+      "Common script.",
+      "Hello \tworld",
+      "/tizen/TizenSansRegular.ttf",
+      TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+      0u,
+      12u,
+      fontDescriptions12,
+      fontRuns12
+    },
   };
-  const unsigned int numberOfTests = 11u;
+  const unsigned int numberOfTests = 12u;
 
   for( unsigned int index = 0u; index < numberOfTests; ++index )
   {
old mode 100644 (file)
new mode 100755 (executable)
index 6ca96ad..4b6eee2
@@ -436,8 +436,6 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
   Vector<ScriptRun>::ConstIterator scriptRunEndIt = scripts.End();
   bool isNewParagraphCharacter = false;
 
-  FontId currentFontId = 0u;
-  FontId previousFontId = 0u;
   bool isPreviousEmojiScript = false;
 
   // Description of fallback font which is selected at current iteration.
@@ -465,7 +463,6 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
 
     // Get the font for the current character.
     FontId fontId = fontClient.GetFontId( currentFontDescription, currentFontPointSize );
-    currentFontId = fontId;
 
     // Get the script for the current character.
     Script script = GetScript( index,
@@ -553,133 +550,107 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
       //      supports the 'white space'. However, that font may not support the DEVANAGARI script.
       isCommonScript = TextAbstraction::IsCommonScript( character );
 
-      if( isCommonScript )
+      // Check in the valid fonts cache.
+      ValidateFontsPerScript* validateFontsPerScript = *( validFontsPerScriptCacheBuffer + script );
+
+      if( NULL != validateFontsPerScript )
       {
-        if( isValidCachedDefaultFont &&
-            ( isDefaultFont || ( currentFontId == previousFontId ) ) &&
-            !isEmojiScript )
+        // This cache stores valid fonts set by the user.
+        isValidFont = validateFontsPerScript->IsValidFont( fontId );
+
+        // It may happen that a validated font for a script doesn't have all the glyphs for that script.
+        // i.e a font validated for the CJK script may contain glyphs for the chinese language but not for the Japanese.
+        if( isValidFont )
         {
-          // At this point the character common for all scripts has no font assigned.
-          // If there is a valid previously cached default font for it, use that one.
-          fontId = cachedDefaultFontId;
+          // Checks if the current character is supported by the font is needed.
+          isValidFont = fontClient.IsCharacterSupportedByFont( fontId, character );
         }
       }
-      else
+
+      if( !isValidFont ) // (2)
       {
-        // Check in the valid fonts cache.
-        ValidateFontsPerScript* validateFontsPerScript = *( validFontsPerScriptCacheBuffer + script );
+        // The selected font is not stored in any cache.
+
+        // Checks if the current character is supported by the selected font.
+        isValidFont = fontClient.IsCharacterSupportedByFont( fontId, character );
 
-        if( NULL != validateFontsPerScript )
+        // Emojis are present in many monochrome fonts; prefer color by default.
+        if( isValidFont &&
+            isEmojiScript )
         {
-          // This cache stores valid fonts set by the user.
-          isValidFont = validateFontsPerScript->IsValidFont( fontId );
+          const GlyphIndex glyphIndex = fontClient.GetGlyphIndex( fontId, character );
 
-          // It may happen that a validated font for a script doesn't have all the glyphs for that script.
-          // i.e a font validated for the CJK script may contain glyphs for the chinese language but not for the Japanese.
-          if( isValidFont )
+          // For color emojis, the font is valid if the glyph is a color glyph (the bitmap is RGBA).
+          isValidFont = fontClient.IsColorGlyph( fontId, glyphIndex );
+        }
+
+        // If there is a valid font, cache it.
+        if( isValidFont && !isCommonScript )
+        {
+          if( NULL == validateFontsPerScript )
           {
-            // Checks if the current character is supported by the font is needed.
-            isValidFont = fontClient.IsCharacterSupportedByFont( fontId, character );
+            validateFontsPerScript = new ValidateFontsPerScript();
+
+            *( validFontsPerScriptCacheBuffer + script ) = validateFontsPerScript;
           }
+
+          validateFontsPerScript->mValidFonts.PushBack( fontId );
         }
 
-        if( !isValidFont ) // (2)
+        if( !isValidFont && ( fontId != cachedDefaultFontId ) && ( !TextAbstraction::IsNewParagraph( character ) )) // (3)
         {
-          // The selected font is not stored in any cache.
-
-          // Checks if the current character is supported by the selected font.
-          isValidFont = fontClient.IsCharacterSupportedByFont( fontId, character );
+          // The selected font by the user or the platform's default font has failed to validate the character.
 
-          // Emojis are present in many monochrome fonts; prefer color by default.
-          if( isValidFont &&
-              isEmojiScript )
+          // Checks if the previously discarted cached default font supports the character.
+          bool isValidCachedFont = false;
+          if( isValidCachedDefaultFont )
           {
-            const GlyphIndex glyphIndex = fontClient.GetGlyphIndex( fontId, character );
-
-            // For color emojis, the font is valid if the glyph is a color glyph (the bitmap is RGBA).
-            isValidFont = fontClient.IsColorGlyph( fontId, glyphIndex );
+            isValidCachedFont = fontClient.IsCharacterSupportedByFont( cachedDefaultFontId, character );
           }
 
-          // If there is a valid font, cache it.
-          if( isValidFont )
+          if( isValidCachedFont )
           {
-            if( NULL == validateFontsPerScript )
-            {
-              validateFontsPerScript = new ValidateFontsPerScript();
+            // Use the cached default font for the script if there is one.
+            fontId = cachedDefaultFontId;
+          }
+          else
+          {
+            // There is no valid cached default font for the script.
 
-              *( validFontsPerScriptCacheBuffer + script ) = validateFontsPerScript;
-            }
+            DefaultFonts* defaultFontsPerScript = NULL;
 
-            validateFontsPerScript->mValidFonts.PushBack( fontId );
-          }
+            // Emojis are present in many monochrome fonts; prefer color by default.
+            const bool preferColor = ( TextAbstraction::EMOJI == script );
 
-          if( !isValidFont && ( fontId != cachedDefaultFontId ) ) // (3)
-          {
-            // The selected font by the user or the platform's default font has failed to validate the character.
+            // Find a fallback-font.
+            fontId = fontClient.FindFallbackFont( character,
+                                                  currentFontDescription,
+                                                  currentFontPointSize,
+                                                  preferColor );
 
-            // Checks if the previously discarted cached default font supports the character.
-            bool isValidCachedFont = false;
-            if( isValidCachedDefaultFont )
+            if( 0u == fontId )
             {
-              isValidCachedFont = fontClient.IsCharacterSupportedByFont( cachedDefaultFontId, character );
+              fontId = fontClient.FindDefaultFont( UTF32_A, currentFontPointSize );
             }
 
-            if( isValidCachedFont )
-            {
-              // Use the cached default font for the script if there is one.
-              fontId = cachedDefaultFontId;
-            }
-            else
+            if ( !isCommonScript && (script != TextAbstraction::UNKNOWN) )
             {
-              // There is no valid cached default font for the script.
-
-              DefaultFonts* defaultFontsPerScript = NULL;
-
-              // Emojis are present in many monochrome fonts; prefer color by default.
-              const bool preferColor = ( TextAbstraction::EMOJI == script );
-
-              // Find a fallback-font.
-              fontId = fontClient.FindFallbackFont( character,
-                                                    currentFontDescription,
-                                                    currentFontPointSize,
-                                                    preferColor );
-
-              if( 0u == fontId )
+              // Cache the font if it is not an unknown script
+              if( NULL == defaultFontsPerScript )
               {
-                // If the system does not support a suitable font, fallback to Latin
-                defaultFontsPerScript = *( defaultFontPerScriptCacheBuffer + TextAbstraction::LATIN );
-                if( NULL != defaultFontsPerScript )
-                {
-                  fontId = defaultFontsPerScript->FindFont( fontClient,
-                                                            currentFontDescription,
-                                                            currentFontPointSize );
-                }
-              }
-
-              if( 0u == fontId )
-              {
-                fontId = fontClient.FindDefaultFont( UTF32_A, currentFontPointSize );
-              }
+                defaultFontsPerScript = *( defaultFontPerScriptCacheBuffer + script );
 
-              if ( script != TextAbstraction::UNKNOWN )
-              {
-                // Cache the font if it is not an unknown script
                 if( NULL == defaultFontsPerScript )
                 {
-                  defaultFontsPerScript = *( defaultFontPerScriptCacheBuffer + script );
-
-                  if( NULL == defaultFontsPerScript )
-                  {
-                    defaultFontsPerScript = new DefaultFonts();
-                    *( defaultFontPerScriptCacheBuffer + script ) = defaultFontsPerScript;
-                  }
+                  defaultFontsPerScript = new DefaultFonts();
+                  *( defaultFontPerScriptCacheBuffer + script ) = defaultFontsPerScript;
                 }
-                defaultFontsPerScript->Cache( currentFontDescription, fontId );
               }
+              defaultFontsPerScript->Cache( currentFontDescription, fontId );
             }
-          } // !isValidFont (3)
-        } // !isValidFont (2)
-      } // !isCommonScript
+          }
+        } // !isValidFont (3)
+      } // !isValidFont (2)
     } // !isValidFont (1)
 
 #ifdef DEBUG_ENABLED
@@ -734,7 +705,6 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
 
     // Whether the current character is a new paragraph character.
     isNewParagraphCharacter = TextAbstraction::IsNewParagraph( character );
-    previousFontId = currentFontId;
     isPreviousEmojiScript = isEmojiScript;
   } // end traverse characters.