X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Fmulti-language-support-impl.cpp;h=7570e041d5b154e821dd37e221cd3fcf0680c1c6;hb=3eed10ef4379cfd9f8af38c1d0fc8cc084ffe80d;hp=ae9a68b6793e1c3cb7eb987182cf72befeaf355f;hpb=1de507cb9f77667b67b269abfe25769205c9817e;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/text/multi-language-support-impl.cpp b/dali-toolkit/internal/text/multi-language-support-impl.cpp index ae9a68b..7570e04 100644 --- a/dali-toolkit/internal/text/multi-language-support-impl.cpp +++ b/dali-toolkit/internal/text/multi-language-support-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -101,11 +101,11 @@ MultilanguageSupport::MultilanguageSupport() { // 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, NULL ); + mDefaultFontPerScriptCache.Resize( TextAbstraction::UNKNOWN + 1, 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. - mValidFontsPerScriptCache.Resize( TextAbstraction::UNKNOWN, NULL ); + mValidFontsPerScriptCache.Resize( TextAbstraction::UNKNOWN + 1, NULL ); } MultilanguageSupport::~MultilanguageSupport() @@ -254,10 +254,6 @@ void MultilanguageSupport::SetScripts( const Vector& text, currentScriptRun.characterRun.numberOfCharacters += numberOfAllScriptCharacters; // Store the script run. - if( TextAbstraction::UNKNOWN == currentScriptRun.script ) - { - currentScriptRun.script = TextAbstraction::LATIN; - } scripts.Insert( scripts.Begin() + scriptIndex, currentScriptRun ); ++scriptIndex; @@ -320,7 +316,6 @@ void MultilanguageSupport::SetScripts( const Vector& text, else if( ( TextAbstraction::UNKNOWN == currentScriptRun.script ) && ( TextAbstraction::EMOJI == script ) ) { - currentScriptRun.script = TextAbstraction::LATIN; currentScriptRun.characterRun.numberOfCharacters += numberOfAllScriptCharacters; numberOfAllScriptCharacters = 0u; } @@ -357,12 +352,6 @@ void MultilanguageSupport::SetScripts( const Vector& text, if( 0u != currentScriptRun.characterRun.numberOfCharacters ) { - if( TextAbstraction::UNKNOWN == currentScriptRun.script ) - { - // There are only white spaces in the last script. Set the latin script. - currentScriptRun.script = TextAbstraction::LATIN; - } - // Store the last run. scripts.Insert( scripts.Begin() + scriptIndex, currentScriptRun ); ++scriptIndex; @@ -451,10 +440,6 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, FontId previousFontId = 0u; bool isPreviousEmojiScript = false; - // Whether it's the first set of characters to be validated. - // Used in case the paragraph starts with characters common to all scripts. - bool isFirstSetToBeValidated = true; - CharacterIndex lastCharacter = startIndex + numberOfCharacters; for( Length index = startIndex; index < lastCharacter; ++index ) { @@ -477,9 +462,9 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, currentFontId = fontId; // Get the script for the current character. - const Script script = GetScript( index, - scriptRunIt, - scriptRunEndIt ); + Script script = GetScript( index, + scriptRunIt, + scriptRunEndIt ); #ifdef DEBUG_ENABLED { @@ -500,10 +485,11 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, // Check first in the cache of default fonts per script and size. - DefaultFonts* defaultFonts = *( defaultFontPerScriptCacheBuffer + script ); FontId cachedDefaultFontId = 0u; + DefaultFonts* defaultFonts = *( defaultFontPerScriptCacheBuffer + script ); if( NULL != defaultFonts ) { + // This cache stores fall-back fonts. cachedDefaultFontId = defaultFonts->FindFont( fontClient, currentFontDescription, currentFontPointSize ); @@ -515,6 +501,12 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, // The font is valid if it matches with the default one for the current script and size and it's different than zero. isValidFont = isValidCachedDefaultFont && ( fontId == cachedDefaultFontId ); + if( isValidFont ) + { + // Check if the font supports the character. + isValidFont = fontClient.IsCharacterSupportedByFont( fontId, character ); + } + bool isCommonScript = false; bool isEmojiScript = TextAbstraction::EMOJI == script; @@ -533,7 +525,6 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, currentFontRun.fontId = fontId; } - // If the given font is not valid, it means either: // - there is no cached font for the current script yet or, // - the user has set a different font than the default one for the current script or, @@ -565,7 +556,6 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, // 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; - isValidFont = true; } } else @@ -575,25 +565,33 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, if( NULL != validateFontsPerScript ) { + // 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 ) + { + // Checks if the current character is supported by the font is needed. + isValidFont = fontClient.IsCharacterSupportedByFont( fontId, character ); + } } if( !isValidFont ) // (2) { - // Use the font client to validate the font. - const GlyphIndex glyphIndex = fontClient.GetGlyphIndex( fontId, character ); + // The selected font is not stored in any cache. - // The font is valid if there is a glyph for that character. - isValidFont = 0u != glyphIndex; + // Checks if the current character is supported by the selected font. + isValidFont = fontClient.IsCharacterSupportedByFont( fontId, character ); // Emojis are present in many monochrome fonts; prefer color by default. if( isValidFont && isEmojiScript ) { - const PixelData bitmap = fontClient.CreateBitmap( fontId, glyphIndex ); + const GlyphIndex glyphIndex = fontClient.GetGlyphIndex( fontId, character ); - // For color emojis, the font is valid if the bitmap is RGBA. - isValidFont = bitmap && ( Pixel::BGRA8888 == bitmap.GetPixelFormat() ); + // 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. @@ -609,12 +607,19 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, validateFontsPerScript->mValidFonts.PushBack( fontId ); } - if( !isValidFont ) // (3) + if( !isValidFont && ( fontId != cachedDefaultFontId ) ) // (3) { - // The given font has not been validated. + // The selected font by the user or the platform's default font has failed to validate the character. + // Checks if the previously discarted cached default font supports the character. + bool isValidCachedFont = false; if( isValidCachedDefaultFont ) { + isValidCachedFont = fontClient.IsCharacterSupportedByFont( cachedDefaultFontId, character ); + } + + if( isValidCachedFont ) + { // Use the cached default font for the script if there is one. fontId = cachedDefaultFontId; } @@ -650,18 +655,21 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, fontId = fontClient.FindDefaultFont( UTF32_A, currentFontPointSize ); } - // Cache the font. - if( NULL == defaultFontsPerScript ) + if ( script != TextAbstraction::UNKNOWN ) { - defaultFontsPerScript = *( defaultFontPerScriptCacheBuffer + script ); - + // Cache the font if it is not an unknown script if( NULL == defaultFontsPerScript ) { - defaultFontsPerScript = new DefaultFonts(); - *( defaultFontPerScriptCacheBuffer + script ) = defaultFontsPerScript; + defaultFontsPerScript = *( defaultFontPerScriptCacheBuffer + script ); + + if( NULL == defaultFontsPerScript ) + { + defaultFontsPerScript = new DefaultFonts(); + *( defaultFontPerScriptCacheBuffer + script ) = defaultFontsPerScript; + } } + defaultFontsPerScript->Cache( currentFontDescription, fontId ); } - defaultFontsPerScript->Cache( currentFontDescription, fontId ); } } // !isValidFont (3) } // !isValidFont (2) @@ -681,12 +689,6 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, } #endif - if( isFirstSetToBeValidated && !isCommonScript ) - { - currentFontRun.fontId = fontId; - isFirstSetToBeValidated = false; - } - // The font is now validated. if( ( fontId != currentFontRun.fontId ) || isNewParagraphCharacter ) @@ -704,11 +706,6 @@ void MultilanguageSupport::ValidateFonts( const Vector& text, currentFontRun.characterRun.characterIndex = currentFontRun.characterRun.characterIndex + currentFontRun.characterRun.numberOfCharacters; currentFontRun.characterRun.numberOfCharacters = 0u; currentFontRun.fontId = fontId; - - if( isNewParagraphCharacter ) - { - isFirstSetToBeValidated = true; - } } // Add one more character to the run.