--- /dev/null
+Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
+Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
+
+Bitstream Vera Fonts Copyright
+------------------------------
+
+Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
+a trademark of Bitstream, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of the fonts accompanying this license ("Fonts") and associated
+documentation files (the "Font Software"), to reproduce and distribute the
+Font Software, including without limitation the rights to use, copy, merge,
+publish, distribute, and/or sell copies of the Font Software, and to permit
+persons to whom the Font Software is furnished to do so, subject to the
+following conditions:
+
+The above copyright and trademark notices and this permission notice shall
+be included in all copies of one or more of the Font Software typefaces.
+
+The Font Software may be modified, altered, or added to, and in particular
+the designs of glyphs or characters in the Fonts may be modified and
+additional glyphs or characters may be added to the Fonts, only if the fonts
+are renamed to names not containing either the words "Bitstream" or the word
+"Vera".
+
+This License becomes null and void to the extent applicable to Fonts or Font
+Software that has been modified and is distributed under the "Bitstream
+Vera" names.
+
+The Font Software may be sold as part of a larger software package but no
+copy of one or more of the Font Software typefaces may be sold by itself.
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
+TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
+FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
+ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
+FONT SOFTWARE.
+
+Except as contained in this notice, the names of Gnome, the Gnome
+Foundation, and Bitstream Inc., shall not be used in advertising or
+otherwise to promote the sale, use or other dealings in this Font Software
+without prior written authorization from the Gnome Foundation or Bitstream
+Inc., respectively. For further information, contact: fonts at gnome dot
+org.
+
+Arev Fonts Copyright
+------------------------------
+
+Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the fonts accompanying this license ("Fonts") and
+associated documentation files (the "Font Software"), to reproduce
+and distribute the modifications to the Bitstream Vera Font Software,
+including without limitation the rights to use, copy, merge, publish,
+distribute, and/or sell copies of the Font Software, and to permit
+persons to whom the Font Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright and trademark notices and this permission notice
+shall be included in all copies of one or more of the Font Software
+typefaces.
+
+The Font Software may be modified, altered, or added to, and in
+particular the designs of glyphs or characters in the Fonts may be
+modified and additional glyphs or characters may be added to the
+Fonts, only if the fonts are renamed to names not containing either
+the words "Tavmjong Bah" or the word "Arev".
+
+This License becomes null and void to the extent applicable to Fonts
+or Font Software that has been modified and is distributed under the
+"Tavmjong Bah Arev" names.
+
+The Font Software may be sold as part of a larger software package but
+no copy of one or more of the Font Software typefaces may be sold by
+itself.
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
+TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
+
+Except as contained in this notice, the name of Tavmjong Bah shall not
+be used in advertising or otherwise to promote the sale, use or other
+dealings in this Font Software without prior written authorization
+from Tavmjong Bah. For further information, contact: tavmjong @ free
+. fr.
+
+$Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $
*/
#include <iostream>
-
#include <stdlib.h>
+#include <unistd.h>
+
+#include <dali/devel-api/text-abstraction/font-client.h>
#include <dali-toolkit/internal/text/character-set-conversion.h>
-#include <dali-toolkit/internal/text/segmentation.h>
-#include <dali-toolkit/internal/text/multi-language-support.h>
#include <dali-toolkit/internal/text/logical-model-impl.h>
+#include <dali-toolkit/internal/text/multi-language-helper-functions.h>
+#include <dali-toolkit/internal/text/multi-language-support.h>
+#include <dali-toolkit/internal/text/segmentation.h>
+#include <dali-toolkit/internal/text/text-run-container.h>
#include <dali-toolkit-test-suite-utils.h>
#include <dali-toolkit/dali-toolkit.h>
-
using namespace Dali;
using namespace Toolkit;
using namespace Text;
// Tests the following functions with different scripts.
+//
+// void MergeFontDescriptions( const Vector<FontDescriptionRun>& fontDescriptions,
+// Vector<FontId>& fontIds,
+// const TextAbstraction::FontDescription& defaultFontDescription,
+// TextAbstraction::PointSize26Dot6 defaultPointSize,
+// CharacterIndex startIndex,
+// Length numberOfCharacters );
+//
+// Script GetScript( Length index,
+// Vector<ScriptRun>::ConstIterator& scriptRunIt,
+// const Vector<ScriptRun>::ConstIterator& scriptRunEndIt );
+//
// Constructor, destructor and MultilanguageSupport::Get()
-// void MultilanguageSupport::SetScripts( const Vector<Character>& text, const Vector<LineBreakInfo>& lineBreakInfo, Vector<ScriptRun>& scripts );
+//
+// void MultilanguageSupport::SetScripts( const Vector<Character>& text,
+// CharacterIndex startIndex,
+// Length numberOfCharacters,
+// Vector<ScriptRun>& scripts );
+//
// void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
// const Vector<ScriptRun>& scripts,
// const Vector<FontDescriptionRun>& fontDescriptions,
// FontId defaultFontId,
+// CharacterIndex startIndex,
+// Length numberOfCharacters,
// Vector<FontRun>& fonts );
//////////////////////////////////////////////////////////
namespace
{
+const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
+const unsigned int EMOJI_FONT_SIZE = 3968u;
+const unsigned int NON_DEFAULT_FONT_SIZE = 40u;
+
+struct MergeFontDescriptionsData
+{
+ std::string description; ///< Description of the experiment.
+ Vector<FontDescriptionRun> fontDescriptionRuns; ///< The font description runs.
+ TextAbstraction::FontDescription defaultFontDescription; ///< The default font description.
+ TextAbstraction::PointSize26Dot6 defaultPointSize; ///< The default point size.
+ unsigned int startIndex; ///< The start index.
+ unsigned int numberOfCharacters; ///< The number of characters.
+ Vector<FontId> expectedFontIds; ///< The expected font ids.
+};
+
struct ScriptsData
{
- std::string description; ///< Description of the experiment.
- std::string text; ///< Input text.
- Vector<ScriptRun> scriptRuns; ///< Expected script runs.
+ std::string description; ///< Description of the experiment.
+ std::string text; ///< Input text.
+ unsigned int index; ///< The index of the first character to update the script.
+ unsigned int numberOfCharacters; ///< The numbers of characters to update the script.
+ Vector<ScriptRun> scriptRuns; ///< Expected script runs.
};
struct ValidateFontsData
{
- std::string description; ///< Description of the experiment.
- std::string text; ///< Input text.
+ std::string description; ///< Description of the experiment.
+ std::string text; ///< Input text.
+ std::string defaultFont; ///< The default font.
+ unsigned int defaultFontSize; ///< The default font size.
+ unsigned int index; ///< The index of the first character to update the script.
+ unsigned int numberOfCharacters; ///< The numbers of characters to update the script.
+ Vector<FontDescriptionRun> fontDescriptionRuns; ///< The font description runs.
+ Vector<FontRun> fontRuns; ///< The expected font runs.
};
//////////////////////////////////////////////////////////
+bool MergeFontDescriptionsTest( const MergeFontDescriptionsData& data )
+{
+ Vector<FontId> fontIds;
+ fontIds.Resize( data.startIndex + data.numberOfCharacters, 0u );
+
+ MergeFontDescriptions( data.fontDescriptionRuns,
+ fontIds,
+ data.defaultFontDescription,
+ data.defaultPointSize,
+ data.startIndex,
+ data.numberOfCharacters );
+
+ if( fontIds.Count() != data.expectedFontIds.Count() )
+ {
+ std::cout << data.description << " Different number of font ids : " << fontIds.Count() << ", expected : " << data.expectedFontIds.Count() << std::endl;
+ return false;
+ }
+
+ for( unsigned int index = 0u; index < fontIds.Count(); ++index )
+ {
+ if( fontIds[index] != data.expectedFontIds[index] )
+ {
+ std::cout << data.description << " Different font id at index : " << index << ", font id : " << fontIds[index] << ", expected : " << data.expectedFontIds[index] << std::endl;
+ std::cout << " font ids : ";
+ for( unsigned int i=0;i<fontIds.Count();++i)
+ {
+ std::cout << fontIds[i] << " ";
+ }
+ std::cout << std::endl;
+ std::cout << " expected font ids : ";
+ for( unsigned int i=0;i<data.expectedFontIds.Count();++i)
+ {
+ std::cout << data.expectedFontIds[i] << " ";
+ }
+ std::cout << std::endl;
+ return false;
+ }
+ }
+
+ return true;
+}
+
bool ScriptsTest( const ScriptsData& data )
{
MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
// 2) Set the script info.
Vector<ScriptRun> scripts;
multilanguageSupport.SetScripts( utf32,
+ 0u,
+ numberOfCharacters,
scripts );
- // 3) Compare the results.
+ if( ( 0u != data.index ) ||
+ ( numberOfCharacters != data.numberOfCharacters ) )
+ {
+ // 3) Clear the scripts.
+ ClearCharacterRuns( data.index,
+ data.index + data.numberOfCharacters - 1u,
+ scripts );
+
+ multilanguageSupport.SetScripts( utf32,
+ data.index,
+ data.numberOfCharacters,
+ scripts );
+ }
+
+ // 4) Compare the results.
tet_printf( "Testing %s\n", data.description.c_str() );
if( scripts.Count() != data.scriptRuns.Count() )
bool ValidateFontTest( const ValidateFontsData& data )
{
MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
+ TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
// 1) Convert to utf32
Vector<Character> utf32;
// 2) Set the script info.
Vector<ScriptRun> scripts;
multilanguageSupport.SetScripts( utf32,
+ 0u,
+ numberOfCharacters,
scripts );
+ char* pathNamePtr = get_current_dir_name();
+ const std::string pathName( pathNamePtr );
+ free( pathNamePtr );
+
+ // Get the default font id.
+ const FontId defaultFontId = fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + data.defaultFont,
+ data.defaultFontSize );
+
// To be completed ...
- Vector<FontDescriptionRun> fontDescriptions;
- FontId defaultFontId = 0u;
- Vector<FontRun> fonts;
+ Vector<FontRun> fontRuns;
- // 3) Validate the fonts
+ // 3) Validate the fonts.
multilanguageSupport.ValidateFonts( utf32,
scripts,
- fontDescriptions,
+ data.fontDescriptionRuns,
defaultFontId,
- fonts );
+ 0u,
+ numberOfCharacters,
+ fontRuns );
+
+ if( ( 0u != data.index ) ||
+ ( numberOfCharacters != data.numberOfCharacters ) )
+ {
+ // 4) Clear the fonts.
+ ClearCharacterRuns( data.index,
+ data.index + data.numberOfCharacters - 1u,
+ fontRuns );
+
+ multilanguageSupport.ValidateFonts( utf32,
+ scripts,
+ data.fontDescriptionRuns,
+ defaultFontId,
+ data.index,
+ data.numberOfCharacters,
+ fontRuns );
+ }
+
+ // 5) Compare the results.
+ if( data.fontRuns.Count() != fontRuns.Count() )
+ {
+ std::cout << " Different number of font runs : " << fontRuns.Count() << ", expected : " << data.fontRuns.Count() << std::endl;
+ return false;
+ }
+
+
+ for( unsigned int index = 0; index < data.fontRuns.Count(); ++index )
+ {
+ const FontRun& run = fontRuns[index];
+ const FontRun& expectedRun = data.fontRuns[index];
+
+ if( run.characterRun.characterIndex != expectedRun.characterRun.characterIndex )
+ {
+ std::cout << " character run : " << index << ", index : " << run.characterRun.characterIndex << ", expected : " << expectedRun.characterRun.characterIndex << std::endl;
+ return false;
+ }
+ if( run.characterRun.numberOfCharacters != expectedRun.characterRun.numberOfCharacters )
+ {
+ std::cout << " character run : " << index << ", num chars : " << run.characterRun.numberOfCharacters << ", expected : " << expectedRun.characterRun.numberOfCharacters << std::endl;
+ return false;
+ }
+ if( run.fontId != expectedRun.fontId )
+ {
+ std::cout << " character run : " << index << ", font : " << run.fontId << ", expected : " << expectedRun.fontId << std::endl;
+ return false;
+ }
+ }
+
return true;
}
} // namespace
+int UtcDaliTextGetScript(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextGetScript");
+
+ Script script = TextAbstraction::LATIN;
+
+ // Text with no scripts.
+ Vector<ScriptRun> scriptRuns;
+ Vector<ScriptRun>::ConstIterator scriptRunIt = scriptRuns.Begin();
+ script = GetScript( 0u,
+ scriptRunIt,
+ scriptRuns.End() );
+
+ DALI_TEST_CHECK( TextAbstraction::UNKNOWN == script );
+
+ const unsigned int numberOfCharacters = 7u;
+ // Add scripts.
+ ScriptRun scriptRun01 =
+ {
+ {
+ 0u,
+ 2u,
+ },
+ TextAbstraction::LATIN
+ };
+ ScriptRun scriptRun02 =
+ {
+ {
+ 2u,
+ 2u,
+ },
+ TextAbstraction::HEBREW
+ };
+ ScriptRun scriptRun03 =
+ {
+ {
+ 4u,
+ 2u,
+ },
+ TextAbstraction::ARABIC
+ };
+ scriptRuns.PushBack( scriptRun01 );
+ scriptRuns.PushBack( scriptRun02 );
+ scriptRuns.PushBack( scriptRun03 );
+
+ // Expected results
+ TextAbstraction::Script expectedScripts[]=
+ {
+ TextAbstraction::LATIN,
+ TextAbstraction::LATIN,
+ TextAbstraction::HEBREW,
+ TextAbstraction::HEBREW,
+ TextAbstraction::ARABIC,
+ TextAbstraction::ARABIC,
+ TextAbstraction::UNKNOWN
+ };
+
+ scriptRunIt = scriptRuns.Begin();
+ for( unsigned int index = 0u; index < numberOfCharacters; ++index )
+ {
+ script = GetScript( index,
+ scriptRunIt,
+ scriptRuns.End() );
+
+ DALI_TEST_CHECK( expectedScripts[index] == script );
+ }
+ DALI_TEST_CHECK( scriptRunIt == scriptRuns.End() );
+
+ tet_result(TET_PASS);
+ END_TEST;
+}
+
+int UtcDaliTextMergeFontDescriptions(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextMergeFontDescriptions");
+
+ // Load some fonts.
+
+ char* pathNamePtr = get_current_dir_name();
+ const std::string pathName( pathNamePtr );
+ free( pathNamePtr );
+
+ TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+ fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSans.ttf" );
+ fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSerif.ttf" );
+ fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSerif.ttf", NON_DEFAULT_FONT_SIZE );
+ fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSerif-Bold.ttf" );
+ fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSerif-Italic.ttf" );
+
+ // To test the font width as GetFontId() with the font file path can't cache the width property.
+ TextAbstraction::FontDescription widthDescription;
+ widthDescription.path = "";
+ widthDescription.family = "DejaVu Serif";
+ widthDescription.weight = TextAbstraction::FontWeight::NORMAL;
+ widthDescription.width = TextAbstraction::FontWidth::EXPANDED;
+ widthDescription.slant = TextAbstraction::FontSlant::NORMAL;
+ fontClient.GetFontId( widthDescription );
+
+ // Test.
+
+ TextAbstraction::FontDescription defaultFontDescription01;
+ Vector<FontDescriptionRun> fontDescriptionRuns01;
+ Vector<FontId> expectedFontIds01;
+
+ TextAbstraction::FontDescription defaultFontDescription02;
+ Vector<FontDescriptionRun> fontDescriptionRuns02;
+ Vector<FontId> expectedFontIds02;
+ expectedFontIds02.PushBack( 0u );
+ expectedFontIds02.PushBack( 0u );
+
+ TextAbstraction::FontDescription defaultFontDescription03;
+ defaultFontDescription03.family = "DejaVu Serif";
+ Vector<FontDescriptionRun> fontDescriptionRuns03;
+
+ FontDescriptionRun fontDescription0301 =
+ {
+ {
+ 0u,
+ 2u
+ },
+ const_cast<char*>( "DejaVu Sans" ),
+ 11u,
+ TextAbstraction::FontWeight::NORMAL,
+ TextAbstraction::FontWidth::NORMAL,
+ TextAbstraction::FontSlant::NORMAL,
+ TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+ true,
+ false,
+ false,
+ false,
+ false
+ };
+ FontDescriptionRun fontDescription0302 =
+ {
+ {
+ 2u,
+ 2u
+ },
+ NULL,
+ 0u,
+ TextAbstraction::FontWeight::NORMAL,
+ TextAbstraction::FontWidth::NORMAL,
+ TextAbstraction::FontSlant::ITALIC,
+ TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+ false,
+ false,
+ false,
+ true,
+ false
+ };
+ FontDescriptionRun fontDescription0303 =
+ {
+ {
+ 4u,
+ 2u
+ },
+ NULL,
+ 0u,
+ TextAbstraction::FontWeight::BOLD,
+ TextAbstraction::FontWidth::NORMAL,
+ TextAbstraction::FontSlant::NORMAL,
+ TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+ false,
+ true,
+ false,
+ false,
+ false
+ };
+ FontDescriptionRun fontDescription0304 =
+ {
+ {
+ 6u,
+ 2u
+ },
+ NULL,
+ 0u,
+ TextAbstraction::FontWeight::NORMAL,
+ TextAbstraction::FontWidth::NORMAL,
+ TextAbstraction::FontSlant::NORMAL,
+ NON_DEFAULT_FONT_SIZE,
+ false,
+ false,
+ false,
+ false,
+ true
+ };
+ FontDescriptionRun fontDescription0305 =
+ {
+ {
+ 8u,
+ 2u
+ },
+ NULL,
+ 0u,
+ TextAbstraction::FontWeight::NORMAL,
+ TextAbstraction::FontWidth::EXPANDED,
+ TextAbstraction::FontSlant::NORMAL,
+ TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+ false,
+ false,
+ true,
+ false,
+ false
+ };
+
+ fontDescriptionRuns03.PushBack( fontDescription0301 );
+ fontDescriptionRuns03.PushBack( fontDescription0302 );
+ fontDescriptionRuns03.PushBack( fontDescription0303 );
+ fontDescriptionRuns03.PushBack( fontDescription0304 );
+ fontDescriptionRuns03.PushBack( fontDescription0305 );
+
+ Vector<FontId> expectedFontIds03;
+ expectedFontIds03.PushBack( 1u );
+ expectedFontIds03.PushBack( 1u );
+ expectedFontIds03.PushBack( 5u );
+ expectedFontIds03.PushBack( 5u );
+ expectedFontIds03.PushBack( 4u );
+ expectedFontIds03.PushBack( 4u );
+ expectedFontIds03.PushBack( 3u );
+ expectedFontIds03.PushBack( 3u );
+ expectedFontIds03.PushBack( 6u );
+ expectedFontIds03.PushBack( 6u );
+
+ const MergeFontDescriptionsData data[] =
+ {
+ {
+ "void text.",
+ fontDescriptionRuns01,
+ defaultFontDescription01,
+ TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+ 0u,
+ 0u,
+ expectedFontIds01
+ },
+ {
+ "No description runs.",
+ fontDescriptionRuns02,
+ defaultFontDescription02,
+ TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+ 0u,
+ 2u,
+ expectedFontIds02
+ },
+ {
+ "Some description runs.",
+ fontDescriptionRuns03,
+ defaultFontDescription03,
+ TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+ 0u,
+ 10u,
+ expectedFontIds03
+ }
+ };
+ const unsigned int numberOfTests = 3u;
+
+ for( unsigned int index = 0u; index < numberOfTests; ++index )
+ {
+ if( !MergeFontDescriptionsTest( data[index] ) )
+ {
+ tet_result(TET_FAIL);
+ }
+ }
+
+ tet_result(TET_PASS);
+ END_TEST;
+}
+
int UtcDaliTextMultiLanguageConstructor(void)
{
ToolkitTestApplication application;
{
{
163u,
- 35u,
+ 18u,
+ },
+ TextAbstraction::HANGUL
+ };
+ ScriptRun scriptRun1011 =
+ {
+ {
+ 181u,
+ 17u,
},
TextAbstraction::HANGUL
};
scriptRuns10.PushBack( scriptRun1008 );
scriptRuns10.PushBack( scriptRun1009 );
scriptRuns10.PushBack( scriptRun1010 );
+ scriptRuns10.PushBack( scriptRun1011 );
// Paragraphs with no scripts mixed with paragraphs with scripts.
Vector<ScriptRun> scriptRuns11;
{
{
0u,
- 31u,
+ 3u,
},
TextAbstraction::LATIN
};
ScriptRun scriptRun1101 =
{
{
+ 3u,
+ 3u,
+ },
+ TextAbstraction::LATIN
+ };
+ ScriptRun scriptRun1102 =
+ {
+ {
+ 6u,
+ 19u,
+ },
+ TextAbstraction::LATIN
+ };
+ ScriptRun scriptRun1103 =
+ {
+ {
+ 25u,
+ 3u,
+ },
+ TextAbstraction::LATIN
+ };
+ ScriptRun scriptRun1104 =
+ {
+ {
+ 28u,
+ 3u,
+ },
+ TextAbstraction::LATIN
+ };
+ ScriptRun scriptRun1105 =
+ {
+ {
31u,
- 21u,
+ 15u,
},
TextAbstraction::HEBREW
};
+ ScriptRun scriptRun1106 =
+ {
+ {
+ 46u,
+ 2u,
+ },
+ TextAbstraction::LATIN
+ };
+ ScriptRun scriptRun1107 =
+ {
+ {
+ 48u,
+ 2u,
+ },
+ TextAbstraction::LATIN
+ };
+ ScriptRun scriptRun1108 =
+ {
+ {
+ 50u,
+ 2u,
+ },
+ TextAbstraction::LATIN
+ };
scriptRuns11.PushBack( scriptRun1100 );
scriptRuns11.PushBack( scriptRun1101 );
+ scriptRuns11.PushBack( scriptRun1102 );
+ scriptRuns11.PushBack( scriptRun1103 );
+ scriptRuns11.PushBack( scriptRun1104 );
+ scriptRuns11.PushBack( scriptRun1105 );
+ scriptRuns11.PushBack( scriptRun1106 );
+ scriptRuns11.PushBack( scriptRun1107 );
+ scriptRuns11.PushBack( scriptRun1108 );
// Paragraphs with no scripts.
Vector<ScriptRun> scriptRuns12;
{
{
0u,
- 11u,
+ 3u,
+ },
+ TextAbstraction::LATIN
+ };
+ ScriptRun scriptRun1201 =
+ {
+ {
+ 3u,
+ 3u,
+ },
+ TextAbstraction::LATIN
+ };
+ ScriptRun scriptRun1202 =
+ {
+ {
+ 6u,
+ 3u,
+ },
+ TextAbstraction::LATIN
+ };
+ ScriptRun scriptRun1203 =
+ {
+ {
+ 9u,
+ 2u,
},
TextAbstraction::LATIN
};
scriptRuns12.PushBack( scriptRun1200 );
+ scriptRuns12.PushBack( scriptRun1201 );
+ scriptRuns12.PushBack( scriptRun1202 );
+ scriptRuns12.PushBack( scriptRun1203 );
+
+ Vector<ScriptRun> scriptRuns13;
+ ScriptRun scriptRun1301 =
+ {
+ {
+ 0u,
+ 4u,
+ },
+ TextAbstraction::LATIN // An unknown script is transformed to LATIN
+ };
+ scriptRuns13.PushBack( scriptRun1301 );
const ScriptsData data[] =
{
{
"void text",
"",
+ 0u,
+ 0u,
scriptRuns00,
},
{
"Easy latin script",
"Hello world",
+ 0u,
+ 11u,
scriptRuns01,
},
{
"Mix of LTR '\\n'and RTL",
"Hello world\nمرحبا بالعالم",
+ 0u,
+ 25u,
+ scriptRuns02,
+ },
+ {
+ "Update mix of LTR '\\n'and RTL. Update LTR",
+ "Hello world\nمرحبا بالعالم",
+ 0u,
+ 12u,
+ scriptRuns02,
+ },
+ {
+ "Update mix of LTR '\\n'and RTL. Update RTL",
+ "Hello world\nمرحبا بالعالم",
+ 12u,
+ 13u,
scriptRuns02,
},
{
"Mix of RTL '\\n'and LTR",
"مرحبا بالعالم\nHello world",
+ 0u,
+ 25u,
+ scriptRuns03,
+ },
+ {
+ "Update mix of RTL '\\n'and LTR. Update RTL",
+ "مرحبا بالعالم\nHello world",
+ 0u,
+ 14u,
+ scriptRuns03,
+ },
+ {
+ "Update mix of RTL '\\n'and LTR. Update LTR",
+ "مرحبا بالعالم\nHello world",
+ 14u,
+ 11u,
scriptRuns03,
},
{
"White spaces. At the beginning of the text.",
" Hello world.",
+ 0u,
+ 16u,
scriptRuns04,
},
{
"White spaces. At the end of the text.",
"Hello world. ",
+ 0u,
+ 16u,
scriptRuns05,
},
{
"White spaces. At the middle of the text.",
"Hello world.",
+ 0u,
+ 16u,
scriptRuns06,
},
{
"White spaces between different scripts.",
" Hel 세계 ",
+ 0u,
+ 13u,
scriptRuns07,
},
{
"White spaces between different scripts and differetn directions. Starting LTR.",
" Hello world مرحبا بالعالم 안녕하세요 세계 ",
+ 0u,
+ 50u,
scriptRuns08,
},
{
"White spaces between different scripts and differetn directions. Starting RTL.",
" مرحبا بالعالم Hello world 안녕하세요 세계 مرحبا بالعالم ",
+ 0u,
+ 67u,
scriptRuns09
},
{
" مرحبا بالعالم Hello world שלום עולם \n "
" Hello world مرحبا بالعالم 안녕하세요 세계 \n "
" 안녕하세요 세계 ",
+ 0u,
+ 198u,
+ scriptRuns10
+ },
+ {
+ "Update paragraphs with different directions. Update initial paragraphs.",
+ " مرحبا بالعالم שלום עולם مرحبا بالعالم \n "
+ " Hello world 안녕하세요 세계 \n "
+ " مرحبا بالعالم Hello world שלום עולם \n "
+ " Hello world مرحبا بالعالم 안녕하세요 세계 \n "
+ " 안녕하세요 세계 ",
+ 0u,
+ 81u,
+ scriptRuns10
+ },
+ {
+ "Update paragraphs with different directions. Update middle paragraphs.",
+ " مرحبا بالعالم שלום עולם مرحبا بالعالم \n "
+ " Hello world 안녕하세요 세계 \n "
+ " مرحبا بالعالم Hello world שלום עולם \n "
+ " Hello world مرحبا بالعالم 안녕하세요 세계 \n "
+ " 안녕하세요 세계 ",
+ 49u,
+ 80u,
+ scriptRuns10
+ },
+ {
+ "Update paragraphs with different directions. Update final paragraphs.",
+ " مرحبا بالعالم שלום עולם مرحبا بالعالم \n "
+ " Hello world 안녕하세요 세계 \n "
+ " مرحبا بالعالم Hello world שלום עולם \n "
+ " Hello world مرحبا بالعالم 안녕하세요 세계 \n "
+ " 안녕하세요 세계 ",
+ 129u,
+ 69u,
scriptRuns10
},
{
"Paragraphs with no scripts mixed with paragraphs with scripts.",
" \n \n Hello world \n \n \n שלום עולם \n \n \n ",
+ 0u,
+ 52u,
scriptRuns11
},
{
"Paragraphs with no scripts.",
" \n \n \n ",
+ 0u,
+ 11u,
scriptRuns12
+ },
+ {
+ "Update paragraphs with no scripts. Update initial paragraphs.",
+ " \n \n \n ",
+ 0u,
+ 3u,
+ scriptRuns12
+ },
+ {
+ "Update paragraphs with no scripts. Update middle paragraphs.",
+ " \n \n \n ",
+ 3u,
+ 6u,
+ scriptRuns12
+ },
+ {
+ "Update paragraphs with no scripts. Update final paragraphs.",
+ " \n \n \n ",
+ 9u,
+ 2u,
+ scriptRuns12
+ },
+ {
+ "Unknown scripts.",
+ "ᚩᚯᚱᚸ", // Runic script not currentlu supported.
+ 0u,
+ 4u,
+ scriptRuns13
}
};
- const unsigned int numberOfTests = 13u;
+ const unsigned int numberOfTests = 24u;
for( unsigned int index = 0u; index < numberOfTests; ++index )
{
ToolkitTestApplication application;
tet_infoline(" UtcDaliTextMultiLanguageValidateFonts");
+ TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+
+ char* pathNamePtr = get_current_dir_name();
+ const std::string pathName( pathNamePtr );
+ free( pathNamePtr );
+
+ // 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 );
+
+ // Font id 1 --> TizenSansArabicRegular.ttf
+ // Font id 2 --> TizenSansHebrewRegular.ttf
+ // Font id 3 --> TizenColorEmoji.ttf
+ // Font id 4 --> (default)
+
+ Vector<FontRun> fontRuns01;
+ Vector<FontDescriptionRun> fontDescriptions01;
+
+ FontRun fontRun0201 =
+ {
+ {
+ 0u,
+ 11u
+ },
+ 4u
+ };
+ Vector<FontRun> fontRuns02;
+ fontRuns02.PushBack( fontRun0201 );
+
+ FontDescriptionRun fontDescription0201 =
+ {
+ {
+ 0u,
+ 11u
+ },
+ const_cast<char*>( "TizenSans" ),
+ 9u,
+ TextAbstraction::FontWeight::NORMAL,
+ TextAbstraction::FontWidth::NORMAL,
+ TextAbstraction::FontSlant::NORMAL,
+ 0u,
+ true,
+ false,
+ false,
+ false,
+ false
+ };
+ Vector<FontDescriptionRun> fontDescriptions02;
+ fontDescriptions02.PushBack( fontDescription0201 );
+
+ FontRun fontRun0301 =
+ {
+ {
+ 0u,
+ 12u
+ },
+ 4u
+ };
+ FontRun fontRun0302 =
+ {
+ {
+ 12u,
+ 12u
+ },
+ 4u
+ };
+ FontRun fontRun0303 =
+ {
+ {
+ 24u,
+ 4u
+ },
+ 4u
+ };
+ Vector<FontRun> fontRuns03;
+ fontRuns03.PushBack( fontRun0301 );
+ fontRuns03.PushBack( fontRun0302 );
+ fontRuns03.PushBack( fontRun0303 );
+
+ Vector<FontDescriptionRun> fontDescriptions03;
+
+ FontRun fontRun0701 =
+ {
+ {
+ 0u,
+ 4u
+ },
+ 2u
+ };
+ FontRun fontRun0702 =
+ {
+ {
+ 4u,
+ 1u
+ },
+ 4u
+ };
+ FontRun fontRun0703 =
+ {
+ {
+ 5u,
+ 4u
+ },
+ 2u
+ };
+ Vector<FontRun> fontRuns07;
+ fontRuns07.PushBack( fontRun0701 );
+ fontRuns07.PushBack( fontRun0702 );
+ fontRuns07.PushBack( fontRun0703 );
+
+ FontDescriptionRun fontDescription0701 =
+ {
+ {
+ 0u,
+ 4u
+ },
+ const_cast<char*>( "TizenSansHebrew" ),
+ 15u,
+ TextAbstraction::FontWeight::NORMAL,
+ TextAbstraction::FontWidth::NORMAL,
+ TextAbstraction::FontSlant::NORMAL,
+ 0u,
+ true,
+ false,
+ false,
+ false,
+ false
+ };
+ FontDescriptionRun fontDescription0702 =
+ {
+ {
+ 5u,
+ 4u
+ },
+ const_cast<char*>( "TizenSansHebrew" ),
+ 15u,
+ TextAbstraction::FontWeight::NORMAL,
+ TextAbstraction::FontWidth::NORMAL,
+ TextAbstraction::FontSlant::NORMAL,
+ 0u,
+ true,
+ false,
+ false,
+ false,
+ false
+ };
+ Vector<FontDescriptionRun> fontDescriptions07;
+ fontDescriptions07.PushBack( fontDescription0701 );
+ fontDescriptions07.PushBack( fontDescription0702 );
+
+ FontRun fontRun0801 =
+ {
+ {
+ 0u,
+ 9u
+ },
+ 2u
+ };
+ Vector<FontRun> fontRuns08;
+ fontRuns08.PushBack( fontRun0801 );
+
+ Vector<FontDescriptionRun> fontDescriptions08;
+
+ FontRun fontRun0901 =
+ {
+ {
+ 0u,
+ 4u
+ },
+ 3u
+ };
+ Vector<FontRun> fontRuns09;
+ fontRuns09.PushBack( fontRun0901 );
+
+ Vector<FontDescriptionRun> fontDescriptions09;
+ FontDescriptionRun fontDescription0901 =
+ {
+ {
+ 0u,
+ 4u
+ },
+ const_cast<char*>( "TizenColorEmoji" ),
+ 15u,
+ TextAbstraction::FontWeight::NORMAL,
+ TextAbstraction::FontWidth::NORMAL,
+ TextAbstraction::FontSlant::NORMAL,
+ EMOJI_FONT_SIZE,
+ true,
+ false,
+ false,
+ false,
+ true
+ };
+ fontDescriptions09.PushBack( fontDescription0901 );
+
const ValidateFontsData data[] =
{
{
- "void text",
+ "void text.",
"",
+ "/tizen/TizenSansRegular.ttf",
+ TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+ 0u,
+ 0u,
+ fontDescriptions01,
+ fontRuns01
},
{
- "Easy latin script",
+ "Easy latin script.",
"Hello world",
+ "/tizen/TizenSansRegular.ttf",
+ TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+ 0u,
+ 11u,
+ fontDescriptions02,
+ fontRuns02
+ },
+ {
+ "Different paragraphs.",
+ "Hello world\nhello world\ndemo",
+ "/tizen/TizenSansRegular.ttf",
+ TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+ 0u,
+ 28u,
+ fontDescriptions03,
+ fontRuns03
+ },
+ {
+ "Different paragraphs. Update the initial paragraph.",
+ "Hello world\nhello world\ndemo",
+ "/tizen/TizenSansRegular.ttf",
+ TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+ 0u,
+ 12u,
+ fontDescriptions03,
+ fontRuns03
+ },
+ {
+ "Different paragraphs. Update the middle paragraph.",
+ "Hello world\nhello world\ndemo",
+ "/tizen/TizenSansRegular.ttf",
+ TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+ 12u,
+ 12u,
+ fontDescriptions03,
+ fontRuns03
+ },
+ {
+ "Different paragraphs. Update the final paragraph.",
+ "Hello world\nhello world\ndemo",
+ "/tizen/TizenSansRegular.ttf",
+ TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+ 24u,
+ 4u,
+ fontDescriptions03,
+ fontRuns03
+ },
+ {
+ "Hebrew text. Default font: latin",
+ "שלום עולם",
+ "/tizen/TizenSansRegular.ttf",
+ TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+ 0u,
+ 9u,
+ fontDescriptions07,
+ fontRuns07
+ },
+ {
+ "Hebrew text. Default font: hebrew",
+ "שלום עולם",
+ "/tizen/TizenSansHebrewRegular.ttf",
+ TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+ 0u,
+ 9u,
+ fontDescriptions08,
+ fontRuns08
+ },
+ {
+ "Emojis",
+ "\xF0\x9F\x98\x81\xF0\x9F\x98\x82\xF0\x9F\x98\x83\xF0\x9F\x98\x84",
+ "/tizen/TizenColorEmoji.ttf",
+ EMOJI_FONT_SIZE,
+ 0u,
+ 4u,
+ fontDescriptions09,
+ fontRuns09
},
};
- const unsigned int numberOfTests = 2u;
+ const unsigned int numberOfTests = 9u;
for( unsigned int index = 0u; index < numberOfTests; ++index )
{
$(toolkit_src_dir)/text/visual-model-impl.cpp \
$(toolkit_src_dir)/text/decorator/text-decorator.cpp \
$(toolkit_src_dir)/text/layouts/layout-engine.cpp \
+ $(toolkit_src_dir)/text/multi-language-helper-functions.cpp \
$(toolkit_src_dir)/text/multi-language-support-impl.cpp \
$(toolkit_src_dir)/text/rendering/text-backend.cpp \
$(toolkit_src_dir)/text/rendering/text-renderer.cpp \
// INTERNAL INCLUDES
#include <dali-toolkit/internal/text/input-style.h>
-#include <dali-toolkit/internal/text/text-style-run-container.h>
+#include <dali-toolkit/internal/text/text-run-container.h>
namespace Dali
{
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/internal/text/multi-language-helper-functions.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/font-client.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+void MergeFontDescriptions( const Vector<FontDescriptionRun>& fontDescriptions,
+ Vector<FontId>& fontIds,
+ const TextAbstraction::FontDescription& defaultFontDescription,
+ TextAbstraction::PointSize26Dot6 defaultPointSize,
+ CharacterIndex startIndex,
+ Length numberOfCharacters )
+{
+ // Get the handle to the font client.
+ TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+
+ // Pointer to the font id buffer.
+ FontId* fontIdsBuffer = fontIds.Begin();
+
+ // Traverse all the characters.
+ for( CharacterIndex index = startIndex; index < numberOfCharacters; ++index )
+ {
+ // The default font description and font point size.
+ TextAbstraction::FontDescription fontDescription = defaultFontDescription;
+ TextAbstraction::PointSize26Dot6 fontSize = defaultPointSize;
+ bool defaultFont = true;
+
+ // Traverse all the font descriptions.
+ for( Vector<FontDescriptionRun>::ConstIterator it = fontDescriptions.Begin(),
+ endIt = fontDescriptions.End();
+ it != endIt;
+ ++it )
+ {
+ // Check whether the character's font is modified by the current font description.
+ const FontDescriptionRun& fontRun = *it;
+ if( ( index >= fontRun.characterRun.characterIndex ) &&
+ ( index < fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters ) )
+ {
+ if( fontRun.familyDefined )
+ {
+ fontDescription.family = std::string( fontRun.familyName, fontRun.familyLength );
+ defaultFont = false;
+ }
+ if( fontRun.weightDefined )
+ {
+ fontDescription.weight = fontRun.weight;
+ defaultFont = false;
+ }
+ if( fontRun.widthDefined )
+ {
+ fontDescription.width = fontRun.width;
+ defaultFont = false;
+ }
+ if( fontRun.slantDefined )
+ {
+ fontDescription.slant = fontRun.slant;
+ defaultFont = false;
+ }
+ if( fontRun.sizeDefined )
+ {
+ fontSize = fontRun.size;
+ defaultFont = false;
+ }
+ }
+ }
+
+ // Get the font id if is not the default font.
+ if( !defaultFont )
+ {
+ *( fontIdsBuffer + index - startIndex ) = fontClient.GetFontId( fontDescription, fontSize );
+ }
+ }
+}
+
+Script GetScript( Length index,
+ Vector<ScriptRun>::ConstIterator& scriptRunIt,
+ const Vector<ScriptRun>::ConstIterator& scriptRunEndIt )
+{
+ Script script = TextAbstraction::UNKNOWN;
+
+ while( scriptRunIt != scriptRunEndIt )
+ {
+ const ScriptRun& scriptRun = *scriptRunIt;
+
+ if( index >= scriptRun.characterRun.characterIndex + scriptRun.characterRun.numberOfCharacters )
+ {
+ ++scriptRunIt;
+ }
+ else if( index >= scriptRun.characterRun.characterIndex )
+ {
+ script = scriptRun.script;
+
+ if( index + 1u == scriptRun.characterRun.characterIndex + scriptRun.characterRun.numberOfCharacters )
+ {
+ // All the characters of the current run have been traversed. Get the next one for the next iteration.
+ ++scriptRunIt;
+ }
+
+ break;
+ }
+ }
+
+ return script;
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_MULTI_LANGUAGE_HELPER_FUNCTIONS_H__
+#define __DALI_TOOLKIT_TEXT_MULTI_LANGUAGE_HELPER_FUNCTIONS_H__
+
+/*
+ * Copyright (c) 2016 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/font-description-run.h>
+#include <dali-toolkit/internal/text/script-run.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief Merges the font descriptions to retrieve the font Id for each character.
+ *
+ * @param[in] fontDescriptions The font descriptions.
+ * @param[out] fontIds The font id for each character.
+ * @param[in] defaultFontDescription The default font description.
+ * @param[in] defaultPointSize The default font size.
+ * @param[in] startIndex The character from where the fonts are merged.
+ * @param[in] numberOfCharacters The number of characters to set the font.
+ */
+void MergeFontDescriptions( const Vector<FontDescriptionRun>& fontDescriptions,
+ Vector<FontId>& fontIds,
+ const TextAbstraction::FontDescription& defaultFontDescription,
+ TextAbstraction::PointSize26Dot6 defaultPointSize,
+ CharacterIndex startIndex,
+ Length numberOfCharacters );
+
+/**
+ * @brief Retrieves the script Id from the script run for a given character's @p index.
+ *
+ * If the character's index exceeds the current script run it increases the iterator to get the next one.
+ *
+ * @param[in] index The character's index.
+ * @param[in,out] scriptRunIt Iterator to the current script run.
+ * @param[in] scriptRunEndIt Iterator to one after the last script run.
+ *
+ * @return The script.
+ */
+Script GetScript( Length index,
+ Vector<ScriptRun>::ConstIterator& scriptRunIt,
+ const Vector<ScriptRun>::ConstIterator& scriptRunEndIt );
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_MULTI_LANGUAGE_HELPER_FUNCTIONS_H__
#include <dali/devel-api/adaptor-framework/singleton-service.h>
#include <dali/devel-api/text-abstraction/font-client.h>
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/multi-language-helper-functions.h>
+
namespace Dali
{
namespace Internal
{
-/**
- * @brief Merges the font descriptions to retrieve the font Id for each character.
- *
- * @param[in] fontDescriptions The font descriptions.
- * @param[out] fontIds The font id for each character.
- * @param[in] defaultFontDescription The default font description.
- * @param[in] defaultPointSize The default font size.
- */
-void MergeFontDescriptions( const Vector<FontDescriptionRun>& fontDescriptions,
- Vector<FontId>& fontIds,
- const TextAbstraction::FontDescription& defaultFontDescription,
- TextAbstraction::PointSize26Dot6 defaultPointSize )
-{
- // Get the handle to the font client.
- TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
-
- // Pointer to the font id buffer.
- FontId* fontIdsBuffer = fontIds.Begin();
-
- // Traverse all the characters.
- const Length numberOfCharacters = fontIds.Count();
- for( CharacterIndex index = 0u; index < numberOfCharacters; ++index )
- {
- // The default font description and font point size.
- TextAbstraction::FontDescription fontDescription = defaultFontDescription;
- TextAbstraction::PointSize26Dot6 fontSize = defaultPointSize;
- bool defaultFont = true;
-
- // Traverse all the font descriptions.
- for( Vector<FontDescriptionRun>::ConstIterator it = fontDescriptions.Begin(),
- endIt = fontDescriptions.End();
- it != endIt;
- ++it )
- {
- // Check whether the character's font is modified by the current font description.
- const FontDescriptionRun& fontRun = *it;
- if( ( index >= fontRun.characterRun.characterIndex ) &&
- ( index < fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters ) )
- {
- if( fontRun.familyDefined )
- {
- fontDescription.family = std::string( fontRun.familyName, fontRun.familyLength );
- defaultFont = false;
- }
- if( fontRun.weightDefined )
- {
- fontDescription.weight = fontRun.weight;
- defaultFont = false;
- }
- if( fontRun.widthDefined )
- {
- fontDescription.width = fontRun.width;
- defaultFont = false;
- }
- if( fontRun.slantDefined )
- {
- fontDescription.slant = fontRun.slant;
- defaultFont = false;
- }
- if( fontRun.sizeDefined )
- {
- fontSize = fontRun.size;
- defaultFont = false;
- }
- }
- }
-
- // Get the font id if is not the default font.
- if( !defaultFont )
- {
- *( fontIdsBuffer + index ) = fontClient.GetFontId( fontDescription, fontSize );
- }
- }
-}
-
-/**
- * @brief Retrieves the script Id from the script run for a given character's @p index.
- *
- * If the character's index exceeds the current script run it increases the iterator to get the next one.
- *
- * @param[in] index The character's index.
- * @param[in,out] scriptRunIt Iterator to the current font run.
- * @param[in] scriptRunEndIt Iterator to one after the last script run.
- *
- * @return The script.
- */
-Script GetScript( Length index,
- Vector<ScriptRun>::ConstIterator& scriptRunIt,
- const Vector<ScriptRun>::ConstIterator& scriptRunEndIt )
-{
- Script script = TextAbstraction::UNKNOWN;
-
- if( scriptRunIt != scriptRunEndIt )
- {
- const ScriptRun& scriptRun = *scriptRunIt;
-
- if( ( index >= scriptRun.characterRun.characterIndex ) &&
- ( index < scriptRun.characterRun.characterIndex + scriptRun.characterRun.numberOfCharacters ) )
- {
- script = scriptRun.script;
- }
-
- if( index + 1u == scriptRun.characterRun.characterIndex + scriptRun.characterRun.numberOfCharacters )
- {
- // All the characters of the current run have been traversed. Get the next one for the next iteration.
- ++scriptRunIt;
- }
- }
-
- return script;
-}
-
bool ValidateFontsPerScript::FindValidFont( FontId fontId ) const
{
for( Vector<FontId>::ConstIterator it = mValidFonts.Begin(),
}
void MultilanguageSupport::SetScripts( const Vector<Character>& text,
+ CharacterIndex startIndex,
+ Length numberOfCharacters,
Vector<ScriptRun>& scripts )
{
- const Length numberOfCharacters = text.Count();
-
if( 0u == numberOfCharacters )
{
// Nothing to do if there are no characters.
return;
}
+ // Find the first index where to insert the script.
+ ScriptRunIndex scriptIndex = 0u;
+ if( 0u != startIndex )
+ {
+ for( Vector<ScriptRun>::ConstIterator it = scripts.Begin(),
+ endIt = scripts.End();
+ it != endIt;
+ ++it, ++scriptIndex )
+ {
+ const ScriptRun& run = *it;
+ if( startIndex < run.characterRun.characterIndex + run.characterRun.numberOfCharacters )
+ {
+ // Run found.
+ break;
+ }
+ }
+ }
+
// Stores the current script run.
ScriptRun currentScriptRun;
- currentScriptRun.characterRun.characterIndex = 0u;
+ currentScriptRun.characterRun.characterIndex = startIndex;
currentScriptRun.characterRun.numberOfCharacters = 0u;
currentScriptRun.script = TextAbstraction::UNKNOWN;
// Reserve some space to reduce the number of reallocations.
- scripts.Reserve( numberOfCharacters << 2u );
+ scripts.Reserve( text.Count() << 2u );
// Whether the first valid script needs to be set.
bool isFirstScriptToBeSet = true;
const Character* const textBuffer = text.Begin();
// Traverse all characters and set the scripts.
- for( Length index = 0u; index < numberOfCharacters; ++index )
+ const Length lastCharacter = startIndex + numberOfCharacters;
+ for( Length index = startIndex; index < lastCharacter; ++index )
{
Character character = *( textBuffer + index );
// script of the first character of the paragraph with a defined script.
// Skip those characters valid for many scripts like white spaces or '\n'.
- bool endOfText = index == numberOfCharacters;
+ bool endOfText = index == lastCharacter;
while( !endOfText &&
( TextAbstraction::COMMON == script ) )
{
// the same direction than the first script of the paragraph.
isFirstScriptToBeSet = true;
- // Characters common to all scripts at the end of the paragraph are added to the last script (if the last one is not unknown).
- if( TextAbstraction::UNKNOWN != currentScriptRun.script )
+ // Characters common to all scripts at the end of the paragraph are added to the last script.
+ currentScriptRun.characterRun.numberOfCharacters += numberOfAllScriptCharacters;
+
+ // Store the script run.
+ if( TextAbstraction::UNKNOWN == currentScriptRun.script )
{
- currentScriptRun.characterRun.numberOfCharacters += numberOfAllScriptCharacters;
- numberOfAllScriptCharacters = 0u;
+ currentScriptRun.script = TextAbstraction::LATIN;
}
- }
+ scripts.Insert( scripts.Begin() + scriptIndex, currentScriptRun );
+ ++scriptIndex;
+
+ // Initialize the new one.
+ currentScriptRun.characterRun.characterIndex = currentScriptRun.characterRun.characterIndex + currentScriptRun.characterRun.numberOfCharacters;
+ currentScriptRun.characterRun.numberOfCharacters = 0u;
+ currentScriptRun.script = TextAbstraction::UNKNOWN;
+ numberOfAllScriptCharacters = 0u;
+ }
// Get the next character.
++index;
- endOfText = index == numberOfCharacters;
+ endOfText = index == lastCharacter;
if( !endOfText )
{
character = *( textBuffer + index );
if( 0u != currentScriptRun.characterRun.numberOfCharacters )
{
// Store the script run.
- scripts.PushBack( currentScriptRun );
+ scripts.Insert( scripts.Begin() + scriptIndex, currentScriptRun );
+ ++scriptIndex;
}
// Initialize the new one.
// Add remaining characters into the last script.
currentScriptRun.characterRun.numberOfCharacters += numberOfAllScriptCharacters;
- DALI_ASSERT_DEBUG( ( 0u != currentScriptRun.characterRun.numberOfCharacters ) && "MultilanguageSupport::SetScripts() Trying to insert a script run with zero characters." );
-
- if( TextAbstraction::UNKNOWN == currentScriptRun.script )
+ if( 0u != currentScriptRun.characterRun.numberOfCharacters )
{
- // There are only white spaces in the last script. Set the latin script.
- currentScriptRun.script = TextAbstraction::LATIN;
+ 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;
}
- // Store the last run.
- scripts.PushBack( currentScriptRun );
+ if( scriptIndex < scripts.Count() )
+ {
+ // Update the indices of the next script runs.
+ const ScriptRun& run = *( scripts.Begin() + scriptIndex - 1u );
+ CharacterIndex nextCharacterIndex = run.characterRun.characterIndex + run.characterRun.numberOfCharacters;
+
+ for( Vector<ScriptRun>::Iterator it = scripts.Begin() + scriptIndex,
+ endIt = scripts.End();
+ it != endIt;
+ ++it )
+ {
+ ScriptRun& run = *it;
+ run.characterRun.characterIndex = nextCharacterIndex;
+ nextCharacterIndex += run.characterRun.numberOfCharacters;
+ }
+ }
}
void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
const Vector<ScriptRun>& scripts,
const Vector<FontDescriptionRun>& fontDescriptions,
FontId defaultFontId,
+ CharacterIndex startIndex,
+ Length numberOfCharacters,
Vector<FontRun>& fonts )
{
- // Clear any previously validated font.
- fonts.Clear();
-
DALI_LOG_INFO( gLogFilter, Debug::General, "-->MultilanguageSupport::ValidateFonts\n" );
- const Length numberOfCharacters = text.Count();
if( 0u == numberOfCharacters )
{
return;
}
+ // Find the first index where to insert the font run.
+ FontRunIndex fontIndex = 0u;
+ if( 0u != startIndex )
+ {
+ for( Vector<FontRun>::ConstIterator it = fonts.Begin(),
+ endIt = fonts.End();
+ it != endIt;
+ ++it, ++fontIndex )
+ {
+ const FontRun& run = *it;
+ if( startIndex < run.characterRun.characterIndex + run.characterRun.numberOfCharacters )
+ {
+ // Run found.
+ break;
+ }
+ }
+ }
+
// Traverse the characters and validate/set the fonts.
// Get the caches.
// Initializes a validated font run.
FontRun currentFontRun;
- currentFontRun.characterRun.characterIndex = 0u;
+ currentFontRun.characterRun.characterIndex = startIndex;
currentFontRun.characterRun.numberOfCharacters = 0u;
currentFontRun.fontId = 0u;
MergeFontDescriptions( fontDescriptions,
fontIds,
defaultFontDescription,
- defaultPointSize );
+ defaultPointSize,
+ startIndex,
+ numberOfCharacters );
const Character* const textBuffer = text.Begin();
const FontId* const fontIdsBuffer = fontIds.Begin();
Vector<ScriptRun>::ConstIterator scriptRunIt = scripts.Begin();
Vector<ScriptRun>::ConstIterator scriptRunEndIt = scripts.End();
+ bool isNewParagraphCharacter = false;
- for( Length index = 0u; index < numberOfCharacters; ++index )
+ CharacterIndex lastCharacter = startIndex + numberOfCharacters;
+ for( Length index = startIndex; index < lastCharacter; ++index )
{
// Get the character.
const Character character = *( textBuffer + index );
// Get the font for the character.
- FontId fontId = *( fontIdsBuffer + index );
+ FontId fontId = *( fontIdsBuffer + index - startIndex );
// Get the script for the character.
Script script = GetScript( index,
}
#endif
- if( TextAbstraction::UNKNOWN == script )
- {
- DALI_LOG_WARNING( "MultilanguageSupport::ValidateFonts. Unknown script!" );
- script = TextAbstraction::LATIN;
- }
-
// Whether the font being validated is a default one not set by the user.
FontId preferredFont = fontId;
#endif
// The font is now validated.
-
- if( fontId != currentFontRun.fontId )
+ if( ( fontId != currentFontRun.fontId ) ||
+ isNewParagraphCharacter )
{
// Current run needs to be stored and a new one initialized.
if( 0u != currentFontRun.characterRun.numberOfCharacters )
{
// Store the font run.
- fonts.PushBack( currentFontRun );
+ fonts.Insert( fonts.Begin() + fontIndex, currentFontRun );
+ ++fontIndex;
}
// Initialize the new one.
// Add one more character to the run.
++currentFontRun.characterRun.numberOfCharacters;
+
+ // Whether the current character is a new paragraph character.
+ isNewParagraphCharacter = TextAbstraction::IsNewParagraph( character );
}
if( 0u != currentFontRun.characterRun.numberOfCharacters )
{
// Store the last run.
- fonts.PushBack( currentFontRun );
+ fonts.Insert( fonts.Begin() + fontIndex, currentFontRun );
+ ++fontIndex;
+ }
+
+ if( fontIndex < fonts.Count() )
+ {
+ // Update the indices of the next font runs.
+ const FontRun& run = *( fonts.Begin() + fontIndex - 1u );
+ CharacterIndex nextCharacterIndex = run.characterRun.characterIndex + run.characterRun.numberOfCharacters;
+
+ for( Vector<FontRun>::Iterator it = fonts.Begin() + fontIndex,
+ endIt = fonts.End();
+ it != endIt;
+ ++it )
+ {
+ FontRun& run = *it;
+
+ run.characterRun.characterIndex = nextCharacterIndex;
+ nextCharacterIndex += run.characterRun.numberOfCharacters;
+ }
}
+
DALI_LOG_INFO( gLogFilter, Debug::General, "<--MultilanguageSupport::ValidateFonts\n" );
}
* @copydoc Dali::MultilanguageSupport::SetScripts()
*/
void SetScripts( const Vector<Character>& text,
+ CharacterIndex startIndex,
+ Length numberOfCharacters,
Vector<ScriptRun>& scripts );
/**
const Vector<ScriptRun>& scripts,
const Vector<FontDescriptionRun>& fontDescriptions,
FontId defaultFontId,
+ CharacterIndex startIndex,
+ Length numberOfCharacters,
Vector<FontRun>& fonts );
private:
}
void MultilanguageSupport::SetScripts( const Vector<Character>& text,
+ CharacterIndex startIndex,
+ Length numberOfCharacters,
Vector<ScriptRun>& scripts )
{
GetImplementation( *this ).SetScripts( text,
+ startIndex,
+ numberOfCharacters,
scripts );
}
const Vector<ScriptRun>& scripts,
const Vector<FontDescriptionRun>& fontDescriptions,
FontId defaultFontId,
+ CharacterIndex startIndex,
+ Length numberOfCharacters,
Vector<FontRun>& fonts )
{
GetImplementation( *this ).ValidateFonts( text,
scripts,
fontDescriptions,
defaultFontId,
+ startIndex,
+ numberOfCharacters,
fonts );
}
* script of the first character of the paragraph with a defined script.
*
* @param[in] text Vector of UTF-32 characters.
+ * @param[in] startIndex The character from where the script info is set.
+ * @param[in] numberOfCharacters The number of characters to set the script.
* @param[out] scripts Vector containing the script runs for the whole text.
*/
void SetScripts( const Vector<Character>& text,
+ CharacterIndex startIndex,
+ Length numberOfCharacters,
Vector<ScriptRun>& scripts );
/**
* @param[in] scripts Vector containing the script runs for the whole text.
* @param[in] fontDescriptions The fonts set by the application developers.
* @param[in] defaultFontId The default font's id.
+ * @param[in] startIndex The character from where the font info is set.
+ * @param[in] numberOfCharacters The number of characters to set the font.
* @param[out] fonts The validated fonts.
*/
void ValidateFonts( const Vector<Character>& text,
const Vector<ScriptRun>& scripts,
const Vector<FontDescriptionRun>& fontDescriptions,
FontId defaultFontId,
+ CharacterIndex startIndex,
+ Length numberOfCharacters,
Vector<FontRun>& fonts );
};
{
// Retrieves the scripts used in the text.
multilanguageSupport.SetScripts( utf32Characters,
+ startIndex,
+ requestedNumberOfCharacters,
scripts );
}
scripts,
fontDescriptionRuns,
defaultFontId,
+ startIndex,
+ requestedNumberOfCharacters,
validFonts );
}
}
{
/**
+ * @brief Clears the runs starting from the given character index.
+ *
+ * @param[in] startIndex The starting character index used to remove runs.
+ * @param[in] endIndex The ending character index used to remove runs.
+ * @param[in,out] runs The text's runs.
+ * @param[out] startRemoveIndex The index to the first run to be removed.
+ * @param[out] endRemoveIndex The index to the last run to be removed.
+ */
+template< typename T >
+void ClearCharacterRuns( CharacterIndex startIndex,
+ CharacterIndex endIndex,
+ Vector<T>& runs,
+ uint32_t& startRemoveIndex,
+ uint32_t& endRemoveIndex )
+{
+ T* runsBuffer = runs.Begin();
+
+ const Length length = runs.Count();
+ for( Length index = 0u; index < length; ++index )
+ {
+ T* run = ( runsBuffer + index );
+
+ if( ( run->characterRun.characterIndex <= endIndex ) &&
+ ( startIndex < run->characterRun.characterIndex + run->characterRun.numberOfCharacters ) )
+ {
+ // Run found.
+
+ // Set the index to the first run to be removed.
+ startRemoveIndex = index;
+ break;
+ }
+ }
+
+ for( Length index = startRemoveIndex; index < length; ++index )
+ {
+ T* run = ( runsBuffer + index );
+
+ if( ( run->characterRun.characterIndex <= endIndex ) &&
+ ( startIndex < run->characterRun.characterIndex + run->characterRun.numberOfCharacters ) )
+ {
+ // Update the index to the last run to be removed.
+ endRemoveIndex = index + 1u;
+ }
+ else
+ {
+ // Run found. Nothing else to do.
+ break;
+ }
+ }
+
+ // The number of characters to remove.
+ const Length numberOfCharactersRemoved = 1u + endIndex - startIndex;
+
+ // Update the character index of the next runs.
+ for( Length index = 0u; index < length; ++index )
+ {
+ T* run = ( runsBuffer + index );
+
+ if( run->characterRun.characterIndex > startIndex )
+ {
+ run->characterRun.characterIndex -= numberOfCharactersRemoved;
+ }
+ }
+}
+
+/**
+ * @brief Clears the runs starting from the given character index.
+ *
+ * @param[in] startIndex The starting character index used to remove runs.
+ * @param[in] endIndex The ending character index used to remove runs.
+ * @param[in,out] runs The text's runs.
+ */
+template< typename T >
+void ClearCharacterRuns( CharacterIndex startIndex,
+ CharacterIndex endIndex,
+ Vector<T>& runs )
+{
+ uint32_t startRemoveIndex = runs.Count();
+ uint32_t endRemoveIndex = startRemoveIndex;
+ ClearCharacterRuns( startIndex,
+ endIndex,
+ runs,
+ startRemoveIndex,
+ endRemoveIndex );
+
+ // Remove all remaining runs.
+ T* runBuffer = runs.Begin();
+ runs.Erase( runBuffer + startRemoveIndex, runBuffer + endRemoveIndex );
+}
+
+/**
* @brief Updates the number of characters and the character index of the text's style runs.
*
* If the @p numberOfCharacters is a negative value, it means the number of characters that are removed starting from the @p index.