[dali_1.0.10] Merge branch 'tizen' 77/28077/1
authorLee Morgan <Lee.morgan@partner.samsung.com>
Thu, 25 Sep 2014 15:02:26 +0000 (16:02 +0100)
committerLee Morgan <Lee.morgan@partner.samsung.com>
Thu, 25 Sep 2014 15:07:20 +0000 (16:07 +0100)
Signed-off-by: Lee Morgan <Lee.morgan@partner.samsung.com>
Change-Id: I955f6ebf6bb45334f197536029d2dd8471c02369
Signed-off-by: Lee Morgan <Lee.morgan@partner.samsung.com>
75 files changed:
automated-tests/src/dali-toolkit-internal/CMakeLists.txt
automated-tests/src/dali-toolkit-internal/utc-Dali-TextView-Processor-Types.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-TextView-Processor.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-TextView-Relayout-Utilities.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-TextView.cpp
automated-tests/src/dali-toolkit-unmanaged/CMakeLists.txt
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-abstraction.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp [deleted file]
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.h [deleted file]
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard-event-notifier.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard-event-notifier.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-test-application.h
automated-tests/src/dali-toolkit/utc-Dali-ControlImpl.cpp
base/dali-toolkit/internal/builder/builder-impl.cpp
base/dali-toolkit/internal/controls/buttons/button-impl.cpp
base/dali-toolkit/internal/controls/buttons/button-impl.h
base/dali-toolkit/internal/controls/buttons/push-button-impl.cpp
base/dali-toolkit/internal/controls/buttons/push-button-impl.h
base/dali-toolkit/internal/controls/text-input/text-input-impl.cpp
base/dali-toolkit/internal/controls/text-input/text-input-impl.h
base/dali-toolkit/internal/controls/text-view/relayout-utilities.cpp
base/dali-toolkit/internal/controls/text-view/relayout-utilities.h
base/dali-toolkit/internal/controls/text-view/split-by-char-policies.cpp
base/dali-toolkit/internal/controls/text-view/split-by-new-line-char-policies.cpp
base/dali-toolkit/internal/controls/text-view/split-by-word-policies.cpp
base/dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.cpp [new file with mode: 0644]
base/dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.h [new file with mode: 0644]
base/dali-toolkit/internal/controls/text-view/text-processor.cpp
base/dali-toolkit/internal/controls/text-view/text-processor.h
base/dali-toolkit/internal/controls/text-view/text-view-character-processor.cpp
base/dali-toolkit/internal/controls/text-view/text-view-impl.cpp
base/dali-toolkit/internal/controls/text-view/text-view-impl.h
base/dali-toolkit/internal/controls/text-view/text-view-paragraph-processor.cpp
base/dali-toolkit/internal/controls/text-view/text-view-paragraph-processor.h
base/dali-toolkit/internal/controls/text-view/text-view-processor-dbg.cpp
base/dali-toolkit/internal/controls/text-view/text-view-processor-dbg.h
base/dali-toolkit/internal/controls/text-view/text-view-processor-helper-functions.cpp
base/dali-toolkit/internal/controls/text-view/text-view-processor-helper-functions.h
base/dali-toolkit/internal/controls/text-view/text-view-processor-types.h
base/dali-toolkit/internal/controls/text-view/text-view-processor.cpp
base/dali-toolkit/internal/controls/text-view/text-view-word-processor.cpp
base/dali-toolkit/internal/controls/text-view/text-view-word-processor.h
base/dali-toolkit/internal/factory/localized-control-factory-impl.cpp [deleted file]
base/dali-toolkit/internal/factory/localized-control-factory-impl.h [deleted file]
base/dali-toolkit/internal/file.list
base/dali-toolkit/internal/styling/style-manager-impl.cpp
base/dali-toolkit/public-api/controls/control-impl.cpp
base/dali-toolkit/public-api/controls/control.h
base/dali-toolkit/public-api/factory/localized-control-factory.cpp [deleted file]
base/dali-toolkit/public-api/factory/localized-control-factory.h [deleted file]
base/dali-toolkit/public-api/file.list
build/tizen/dali-toolkit/Makefile.am
docs/content/images/texture-atlas/atlas-size.jpg [new file with mode: 0644]
docs/content/images/texture-atlas/atlas.jpg [new file with mode: 0644]
docs/content/images/texture-atlas/compression-example.jpg [new file with mode: 0644]
docs/content/images/texture-atlas/compression-options.jpg [new file with mode: 0644]
docs/content/images/texture-atlas/example-code.jpg [new file with mode: 0644]
docs/content/images/texture-atlas/image-wall.jpg [new file with mode: 0644]
docs/content/images/texture-atlas/texture-packer-add-sprites.jpg [new file with mode: 0644]
docs/content/images/texture-atlas/texture-packer-preferences.jpg [new file with mode: 0644]
docs/content/images/texture-atlas/texture-packer-publish.jpg [new file with mode: 0644]
docs/content/images/texture-atlas/texture-packer-startup.jpg [new file with mode: 0644]
docs/content/main-page.h
docs/content/programming-guide/performance-profiling.h
docs/content/programming-guide/performance-tips.h [new file with mode: 0644]
docs/content/programming-guide/texture-atlases.h [new file with mode: 0644]
docs/content/programming-guide/texture-compression.h [new file with mode: 0644]
optional/dali-toolkit/dali-toolkit.h
optional/dali-toolkit/internal/controls/cluster/cluster-style-impl.cpp
optional/dali-toolkit/internal/controls/magnifier/magnifier-impl.cpp
optional/dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec
texture-atlas-exporter/dali-exporter/dali3d_exporter.cpp [new file with mode: 0755]
texture-atlas-exporter/dali-exporter/exporter.xml [new file with mode: 0755]

index ff683d5..78b995d 100644 (file)
@@ -18,7 +18,6 @@ SET(TC_SOURCES
 # Append list of test harness files (Won't get parsed for test cases)
 LIST(APPEND TC_SOURCES
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-accessibility-manager.cpp
-   ../dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-application.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-imf-manager.cpp
index 7cb03fe..44e25c0 100644 (file)
@@ -67,12 +67,11 @@ int UtcDaliTextViewDefaultConstructorDestructor_PT(void)
   DALI_TEST_EQUALS( characterLayoutInfo.mUnderlineThickness, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
   DALI_TEST_EQUALS( characterLayoutInfo.mUnderlinePosition, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
   DALI_TEST_CHECK( !characterLayoutInfo.mGlyphActor );
-  DALI_TEST_CHECK( characterLayoutInfo.mStyledText.mText.IsEmpty() );
   DALI_TEST_EQUALS( characterLayoutInfo.mColorAlpha, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
   DALI_TEST_CHECK( NULL == characterLayoutInfo.mGradientInfo );
   DALI_TEST_CHECK( characterLayoutInfo.mIsVisible );
-  DALI_TEST_CHECK( characterLayoutInfo.mSetText );
-  DALI_TEST_CHECK( characterLayoutInfo.mSetStyle );
+  DALI_TEST_CHECK( !characterLayoutInfo.mSetText );
+  DALI_TEST_CHECK( !characterLayoutInfo.mSetStyle );
 
   TextViewProcessor::WordLayoutInfo wordLayoutInfo;
   DALI_TEST_EQUALS( wordLayoutInfo.mSize, Vector2::ZERO, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
@@ -116,7 +115,6 @@ int UtcDaliTextViewCopyConstructorOperator(void)
   characterLayoutInfo.mUnderlinePosition = 1.f;
 
   characterLayoutInfo.mGlyphActor = TextActor::New( "Hello" );
-  characterLayoutInfo.mStyledText.mText = Text( "Hello" );
 
   TextViewProcessor::GradientInfo* info = new TextViewProcessor::GradientInfo();
   info->mGradientColor = Vector4( 1.f, 1.f, 1.f, 1.f );
@@ -141,7 +139,6 @@ int UtcDaliTextViewCopyConstructorOperator(void)
   DALI_TEST_EQUALS( characterLayoutInfo1.mUnderlineThickness, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
   DALI_TEST_EQUALS( characterLayoutInfo1.mUnderlinePosition, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
   DALI_TEST_CHECK( characterLayoutInfo1.mGlyphActor );
-  DALI_TEST_EQUALS( characterLayoutInfo1.mStyledText.mText.GetLength(), 5u, TEST_LOCATION );
   DALI_TEST_EQUALS( characterLayoutInfo1.mColorAlpha, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
   DALI_TEST_EQUALS( characterLayoutInfo1.mGradientInfo->mGradientColor, Vector4( 1.f, 1.f, 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
   DALI_TEST_EQUALS( characterLayoutInfo1.mGradientInfo->mStartPoint, Vector2( 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
@@ -159,7 +156,6 @@ int UtcDaliTextViewCopyConstructorOperator(void)
   DALI_TEST_EQUALS( characterLayoutInfo2.mUnderlineThickness, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
   DALI_TEST_EQUALS( characterLayoutInfo2.mUnderlinePosition, 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
   DALI_TEST_CHECK( characterLayoutInfo2.mGlyphActor );
-  DALI_TEST_EQUALS( characterLayoutInfo2.mStyledText.mText.GetLength(), 5u, TEST_LOCATION );
   DALI_TEST_EQUALS( characterLayoutInfo2.mColorAlpha, 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
   DALI_TEST_EQUALS( characterLayoutInfo2.mGradientInfo->mGradientColor, Vector4( 1.f, 1.f, 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
   DALI_TEST_EQUALS( characterLayoutInfo2.mGradientInfo->mStartPoint, Vector2( 1.f, 1.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
index 2fb823f..8fef857 100644 (file)
@@ -22,6 +22,7 @@
 
 // Internal headers are allowed here
 #include <dali-toolkit/internal/controls/text-view/text-processor.h>
+#include <dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.h>
 
 using namespace Dali;
 using namespace Dali::Toolkit;
@@ -53,11 +54,10 @@ struct BeginsRightToLeftCharacterTest
 
 bool TestBeginsRightToLeftCharacter( const std::string& description, const std::string& input, const bool result, const char* location )
 {
-  // Creates a styled text with the markup or plain string.
-  MarkupProcessor::StyledTextArray styledText;
-  MarkupProcessor::GetStyledTextArray( input, styledText, true );
+  // Creates a text with the string.
+  Text text( input );
 
-  const bool ret = ( result == TextProcessor::BeginsRightToLeftCharacter( styledText ) );
+  const bool ret = ( result == TextProcessor::BeginsRightToLeftCharacter( text ) );
 
   if( !ret )
   {
@@ -79,11 +79,10 @@ struct ContainsRightToLeftCharacterTest
 
 bool TestContainsRightToLeftCharacter( const std::string& description, const std::string& input, const bool result, const char* location )
 {
-  // Creates a styled text with the markup or plain string.
-  MarkupProcessor::StyledTextArray styledText;
-  MarkupProcessor::GetStyledTextArray( input, styledText, true );
+  // Creates a text with the string.
+  Text text( input );
 
-  const bool ret = ( result == TextProcessor::ContainsRightToLeftCharacter( styledText ) );
+  const bool ret = ( result == TextProcessor::ContainsRightToLeftCharacter( text ) );
 
   if( !ret )
   {
@@ -141,10 +140,12 @@ bool TestSplitInParagraphs( const SplitInParagraphsTest& test, const char* locat
   MarkupProcessor::StyledTextArray styledText;
   MarkupProcessor::GetStyledTextArray( test.inputText, styledText, true );
 
-  std::vector<MarkupProcessor::StyledTextArray> paragraphs;
+  std::vector<Text> paragraphs;
+  std::vector< Vector<TextStyle*> > styles;
 
   TextProcessor::SplitInParagraphs( styledText,
-                                    paragraphs );
+                                    paragraphs,
+                                    styles );
 
   if( paragraphs.size() != test.resultNumberOfParagraphs )
   {
@@ -163,24 +164,23 @@ struct SplitInWordsTest
 {
   std::string inputText;
 
-  std::size_t resultNumberOfWords;
+  std::size_t resultNumberOfSeparators;
 };
 
 bool TestSplitInWords( const SplitInWordsTest& test, const char* location )
 {
-  // Creates a styled text with the markup or plain string.
-  MarkupProcessor::StyledTextArray styledText;
-  MarkupProcessor::GetStyledTextArray( test.inputText, styledText, true );
+  // Creates a text with the string.
+  Text text( test.inputText );
 
-  std::vector<MarkupProcessor::StyledTextArray> words;
+  Vector<std::size_t> positions;
 
-  TextProcessor::SplitInWords( styledText,
-                               words );
+  TextProcessor::SplitInWords( text,
+                               positions );
 
-  if( words.size() != test.resultNumberOfWords )
+  if( positions.Count() != test.resultNumberOfSeparators )
   {
     tet_printf( "Fail. %s", location );
-    tet_printf( "Different number of words, result %d, expected result %d", words.size(), test.resultNumberOfWords );
+    tet_printf( "Different number of separators, result %d, expected result %d", positions.Count(), test.resultNumberOfSeparators );
 
     return false;
   }
@@ -236,10 +236,14 @@ int UtcDaliTextViewSplitInWords(void)
   {
     {
       std::string( "Hello world, hello word!" ),
-      7
+      3u
     },
+    {
+      std::string( "Hello world\n" ),
+      2u
+    }
   };
-  const std::size_t numberOfTests( 1 );
+  const std::size_t numberOfTests( 2u );
 
   for( std::size_t index = 0; index < numberOfTests; ++index )
   {
index 255c96a..c556e08 100644 (file)
@@ -88,6 +88,7 @@ bool TestCalculateLineLayout( const CalculateLineLayoutTest& test,  const char*
 
   // Creaqte indices.
   TextViewProcessor::TextInfoIndices indices( 0u, test.wordIndex, test.characterIndex );
+  indices.mCharacterParagraphIndex = test.characterParagraphIndex;
 
   // Get the input paragraph.
   TextViewProcessor::ParagraphLayoutInfo inputParagraphLayout;
index ee43cbd..dc2a363 100644 (file)
@@ -66,6 +66,7 @@ struct SplitParagraphTest
   std::string input;
   std::size_t wordIndex;
   std::size_t characterIndex;
+  std::size_t characterParagraphIndex;
   float       lineHeightOffset;
   std::string firstResult;
   std::string lastResult;
@@ -141,10 +142,6 @@ void Print( const TextViewProcessor::CharacterLayoutInfo& character )
   {
     std::cout << "[" << textActor.GetText() << "]";
   }
-  else
-  {
-    std::cout << "{" << character.mStyledText.mText.GetText() << "}";
-  }
 }
 
 void Print( const TextViewProcessor::WordLayoutInfo& word )
@@ -186,21 +183,13 @@ void Print( const TextViewProcessor::TextLayoutInfo& text )
   std::cout << "||" << std::endl;
 }
 
-std::string GetText( const TextViewProcessor::CharacterLayoutInfo& character )
-{
-  return character.mStyledText.mText.GetText();
-}
-
-std::string GetText( const TextViewProcessor::WordLayoutInfo& word )
+std::string GetText( const TextViewProcessor::WordLayoutInfo& word, const Text& paragraphText )
 {
-  std::string text;
+  Text text;
 
-  for( TextViewProcessor::CharacterLayoutInfoContainer::const_iterator it = word.mCharactersLayoutInfo.begin(), endIt = word.mCharactersLayoutInfo.end(); it != endIt; ++it )
-  {
-    text += GetText( *it );
-  }
+  paragraphText.GetSubText( word.mFirstCharacter, word.mFirstCharacter + word.mCharactersLayoutInfo.size() - 1u, text );
 
-  return text;
+  return text.GetText();
 }
 
 std::string GetText( const TextViewProcessor::ParagraphLayoutInfo& paragraph )
@@ -209,7 +198,7 @@ std::string GetText( const TextViewProcessor::ParagraphLayoutInfo& paragraph )
 
   for( TextViewProcessor::WordLayoutInfoContainer::const_iterator it = paragraph.mWordsLayoutInfo.begin(), endIt = paragraph.mWordsLayoutInfo.end(); it != endIt; ++it )
   {
-    text += GetText( *it );
+    text += GetText( *it, paragraph.mText );
   }
 
   return text;
@@ -288,27 +277,6 @@ bool TestEqual( const TextViewProcessor::CharacterLayoutInfo& character1,
     return false;
   }
 
-  text1 = character1.mStyledText.mText.GetText();
-  style1 = character1.mStyledText.mStyle;
-
-  text2 = character2.mStyledText.mText.GetText();
-  style2 = character2.mStyledText.mStyle;
-
-  if( text1 != text2 )
-  {
-    return false;
-  }
-
-  if( style1 != style2 )
-  {
-    std::cout << "  style1 : " << std::endl;
-    TextViewProcessor::dbgPrint( style1 );
-
-    std::cout << "  style2 : " << std::endl;
-    TextViewProcessor::dbgPrint( style2 );
-    return false;
-  }
-
   return true;
 }
 
@@ -557,6 +525,7 @@ bool TestSplitWord( const std::string& description, const std::string& input, co
  * @param input The input word.
  * @param wordIndex Index to the word within the paragraph where to split it.
  * @param characterIndex Where to split the word.
+ * @param characterIndex Character index within the paragraph.
  * @param lineHeightOffset Offset between lines.
  * @param firstResult First part of the split paragraph.
  * @param lastResult Last part of the split paragraph.
@@ -568,6 +537,7 @@ bool TestSplitParagraph( const std::string& description,
                          const std::string& input,
                          size_t wordIndex,
                          size_t characterIndex,
+                         size_t characterParagraphIndex,
                          float lineHeightOffset,
                          const std::string& firstResult,
                          const std::string& lastResult,
@@ -589,7 +559,6 @@ bool TestSplitParagraph( const std::string& description,
                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
                                                                                     Toolkit::TextView::Center,
                                                                                     PointSize( lineHeightOffset ),
-                                                                                    std::string( "..." ),
                                                                                     true ),
                                      relayoutData );
 
@@ -616,7 +585,6 @@ bool TestSplitParagraph( const std::string& description,
                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
                                                                                     Toolkit::TextView::Center,
                                                                                     PointSize( lineHeightOffset ),
-                                                                                    std::string( "..." ),
                                                                                     true ),
                                      firstRelayoutData );
 
@@ -643,7 +611,6 @@ bool TestSplitParagraph( const std::string& description,
                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
                                                                                     Toolkit::TextView::Center,
                                                                                     PointSize( lineHeightOffset ),
-                                                                                    std::string( "..."),
                                                                                     true ),
                                      lastRelayoutData );
 
@@ -660,6 +627,7 @@ bool TestSplitParagraph( const std::string& description,
   TextViewProcessor::ParagraphLayoutInfo lastParagraphLayoutInfo;
 
   TextViewProcessor::TextInfoIndices indices( 0, wordIndex, characterIndex );
+  indices.mCharacterParagraphIndex = characterParagraphIndex;
 
   SplitParagraph( indices,
                   PointSize( lineHeightOffset ),
@@ -812,7 +780,6 @@ bool TestMergeParagraphs( const std::string& description, const std::string& inp
                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
                                                                                     Toolkit::TextView::Center,
                                                                                     PointSize( lineHeightOffset ),
-                                                                                    std::string( "..." ),
                                                                                     true ),
                                      firstRelayoutData );
 
@@ -838,7 +805,6 @@ bool TestMergeParagraphs( const std::string& description, const std::string& inp
                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
                                                                                     Toolkit::TextView::Center,
                                                                                     PointSize( lineHeightOffset ),
-                                                                                    std::string( "..." ),
                                                                                     true ),
                                      lastRelayoutData );
 
@@ -864,7 +830,6 @@ bool TestMergeParagraphs( const std::string& description, const std::string& inp
                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
                                                                                     Toolkit::TextView::Center,
                                                                                     PointSize( lineHeightOffset ),
-                                                                                    std::string( "..." ),
                                                                                     true ),
                                      resultRelayoutData );
 
@@ -998,7 +963,6 @@ bool TestRemoveWordsFromParagraph( const std::string& description, const std::st
                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
                                                                                     Toolkit::TextView::Center,
                                                                                     PointSize( lineHeightOffset ),
-                                                                                    std::string( "..." ),
                                                                                     true ),
                                      relayoutData );
 
@@ -1024,7 +988,6 @@ bool TestRemoveWordsFromParagraph( const std::string& description, const std::st
                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
                                                                                     Toolkit::TextView::Center,
                                                                                     PointSize( lineHeightOffset ),
-                                                                                    std::string( "..." ),
                                                                                     true ),
                                      resultRelayoutData );
 
@@ -1099,7 +1062,6 @@ bool TestUpdateTextInfo( const std::string& description,
                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
                                                                                     Toolkit::TextView::Center,
                                                                                     PointSize( lineHeightOffset ),
-                                                                                    std::string( "..." ),
                                                                                     true ),
                                      relayoutData );
 
@@ -1117,7 +1079,6 @@ bool TestUpdateTextInfo( const std::string& description,
                                                                                     static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
                                                                                     Toolkit::TextView::Center,
                                                                                     PointSize( lineHeightOffset ),
-                                                                                    std::string( "..." ),
                                                                                     true ),
                                      resultRelayoutData );
 
@@ -1128,7 +1089,6 @@ bool TestUpdateTextInfo( const std::string& description,
                                                                         static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
                                                                         Toolkit::TextView::Center,
                                                                         PointSize( lineHeightOffset ),
-                                                                        std::string( "..." ),
                                                                         true );
 
   switch( operation )
@@ -1254,15 +1214,6 @@ int UtcDaliTextViewCreateTextInfo(void)
   layoutInfo12.mBearing = BEARING_12;
   layoutInfo12.mAscender = ASCENDER_12;
 
-  TextStyle style10;
-  style10.SetFontName( "" );
-  style10.SetFontPointSize( PointSize( 10.f ) );
-  TextStyle style12;
-  style12.SetFontName( "" );
-
-  layoutInfo12.mStyledText.mStyle = style12;
-  layoutInfo10.mStyledText.mStyle = style10;
-
   // Words
 
   TextViewProcessor::WordLayoutInfo wordLayout1, wordLayout2, wordLayout3, wordLayout4;
@@ -1272,46 +1223,33 @@ int UtcDaliTextViewCreateTextInfo(void)
   wordLayout1.mAscender = ASCENDER_12;
   wordLayout1.mType = TextViewProcessor::NoSeparator;
 
-  layoutInfo12.mStyledText.mText = Text( "H" );
   wordLayout1.mCharactersLayoutInfo.push_back( layoutInfo12 ); // H
-  layoutInfo12.mStyledText.mText = Text( "e" );
   wordLayout1.mCharactersLayoutInfo.push_back( layoutInfo12 ); // e
-  layoutInfo12.mStyledText.mText = Text( "l" );
   wordLayout1.mCharactersLayoutInfo.push_back( layoutInfo12 ); // l
-  layoutInfo10.mStyledText.mText = Text( "l" );
   wordLayout1.mCharactersLayoutInfo.push_back( layoutInfo10 ); // l
-  layoutInfo10.mStyledText.mText = Text( "o" );
   wordLayout1.mCharactersLayoutInfo.push_back( layoutInfo10 ); // o
 
   // (white space)
   wordLayout2.mSize = Size( ADVANCE_10, HEIGHT_10 );
   wordLayout2.mAscender = ASCENDER_10;
   wordLayout2.mType = TextViewProcessor::WordSeparator;
-  layoutInfo10.mStyledText.mText = Text( " " );
   wordLayout2.mCharactersLayoutInfo.push_back( layoutInfo10 ); // (white space)
 
   // world!
   wordLayout3.mSize = Size( 2.f * ADVANCE_10 + 4.f * ADVANCE_12, HEIGHT_12 );
   wordLayout3.mAscender = ASCENDER_12;
   wordLayout3.mType = TextViewProcessor::NoSeparator;
-  layoutInfo10.mStyledText.mText = Text( "w" );
   wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo10 ); // w
-  layoutInfo10.mStyledText.mText = Text( "o" );
   wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo10 ); // o
-  layoutInfo12.mStyledText.mText = Text( "r" );
   wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo12 ); // r
-  layoutInfo12.mStyledText.mText = Text( "l" );
   wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo12 ); // l
-  layoutInfo12.mStyledText.mText = Text( "d" );
   wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo12 ); // d
-  layoutInfo12.mStyledText.mText = Text( "!" );
   wordLayout3.mCharactersLayoutInfo.push_back( layoutInfo12 ); // !
 
   // (new paragraph character)
   wordLayout4.mSize = Size( 0.f, HEIGHT_12 );
   wordLayout4.mAscender = ASCENDER_12;
   wordLayout4.mType = TextViewProcessor::ParagraphSeparator;
-  layoutInfo12.mStyledText.mText = Text( "\n" );
   layoutInfo12.mSize.width = 0.f;
   wordLayout4.mCharactersLayoutInfo.push_back( layoutInfo12 ); // (new paragraph char)
 
@@ -1533,7 +1471,6 @@ int UtcDaliTextViewUpdateTextInfo(void)
       std::string( "Hello <font size='30'>w</font>orl<font size='10'>dhello</font> world" )
     },
     // * Remove RTL text within LTR
-    /* TODO check this when RTL text is working
     {
       std::string( "Remove within the same paragraph, RTL text within LTR." ),
       Remove,
@@ -1544,7 +1481,6 @@ int UtcDaliTextViewUpdateTextInfo(void)
       0.f,
       std::string( "Hello worlello world" )
     },
-    */
     // * Remove whole paragraph
     {
       std::string( "Remove whole paragraph" ),
@@ -1668,7 +1604,7 @@ int UtcDaliTextViewUpdateTextInfo(void)
       std::string( "Touch <b>me\nhello\n</b>world" )
     },
   };
-  const std::size_t numberOfTests( 21u );
+  const std::size_t numberOfTests( 22u );
 
   for( std::size_t index = 0u; index < numberOfTests; ++index )
   {
@@ -1697,6 +1633,7 @@ int UtcDaliTextViewSplitParagraph(void)
       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
       0,
       0,
+      0,
       3.f,
       std::string( "" ),
       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
@@ -1706,6 +1643,7 @@ int UtcDaliTextViewSplitParagraph(void)
       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
       10,
       4,
+      36,
       0.f,
       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
       std::string( "" ),
@@ -1715,16 +1653,17 @@ int UtcDaliTextViewSplitParagraph(void)
       std::string("<font size='10'>Hello </font>wor<font size='12'>ld, hello wo</font>rld"),
       2,
       4,
+      10,
       0.f,
       std::string("<font size='10'>Hello </font>wor<font size='12'>l</font>"),
       std::string("<font size='12'>d, hello wo</font>rld")
-    }
-    /* TODO RTL
+    },
     {
       std::string( "Split paragraph, wordPosition 6, position 0." ),
       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
       6,
       0,
+      21,
       0.f,
       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום " ),
       std::string( "עולם text text" ),
@@ -1734,6 +1673,7 @@ int UtcDaliTextViewSplitParagraph(void)
       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
       4,
       0,
+      17,
       0.f,
       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> " ),
       std::string( "שלום עולם text text" ),
@@ -1743,13 +1683,13 @@ int UtcDaliTextViewSplitParagraph(void)
       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם text text" ),
       8,
       0,
+      27,
       6.f,
       std::string( "<font size='10'>He<font size='12'>ll</font>oooo wooorld</font> שלום עולם " ),
       std::string( "text text" ),
     },
-    */
   };
-  const std::size_t numberOfTests( 3u );
+  const std::size_t numberOfTests( 6u );
 
   for( std::size_t index = 0u; index < numberOfTests; ++index )
   {
@@ -1759,6 +1699,7 @@ int UtcDaliTextViewSplitParagraph(void)
                              test.input,
                              test.wordIndex,
                              test.characterIndex,
+                             test.characterParagraphIndex,
                              test.lineHeightOffset,
                              test.firstResult,
                              test.lastResult,
@@ -1969,7 +1910,6 @@ int UtcDaliTextViewMergeParagraph01(void)
       0.f,
       std::string( "Hello world, this is a whole paragraph" )
     },
-    /* TODO RTL
     {
       std::string( "Merge paragraphs: last starting with RTL text and first ending with RTL" ),
       std::string( "Hello world, שלום" ),
@@ -1984,7 +1924,6 @@ int UtcDaliTextViewMergeParagraph01(void)
       3.f,
       std::string( "Hello world, שלום עולם, hello world." )
     },
-    */
     {
       std::string( "Merge paragraphs. Don't merge words" ),
       std::string( "Hello world," ),
@@ -2000,7 +1939,7 @@ int UtcDaliTextViewMergeParagraph01(void)
       std::string( "Hello world, this is a whole paragraph" )
     },
   };
-  const std::size_t numberOfTests( 4u );
+  const std::size_t numberOfTests( 6u );
 
   for( std::size_t index = 0u; index < numberOfTests; ++index )
   {
index 13c2d32..a4ad16f 100644 (file)
@@ -55,7 +55,6 @@ SET(TC_SOURCES
 # Append list of test harness files (Won't get parsed for test cases)
 LIST(APPEND TC_SOURCES
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-accessibility-manager.cpp
-   ../dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-application.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-imf-manager.cpp
index 52f8353..afe9242 100644 (file)
@@ -37,7 +37,6 @@ SET(TC_SOURCES
 # Append list of test harness files (Won't get parsed for test cases)
 LIST(APPEND TC_SOURCES
    dali-toolkit-test-utils/toolkit-accessibility-manager.cpp
-   dali-toolkit-test-utils/toolkit-adaptor.cpp
    dali-toolkit-test-utils/toolkit-application.cpp
    dali-toolkit-test-utils/toolkit-clipboard.cpp
    dali-toolkit-test-utils/toolkit-imf-manager.cpp
index 47a5b3a..b094fde 100644 (file)
@@ -729,6 +729,10 @@ public:
 
   inline void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
   {
+    mScissorParams.x = x;
+    mScissorParams.y = y;
+    mScissorParams.width = width;
+    mScissorParams.height = height;
   }
 
   inline void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length)
@@ -1643,6 +1647,18 @@ public: // TEST FUNCTIONS
     ATTRIB_TYPE_LAST
   };
 
+  struct ScissorParams
+  {
+    GLint x;
+    GLint y;
+    GLsizei width;
+    GLsizei height;
+
+    ScissorParams() : x( 0 ), y( 0 ), width( 0 ), height( 0 ) { }
+  };
+
+  // Methods to check scissor tests
+  inline const ScissorParams& GetScissorParams() const { return mScissorParams; }
 
 private:
   GLuint     mCurrentProgram;
@@ -1820,6 +1836,8 @@ private:
     mVertexAttribArrayState[ index ] = state;
     mVertexAttribArrayChanged = true;
   }
+
+  ScissorParams mScissorParams;
 };
 
 template <>
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp
deleted file mode 100644 (file)
index 17bd210..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 2014 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.
- *
- */
-
-#define __DALI_ADAPTOR_H__
-#define __DALI_ACCESSIBILITY_MANAGER_H__
-#define __DALI_TIMER_H__
-#define __DALI_CLIPBOARD_H__
-#define __DALI_IMF_MANAGER_H__
-
-#include "toolkit-adaptor.h"
-#include <map>
-#include <dali/public-api/common/dali-common.h>
-#include <dali/public-api/signals/dali-signal-v2.h>
-
-namespace Dali
-{
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-class TestRenderSurface : public RenderSurface
-{
-public:
-  TestRenderSurface(){}
-  virtual ~TestRenderSurface(){}
-  virtual SurfaceType GetType() { return RenderSurface::WINDOW; }
-  virtual Dali::Any GetSurface() { return Dali::Any(); }
-  virtual Dali::Any GetDisplay() { return Dali::Any(); }
-  virtual PositionSize GetPositionSize() const { return PositionSize(0, 0, 640, 480);}
-};
-
-typedef Dali::Rect<int> PositionSize;
-
-/**
- * Stub for the Adaptor
- */
-class Adaptor
-{
-public:
-
-  typedef SignalV2< void ( Adaptor& ) > AdaptorSignalV2;
-
-public:
-
-  Adaptor(ToolkitAdaptor& toolkitAdaptor);
-  ~Adaptor();
-
-public:
-
-  void Start();
-  void Pause();
-  void Resume();
-  void Stop();
-  bool AddIdle(boost::function<void(void)> callBack);
-  void FeedEvent(TouchPoint& point, int timeStamp);
-  bool MoveResize(const PositionSize& positionSize);
-  void SurfaceResized(const PositionSize& positionSize);
-  void ReplaceSurface(RenderSurface& surface);
-  void RenderSync();
-  RenderSurface& GetSurface();
-
-public: // static methods
-  static Adaptor& Get();
-  static bool IsAvailable();
-
-public:  // Signals
-
-  AdaptorSignalV2& SignalResize();
-
-  void EmitSignalResize()
-  {
-    mResizeSignal.Emit( *this );
-  }
-
-private:
-
-  // Undefined
-  Adaptor(const Adaptor&);
-  Adaptor& operator=(Adaptor&);
-
-  AdaptorSignalV2 mResizeSignal;
-  TestRenderSurface mRenderSurface;
-  ToolkitAdaptor& mToolkitAdaptor;
-};
-
-namespace
-{
-Adaptor* gAdaptor = NULL;
-
-}
-
-Adaptor::Adaptor(ToolkitAdaptor& toolkitAdaptor)
-: mToolkitAdaptor(toolkitAdaptor)
-{
-}
-
-Adaptor::~Adaptor()
-{
-
-}
-
-void Adaptor::Start()
-{
-  mToolkitAdaptor.mFunctionsCalled.Start = true;
-}
-
-void Adaptor::Pause()
-{
-  mToolkitAdaptor.mFunctionsCalled.Pause = true;
-}
-
-void Adaptor::Resume()
-{
-  mToolkitAdaptor.mFunctionsCalled.Resume = true;
-}
-
-void Adaptor::Stop()
-{
-  mToolkitAdaptor.mFunctionsCalled.Stop = true;
-}
-
-bool Adaptor::AddIdle(boost::function<void(void)> callBack)
-{
-  mToolkitAdaptor.mFunctionsCalled.AddIdle = true;
-  mToolkitAdaptor.mLastIdleAdded = callBack;
-  return true;
-}
-
-void Adaptor::FeedEvent(TouchPoint& point, int timeStamp)
-{
-  mToolkitAdaptor.mFunctionsCalled.FeedEvent = true;
-  mToolkitAdaptor.mLastTouchPointFed = point;
-  mToolkitAdaptor.mLastTimeStampFed = timeStamp;
-}
-
-bool Adaptor::MoveResize(const PositionSize& positionSize)
-{
-  mToolkitAdaptor.mFunctionsCalled.MoveResize = true;
-  mToolkitAdaptor.mLastSizeSet = positionSize;
-  return true;
-}
-
-void Adaptor::SurfaceResized(const PositionSize& positionSize)
-{
-  mToolkitAdaptor.mFunctionsCalled.SurfaceResized = true;
-  mToolkitAdaptor.mLastSizeSet = positionSize;
-}
-
-void Adaptor::ReplaceSurface(RenderSurface& surface)
-{
-  mToolkitAdaptor.mFunctionsCalled.ReplaceSurface = true;
-}
-
-void Adaptor::RenderSync()
-{
-  mToolkitAdaptor.mFunctionsCalled.RenderSync = true;
-}
-
-RenderSurface& Adaptor::GetSurface()
-{
-  mToolkitAdaptor.mFunctionsCalled.GetSurface = true;
-  return mRenderSurface;
-}
-
-Adaptor& Adaptor::Get()
-{
-  DALI_ASSERT_ALWAYS(gAdaptor);
-  gAdaptor->mToolkitAdaptor.mFunctionsCalled.Get = true;
-  return *gAdaptor;
-}
-
-bool Adaptor::IsAvailable()
-{
-  bool available(false);
-
-  if (gAdaptor)
-  {
-    gAdaptor->mToolkitAdaptor.mFunctionsCalled.IsAvailable = true;
-    available = true;
-  }
-
-  return available;
-}
-
-Adaptor::AdaptorSignalV2& Adaptor::SignalResize()
-{
-  mToolkitAdaptor.mFunctionsCalled.SignalResize = true;
-  return mResizeSignal;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-ToolkitAdaptor::ToolkitAdaptor()
-: mLastTouchPointFed(0, TouchPoint::Down, 0.0f, 0.0f),
-  mLastTimeStampFed(0),
-  mStyleMonitor(StyleMonitor::Get()),
-  mAccessibilityManager(AccessibilityManager::Get()),
-  mImfManager(ImfManager::Get()),
-  mAdaptorStub(new Adaptor(*this))
-{
-  gAdaptor = mAdaptorStub;
-}
-
-ToolkitAdaptor::~ToolkitAdaptor()
-{
-  delete mAdaptorStub;
-  gAdaptor = NULL;
-}
-
-void ToolkitAdaptor::EmitSignalResize()
-{
-  mAdaptorStub->EmitSignalResize();
-}
-
-} // namespace Dali
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.h
deleted file mode 100644 (file)
index 5d8473c..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-#ifndef __DALI_TOOLKIT_TOOLKIT_ADAPTOR_H__
-#define __DALI_TOOLKIT_TOOLKIT_ADAPTOR_H__
-
-/*
- * Copyright (c) 2014 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 <boost/function.hpp>
-
-// INTERNAL INCLUDES
-#include "toolkit-style-monitor.h"
-#include "toolkit-accessibility-manager.h"
-#include "toolkit-timer.h"
-#include "toolkit-imf-manager.h"
-#include "toolkit-clipboard-event-notifier.h"
-
-#include <dali/public-api/events/touch-point.h>
-#include <dali/public-api/math/rect.h>
-
-namespace Dali
-{
-
-class Adaptor;
-
-typedef Dali::Rect<int> PositionSize;
-
-/**
- * This creates a stubbed Adaptor so that internal Toolkit Adaptor calls work.
- * Furthermore, it provides an interface to see if certain methods were invoked.
- */
-class ToolkitAdaptor
-{
-public: // Construction & Destruction
-
-  ToolkitAdaptor();
-  ~ToolkitAdaptor();
-
-public: // Getters
-
-  boost::function<void(void)> GetLastIdleAdded() const
-  {
-    return mLastIdleAdded;
-  }
-
-  TouchPoint GetLastTouchPointFed() const
-  {
-    return mLastTouchPointFed;
-  }
-
-  int GetLastTimeStampFed() const
-  {
-    return mLastTimeStampFed;
-  }
-
-  PositionSize GetLastSizeSet() const
-  {
-    return mLastSizeSet;
-  }
-
-  StyleMonitor& GetToolkitStyleMonitor()
-  {
-    return mStyleMonitor;
-  }
-
-  AccessibilityManager& GetAccessibilityManager()
-  {
-    return mAccessibilityManager;
-  }
-
-  ToolkitClipboardEventNotifier& GetClipboardEventNotifier()
-  {
-    return mClipboardEventNotifier;
-  }
-
-public: // Signal Emissions
-
-  void EmitSignalResize();
-
-public: // TEST FUNCTIONS
-
-  // Enumeration of Adaptor methods
-  enum TestFuncEnum
-  {
-    StartType,
-    PauseType,
-    ResumeType,
-    StopType,
-    AddIdleType,
-    FeedEventType,
-    MoveResizeType,
-    SurfaceResizedType,
-    ReplaceSurfaceType,
-    RenderSyncType,
-    GetSurfaceType,
-    GetType,
-    IsAvailableType,
-    RegisterSingletonType,
-    GetSingletonType,
-    SignalResizeType,
-  };
-
-  void Reset()
-  {
-    mFunctionsCalled.Reset();
-  }
-
-  bool WasCalled(TestFuncEnum func)
-  {
-    switch(func)
-    {
-      case StartType:                             return mFunctionsCalled.Start;
-      case PauseType:                             return mFunctionsCalled.Pause;
-      case ResumeType:                            return mFunctionsCalled.Resume;
-      case StopType:                              return mFunctionsCalled.Stop;
-      case AddIdleType:                           return mFunctionsCalled.AddIdle;
-      case FeedEventType:                         return mFunctionsCalled.FeedEvent;
-      case MoveResizeType:                        return mFunctionsCalled.MoveResize;
-      case SurfaceResizedType:                    return mFunctionsCalled.SurfaceResized;
-      case ReplaceSurfaceType:                    return mFunctionsCalled.ReplaceSurface;
-      case RenderSyncType:                        return mFunctionsCalled.RenderSync;
-      case GetSurfaceType:                        return mFunctionsCalled.GetSurface;
-      case GetType:                               return mFunctionsCalled.Get;
-      case IsAvailableType:                       return mFunctionsCalled.IsAvailable;
-      case RegisterSingletonType:                 return mFunctionsCalled.RegisterSingleton;
-      case GetSingletonType:                      return mFunctionsCalled.GetSingleton;
-      case SignalResizeType:                      return mFunctionsCalled.SignalResize;
-    }
-    return false;
-  }
-
-  void ResetCallStatistics(TestFuncEnum func)
-  {
-    switch(func)
-    {
-      case StartType:                             mFunctionsCalled.Start = false; break;
-      case PauseType:                             mFunctionsCalled.Pause = false; break;
-      case ResumeType:                            mFunctionsCalled.Resume = false; break;
-      case StopType:                              mFunctionsCalled.Stop = false; break;
-      case AddIdleType:                           mFunctionsCalled.AddIdle = false; break;
-      case FeedEventType:                         mFunctionsCalled.FeedEvent = false; break;
-      case MoveResizeType:                        mFunctionsCalled.MoveResize = false; break;
-      case SurfaceResizedType:                    mFunctionsCalled.SurfaceResized = false; break;
-      case ReplaceSurfaceType:                    mFunctionsCalled.ReplaceSurface = false; break;
-      case RenderSyncType:                        mFunctionsCalled.RenderSync = false; break;
-      case GetSurfaceType:                        mFunctionsCalled.GetSurface = false; break;
-      case GetType:                               mFunctionsCalled.Get = false; break;
-      case IsAvailableType:                       mFunctionsCalled.IsAvailable = false; break;
-      case RegisterSingletonType:                 mFunctionsCalled.RegisterSingleton = false; break;
-      case GetSingletonType:                      mFunctionsCalled.GetSingleton = false; break;
-      case SignalResizeType:                      mFunctionsCalled.SignalResize = false; break;
-    }
-  }
-
-private:
-
-  struct TestFunctions
-  {
-    TestFunctions()
-    : Start(false),
-      Pause(false),
-      Resume(false),
-      Stop(false),
-      AddIdle(false),
-      FeedEvent(false),
-      MoveResize(false),
-      SurfaceResized(false),
-      ReplaceSurface(false),
-      RenderSync(false),
-      GetSurface(false),
-      Get(false),
-      IsAvailable(false),
-      RegisterSingleton(false),
-      GetSingleton(false),
-      SignalResize(false)
-    {
-    }
-
-    void Reset()
-    {
-      Start = false;
-      Pause = false;
-      Resume = false;
-      Stop = false;
-      AddIdle = false;
-      FeedEvent = false;
-      MoveResize = false;
-      SurfaceResized = false;
-      ReplaceSurface = false;
-      RenderSync = false;
-      GetSurface = false;
-      Get = false;
-      IsAvailable = false;
-      RegisterSingleton = false;
-      GetSingleton = false;
-      SignalResize = false;
-    }
-
-    bool Start;
-    bool Pause;
-    bool Resume;
-    bool Stop;
-    bool AddIdle;
-    bool FeedEvent;
-    bool MoveResize;
-    bool SurfaceResized;
-    bool ReplaceSurface;
-    bool RenderSync;
-    bool GetSurface;
-    bool Get;
-    bool IsAvailable;
-    bool RegisterSingleton;
-    bool GetSingleton;
-    bool SignalResize;
-  };
-
-  TestFunctions mFunctionsCalled;
-
-  // Last set information
-  boost::function<void(void)> mLastIdleAdded;
-  TouchPoint mLastTouchPointFed;
-  int mLastTimeStampFed;
-  PositionSize mLastSizeSet;
-
-  // Contains Test functions for the Style Monitor
-  StyleMonitor mStyleMonitor;
-
-  // Stub for AccessibilityManager
-  AccessibilityManager mAccessibilityManager;
-
-  // Stub for ClipboardEventNotifier
-  ToolkitClipboardEventNotifier mClipboardEventNotifier;
-
-  ImfManager mImfManager;
-
-  // The Adaptor Stub
-  Adaptor* mAdaptorStub;
-  friend class Adaptor;
-};
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_TOOLKIT_ADAPTOR_H__
index e4dc0cc..cf00a92 100644 (file)
 namespace Dali
 {
 
-namespace
-{
-ToolkitClipboardEventNotifier* gToolkitClipboardEventNotifier(NULL);
-} // unnamed namespace
-
 namespace Internal
 {
 
 namespace Adaptor
 {
 
-/**
- * Stub for the ClipboardEventNotifier
- */
-class ClipboardEventNotifier : public BaseObject
+class ClipboardEventNotifier : public Dali::BaseObject
 {
-public: // Creation & Destruction
+public:
+
+  typedef Dali::ClipboardEventNotifier::ClipboardEventSignalV2 ClipboardEventSignalV2;
 
+  // Creation
+  static Dali::ClipboardEventNotifier New();
   static Dali::ClipboardEventNotifier Get();
 
+  // Public API
+  const std::string& GetContent() const;
+  void SetContent( const std::string& content );
+  void ClearContent();
+  void EmitContentSelectedSignal();
+
+  // Signals
+  ClipboardEventSignalV2& ContentSelectedSignal()
+  {
+    return mContentSelectedSignalV2;
+  }
+
+private:
+  // Construction & Destruction
   ClipboardEventNotifier();
-  ClipboardEventNotifier(ToolkitClipboardEventNotifier *clipboardEventNotifier);
-  ~ClipboardEventNotifier();
+  virtual ~ClipboardEventNotifier();
+
+  // Undefined
+  ClipboardEventNotifier( const ClipboardEventNotifier& );
+  ClipboardEventNotifier& operator=( ClipboardEventNotifier& );
+
+private:
 
-public: // Signals
+  std::string mContent;    ///< The current selected content.
+  ClipboardEventSignalV2 mContentSelectedSignalV2;
 
-  Dali::ClipboardEventNotifier::ClipboardEventSignalV2& SignalContentSelected()
+  static Dali::ClipboardEventNotifier mToolkitClipboardEventNotifier;
+
+public:
+
+  // Helpers for public-api forwarding methods
+
+  inline static Internal::Adaptor::ClipboardEventNotifier& GetImplementation(Dali::ClipboardEventNotifier& detector)
   {
-    return mClipboardSignal;
+    DALI_ASSERT_ALWAYS( detector && "ClipboardEventNotifier handle is empty" );
+
+    BaseObject& handle = detector.GetBaseObject();
+
+    return static_cast<Internal::Adaptor::ClipboardEventNotifier&>(handle);
   }
 
-private:
+  inline static const Internal::Adaptor::ClipboardEventNotifier& GetImplementation(const Dali::ClipboardEventNotifier& detector)
+  {
+    DALI_ASSERT_ALWAYS( detector && "ClipboardEventNotifier handle is empty" );
+
+    const BaseObject& handle = detector.GetBaseObject();
 
-  ToolkitClipboardEventNotifier* mToolkitClipboardEventNotifier;
-  Dali::ClipboardEventNotifier::ClipboardEventSignalV2 mClipboardSignal;
+    return static_cast<const Internal::Adaptor::ClipboardEventNotifier&>(handle);
+  }
 
 };
 
+Dali::ClipboardEventNotifier ClipboardEventNotifier::mToolkitClipboardEventNotifier;
+
+Dali::ClipboardEventNotifier ClipboardEventNotifier::New()
+{
+  return Get();
+}
+
 Dali::ClipboardEventNotifier ClipboardEventNotifier::Get()
 {
-  return gToolkitClipboardEventNotifier->GetClipboardEventNotifier();
+  if ( !mToolkitClipboardEventNotifier )
+  {
+    mToolkitClipboardEventNotifier = Dali::ClipboardEventNotifier( new ClipboardEventNotifier );
+  }
+  return mToolkitClipboardEventNotifier;
 }
 
-ClipboardEventNotifier::ClipboardEventNotifier()
-: mToolkitClipboardEventNotifier(NULL)
+const std::string& ClipboardEventNotifier::GetContent() const
+{
+  return mContent;
+}
+
+void ClipboardEventNotifier::SetContent( const std::string& content )
 {
+  mContent = content;
 }
 
-ClipboardEventNotifier::ClipboardEventNotifier(ToolkitClipboardEventNotifier *clipboardEventNotifier)
-: mToolkitClipboardEventNotifier(clipboardEventNotifier)
+void ClipboardEventNotifier::ClearContent()
+{
+  mContent.clear();
+}
+
+void ClipboardEventNotifier::EmitContentSelectedSignal()
+{
+  if ( !mContentSelectedSignalV2.Empty() )
+  {
+    Dali::ClipboardEventNotifier handle( this );
+    mContentSelectedSignalV2.Emit( handle );
+  }
+}
+
+ClipboardEventNotifier::ClipboardEventNotifier()
+: mContent()
 {
 }
 
@@ -82,26 +142,53 @@ ClipboardEventNotifier::~ClipboardEventNotifier()
 }
 
 } // namespace Adaptor
-
 } // namespace Internal
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
-ToolkitClipboardEventNotifier::ToolkitClipboardEventNotifier()
-: mClipboardEventNotifierStub(new Internal::Adaptor::ClipboardEventNotifier(this)),
-  mClipboardEventNotifier( mClipboardEventNotifierStub )
+const char* const ClipboardEventNotifier::SIGNAL_CONTENT_SELECTED( "content-selected" );
+
+ClipboardEventNotifier::ClipboardEventNotifier()
+{
+}
+
+ClipboardEventNotifier ClipboardEventNotifier::Get()
+{
+  return Internal::Adaptor::ClipboardEventNotifier::Get();
+}
+
+ClipboardEventNotifier::~ClipboardEventNotifier()
+{
+}
+
+const std::string& ClipboardEventNotifier::GetContent() const
+{
+  return Internal::Adaptor::ClipboardEventNotifier::GetImplementation(*this).GetContent();
+}
+
+void ClipboardEventNotifier::SetContent( const std::string& content )
+{
+  Internal::Adaptor::ClipboardEventNotifier::GetImplementation(*this).SetContent(content);
+}
+
+void ClipboardEventNotifier::ClearContent()
+{
+  Internal::Adaptor::ClipboardEventNotifier::GetImplementation(*this).ClearContent();
+}
+
+void ClipboardEventNotifier::EmitContentSelectedSignal()
 {
-  gToolkitClipboardEventNotifier = this;
+  Internal::Adaptor::ClipboardEventNotifier::GetImplementation(*this).EmitContentSelectedSignal();
 }
 
-ToolkitClipboardEventNotifier::~ToolkitClipboardEventNotifier()
+ClipboardEventNotifier::ClipboardEventSignalV2& ClipboardEventNotifier::ContentSelectedSignal()
 {
-  gToolkitClipboardEventNotifier = NULL;
+  return Internal::Adaptor::ClipboardEventNotifier::GetImplementation(*this).ContentSelectedSignal();
 }
 
-ClipboardEventNotifier ToolkitClipboardEventNotifier::GetClipboardEventNotifier()
+ClipboardEventNotifier::ClipboardEventNotifier( Internal::Adaptor::ClipboardEventNotifier* notifier )
+: BaseHandle( notifier )
 {
-  return mClipboardEventNotifier;
 }
 
 } // namespace Dali
index c7dcc08..adc4abc 100644 (file)
 #include <string>
 
 // PUBLIC INCLUDES
-#include <dali/public-api/adaptor-framework/clipboard-event-notifier.h>
+#define __DALI_CLIPBOARD_EVENT_NOTIFIER_H__
+#include <dali/public-api/object/base-handle.h>
+#include <dali/public-api/signals/dali-signal-v2.h>
+
 
 namespace Dali
 {
@@ -35,33 +38,24 @@ class ClipboardEventNotifier;
 }
 }
 
-/**
- * This creates a stubbed ClipboardEventNotifier so that internal Toolkit Adaptor calls work.
- */
-class ToolkitClipboardEventNotifier
+class ClipboardEventNotifier : public BaseHandle
 {
-public: // Constants
-
-public: // Construction & Destruction
-
-  ToolkitClipboardEventNotifier();
-  ~ToolkitClipboardEventNotifier();
-
-public: // Getters
-
-  ClipboardEventNotifier GetClipboardEventNotifier();
-
-public: // Signal Emissions
+public:
+  typedef SignalV2< void ( ClipboardEventNotifier& ) > ClipboardEventSignalV2;
+  static const char* const SIGNAL_CONTENT_SELECTED; ///< name "content-selected"
 
-  ClipboardEventNotifier::ClipboardEventSignalV2& SignalContentSelected();
+  ClipboardEventNotifier();
+  static ClipboardEventNotifier Get();
+  ~ClipboardEventNotifier();
 
-public: // TEST FUNCTIONS
+  const std::string& GetContent() const;
+  void SetContent( const std::string& content );
+  void ClearContent();
 
-private:
+  void EmitContentSelectedSignal();
+  ClipboardEventSignalV2& ContentSelectedSignal();
 
-  Internal::Adaptor::ClipboardEventNotifier* mClipboardEventNotifierStub;
-  friend class Internal::Adaptor::ClipboardEventNotifier;
-  ClipboardEventNotifier mClipboardEventNotifier; // Hold a handle ourselves.
+  ClipboardEventNotifier( Internal::Adaptor::ClipboardEventNotifier* notifier );
 };
 
 } // namespace Dali
index 7a090f5..e8e4466 100644 (file)
@@ -21,7 +21,6 @@
 // INTERNAL INCLUDES
 #include <dali-test-suite-utils.h>
 
-#include "toolkit-adaptor.h"
 #include "toolkit-orientation.h"
 
 namespace Dali
@@ -50,18 +49,12 @@ public:
     mCore = NULL;
   }
 
-  inline ToolkitAdaptor& GetAdaptor()
-  {
-    return mAdaptor;
-  }
-
   //ToolkitOrientation& GetOrientation()
   //{
   //return mOrientation;
   //}
 
 private:
-  ToolkitAdaptor mAdaptor;
   //ToolkitOrientation mOrientation;
 };
 
index 5d0e4ab..869f9a6 100644 (file)
@@ -21,6 +21,7 @@
 // Need to override adaptor classes for toolkit test harness, so include
 // test harness headers before dali headers.
 #include <dali-toolkit-test-suite-utils.h>
+#include "toolkit-style-monitor.h"
 
 #include <dali.h>
 #include <dali-toolkit/dali-toolkit.h>
@@ -656,7 +657,7 @@ int UtcDaliControlImplStyleChange(void)
   DALI_TEST_EQUALS( dummyImpl.fontChangeCalled, false, TEST_LOCATION );
   StyleChange styleChange;
   styleChange.defaultFontChange = true;
-  Dali::StyleMonitor styleMonitor = application.GetAdaptor().GetToolkitStyleMonitor();
+  Dali::StyleMonitor styleMonitor = StyleMonitor::Get();
   styleMonitor.EmitStyleChangeSignal(styleChange);
 
   DALI_TEST_EQUALS( dummyImpl.fontChangeCalled, true, TEST_LOCATION );
index f6af80e..3f134b6 100644 (file)
@@ -87,6 +87,7 @@ std::string ToString(const Rect<int>& value)
   return ss.str();
 }
 
+#if defined(DEBUG_ENABLED)
 
 std::string PropertyValueToString( const Property::Value& value )
 {
@@ -178,6 +179,7 @@ std::string PropertyValueToString( const Property::Value& value )
 
   return ret;
 }
+#endif // DEBUG_ENABLED
 
 /*
  * Recursively collects all stylesin a node (An array of style names).
@@ -1010,7 +1012,6 @@ bool Builder::ApplyStyle( const std::string& styleName, Handle& handle, const Re
   }
   else
   {
-    DALI_SCRIPT_WARNING("No styles section to create style '%s'\n", styleName.c_str());
     return false;
   }
 }
index f2e4af1..ec78cba 100644 (file)
@@ -224,13 +224,10 @@ void Button::OnTap(Actor actor, TapGesture tap)
   // Do nothing.
 }
 
-void Button::OnStageDisconnection()
+void Button::OnControlStageDisconnection()
 {
-  if( ButtonUp != mState )
-  {
-    OnTouchPointLeave(); // Notification for derived classes.
-    mState = ButtonUp;
-  }
+  OnButtonStageDisconnection(); // Notification for derived classes.
+  mState = ButtonUp;
 }
 
 void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
index 441a725..e3763e4 100644 (file)
@@ -130,6 +130,12 @@ private:
    */
   virtual float OnAnimationTimeRequested() const;
 
+  /**
+   * This method is called when the button is removed from the stage.
+   * Could be reimplemented in subclasses to provide specific behaviour.
+   */
+  virtual void OnButtonStageDisconnection() { }
+
 public:
 
   /**
@@ -185,6 +191,12 @@ private: // From Control
    */
   virtual void OnControlSizeSet( const Vector3& targetSize );
 
+  /**
+   * Callback received when the button is disconnected from the stage.
+   * It resets the button status.
+   */
+  void OnControlStageDisconnection();
+
 private:
 
   /**
@@ -199,14 +211,6 @@ private:
 
 private:
 
-  /**
-   * Callback received when the button is disconected from the stage.
-   * It resets the button status.
-   */
-  void OnStageDisconnection();
-
-private:
-
   // Undefined
   Button( const Button& );
 
index 46159ed..9d758b0 100644 (file)
@@ -644,6 +644,25 @@ float PushButton::OnAnimationTimeRequested() const
   return GetPushButtonPainter( mPainter )->GetAnimationTime();
 }
 
+void PushButton::OnButtonStageDisconnection()
+{
+  if( ButtonDown == mState )
+  {
+    if( !mToggleButton )
+    {
+      Toolkit::PushButton handle( GetOwner() );
+
+      // Notifies the painter the button has been released.
+      GetPushButtonPainter( mPainter )->Released( handle );
+
+      if( mAutoRepeating )
+      {
+        mAutoRepeatingTimer.Reset();
+      }
+    }
+  }
+}
+
 PushButton::PushButton()
 : Button(),
   mAutoRepeating( false ),
index a6c0b86..b4acfaf 100644 (file)
@@ -321,6 +321,11 @@ protected: // From Button
    */
   virtual float OnAnimationTimeRequested() const;
 
+  /**
+   * This method is called when the button is removed from the stage.
+   */
+  virtual void OnButtonStageDisconnection();
+
 protected: // From Control
 
   /**
index 850431e..69e02a8 100644 (file)
@@ -86,36 +86,6 @@ enum SelectionState
   SelectionFinished                         ///< Finished selected section
 };
 
-/**
- * Whether the given style is the default style or not.
- * @param[in] style The given style.
- * @return \e true if the given style is the default. Otherwise it returns \e false.
- */
-bool IsDefaultStyle( const TextStyle& style )
-{
-  return DEFAULT_TEXT_STYLE == style;
-}
-
-/**
- * Whether the given styled text is using the default style or not.
- * @param[in] textArray The given text.
- * @return \e true if the given styled text is using the default style. Otherwise it returns \e false.
- */
-bool IsTextDefaultStyle( const Toolkit::MarkupProcessor::StyledTextArray& textArray )
-{
-  for( Toolkit::MarkupProcessor::StyledTextArray::const_iterator it = textArray.begin(), endIt = textArray.end(); it != endIt; ++it )
-  {
-    const TextStyle& style( (*it).mStyle );
-
-    if( !IsDefaultStyle( style ) )
-    {
-      return false;
-    }
-  }
-
-  return true;
-}
-
 std::size_t FindVisibleCharacterLeft( std::size_t cursorPosition, const Toolkit::TextView::CharacterLayoutInfoContainer& characterLayoutInfoTable )
 {
   for( Toolkit::TextView::CharacterLayoutInfoContainer::const_reverse_iterator it = characterLayoutInfoTable.rbegin() + characterLayoutInfoTable.size() - cursorPosition, endIt = characterLayoutInfoTable.rend();
@@ -281,9 +251,9 @@ Dali::Toolkit::TextInput TextInput::New()
   TextInputPtr textInput(new TextInput());
   // Pass ownership to CustomActor via derived handle
   Dali::Toolkit::TextInput handle(*textInput);
+  handle.SetName( "TextInput");
 
   textInput->Initialize();
-
   return handle;
 }
 
@@ -1072,13 +1042,10 @@ void TextInput::OnKeyInputFocusGained()
   mClipboard = Clipboard::Get(); // Store handle to clipboard
 
   // Now in edit mode we can accept string to paste from clipboard
-  if( Adaptor::IsAvailable() )
+  ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
+  if ( notifier )
   {
-    ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
-    if ( notifier )
-    {
-      notifier.ContentSelectedSignal().Connect( this, &TextInput::OnClipboardTextSelected );
-    }
+    notifier.ContentSelectedSignal().Connect( this, &TextInput::OnClipboardTextSelected );
   }
 }
 
@@ -1122,19 +1089,16 @@ void TextInput::OnKeyInputFocusLost()
 
   mClipboard.Reset();
   // No longer in edit mode so do not want to receive string from clipboard
-  if( Adaptor::IsAvailable() )
+  ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
+  if ( notifier )
   {
-    ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
-    if ( notifier )
-    {
-      notifier.ContentSelectedSignal().Disconnect( this, &TextInput::OnClipboardTextSelected );
-    }
-    Clipboard clipboard = Clipboard::Get();
+    notifier.ContentSelectedSignal().Disconnect( this, &TextInput::OnClipboardTextSelected );
+  }
 
-    if ( clipboard )
-    {
-      clipboard.HideClipboard();
-    }
+  Clipboard clipboard = Clipboard::Get();
+  if ( clipboard )
+  {
+    clipboard.HideClipboard();
   }
 }
 
@@ -1152,6 +1116,7 @@ void TextInput::CreateActiveLayer()
 {
   Actor self = Self();
   mActiveLayer = Layer::New();
+  mActiveLayer.SetName ( "ActiveLayerActor" );
 
   mActiveLayer.SetAnchorPoint( AnchorPoint::CENTER);
   mActiveLayer.SetParentOrigin( ParentOrigin::CENTER);
@@ -1387,6 +1352,12 @@ void TextInput::OnDoubleTap(Dali::Actor actor, Dali::TapGesture tap)
      mTextLayoutInfo.mScrollOffset = mDisplayedTextView.GetScrollPosition();
      ReturnClosestIndex( tap.localPoint, mCursorPosition );
 
+     std::size_t start = 0;
+     std::size_t end = 0;
+     Dali::Toolkit::Internal::TextProcessor::FindNearestWord( mStyledText, mCursorPosition, start, end );
+
+     mCursorPosition = end; // Ensure cursor is positioned at end of selected word
+
      ImfManager imfManager = ImfManager::Get();
      if ( imfManager )
      {
@@ -1394,14 +1365,20 @@ void TextInput::OnDoubleTap(Dali::Actor actor, Dali::TapGesture tap)
        imfManager.NotifyCursorPosition();
      }
 
-     std::size_t start = 0;
-     std::size_t end = 0;
-     Dali::Toolkit::Internal::TextProcessor::FindNearestWord( mStyledText, mCursorPosition, start, end );
-
-     SelectText( start, end );
+     if ( !mStyledText.at(end-1).mText[0].IsWhiteSpace() )
+     {
+       SelectText( start, end );
+       ShowPopupCutCopyPaste();
+     }
+     else
+     {
+       RemoveHighlight( false ); // Remove highlight but do not auto hide popup
+       HidePopup( false ); // Hide popup with setting to do auto show.
+       SetUpPopupSelection( false ); // Set to false so if nearest word is whitespace it will not show cut button.
+       ShowPopup();
+     }
    }
-   // if no text but clipboard has content then show paste option
-   if ( ( mClipboard && mClipboard.NumberOfItems() ) || !mStyledText.empty() )
+   else if ( mClipboard && mClipboard.NumberOfItems() )
    {
      ShowPopupCutCopyPaste();
    }
@@ -1450,26 +1427,6 @@ void TextInput::OnTextTap(Dali::Actor actor, Dali::TapGesture tap)
     {
       // Set the initial cursor position in the tap point.
       ReturnClosestIndex(tap.localPoint, mCursorPosition );
-
-      // Create the grab handle.
-      // TODO Make this a re-usable function.
-      if ( IsGrabHandleEnabled() )
-      {
-        const Vector3 cursorPosition = GetActualPositionFromCharacterPosition(mCursorPosition);
-
-        CreateGrabHandle();
-
-        mActualGrabHandlePosition.x = cursorPosition.x; // Set grab handle to be at the cursor position
-        mActualGrabHandlePosition.y = cursorPosition.y; // Set grab handle to be at the cursor position
-        mGrabHandle.SetPosition( mActualGrabHandlePosition + UI_OFFSET );
-        ShowGrabHandleAndSetVisibility( mIsGrabHandleInScrollArea );
-
-      }
-
-      // Edit mode started after grab handle created to ensure the signal InputStarted is sent last.
-      // This is used to ensure if selecting text hides the grab handle then this code is run after grab handle is created,
-      // otherwise the Grab handle will be shown when selecting.
-
       StartEditMode();
     }
   }
@@ -1523,6 +1480,9 @@ void TextInput::OnTextTap(Dali::Actor actor, Dali::TapGesture tap)
     }
   }
 
+  // Edit mode started after grab handle created to ensure the signal InputStarted is sent last.
+  // This is used to ensure if selecting text hides the grab handle then this code is run after grab handle is created,
+  // otherwise the Grab handle will be shown when selecting.
   if ( createGrabHandle && IsGrabHandleEnabled() )
   {
     const Vector3 cursorPosition = GetActualPositionFromCharacterPosition(mCursorPosition);
@@ -1541,6 +1501,12 @@ void TextInput::OnLongPress(Dali::Actor actor, Dali::LongPressGesture longPress)
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "OnLongPress\n" );
 
+  // Ignore longpress if in selection mode already
+  if( mHighlightMeshActor )
+  {
+    return;
+  }
+
   if(longPress.state == Dali::Gesture::Started)
   {
     // Start edit mode on long press
@@ -1577,15 +1543,18 @@ void TextInput::OnLongPress(Dali::Actor actor, Dali::LongPressGesture longPress)
       mTextLayoutInfo.mScrollOffset = mDisplayedTextView.GetScrollPosition();
       ReturnClosestIndex( longPress.localPoint, mCursorPosition );
 
+      std::size_t start = 0;
+      std::size_t end = 0;
+      Dali::Toolkit::Internal::TextProcessor::FindNearestWord( mStyledText, mCursorPosition, start, end );
+
+      mCursorPosition  = end; // Ensure cursor is positioned at end of selected word
+
       ImfManager imfManager = ImfManager::Get();
       if ( imfManager )
       {
         imfManager.SetCursorPosition ( mCursorPosition );
         imfManager.NotifyCursorPosition();
       }
-      std::size_t start = 0;
-      std::size_t end = 0;
-      Dali::Toolkit::Internal::TextProcessor::FindNearestWord( mStyledText, mCursorPosition, start, end );
 
       SelectText( start, end );
     }
@@ -1744,11 +1713,9 @@ bool TextInput::OnKeyDownEvent(const KeyEvent& event)
     {
       bool preEditFlagPreviouslySet( mPreEditFlag );
 
-      if (mHighlightMeshActor)
-      {
-        // replaces highlighted text with new line
-        DeleteHighlightedText( false );
-      }
+      // replaces highlighted text with new line
+      DeleteHighlightedText( false );
+
       mCursorPosition = mCursorPosition + InsertAt( Text( NEWLINE ), mCursorPosition, 0 );
 
       // If we are in pre-edit mode then pressing enter will cause a commit.  But the commit string does not include the
@@ -1825,15 +1792,11 @@ bool TextInput::OnKeyDownEvent(const KeyEvent& event)
     // Some text may be selected, hiding keyboard causes an empty keystring to be sent, we don't want to delete highlight in this case
     if ( !keyString.empty() )
     {
-      if ( mHighlightMeshActor )
-      {
-        // replaces highlighted text with new character
-        DeleteHighlightedText( false );
-      }
-
+      // replaces highlighted text with new character
+      DeleteHighlightedText( false );
 
       // Received key String
-      mCursorPosition = mCursorPosition + InsertAt( Text( keyString ), mCursorPosition, 0 );
+      mCursorPosition += InsertAt( Text( keyString ), mCursorPosition, 0 );
       update = true;
       EmitTextModified();
     }
@@ -2076,6 +2039,7 @@ void TextInput::SetUpTouchEvents()
 void TextInput::CreateTextViewActor()
 {
   mDisplayedTextView = Toolkit::TextView::New();
+  mDisplayedTextView.SetName( "DisplayedTextView ");
   mDisplayedTextView.SetMarkupProcessingEnabled( mMarkUpEnabled );
   mDisplayedTextView.SetParentOrigin(ParentOrigin::TOP_LEFT);
   mDisplayedTextView.SetAnchorPoint(AnchorPoint::TOP_LEFT);
@@ -2579,7 +2543,7 @@ void TextInput::DeleteHighlightedText( bool inheritStyle )
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "DeleteHighlightedText handlePosOne[%u] handlePosTwo[%u]\n", mSelectionHandleOnePosition, mSelectionHandleTwoPosition);
 
-  if(mHighlightMeshActor)
+  if( mHighlightMeshActor )
   {
     mCursorPosition = std::min( mSelectionHandleOnePosition, mSelectionHandleTwoPosition );
 
@@ -2826,9 +2790,10 @@ ImageActor TextInput::CreateCursor( const Vector4& color)
 {
   ImageActor cursor;
   cursor = CreateSolidColorActor(color);
+  cursor.SetName( "Cursor" );
 
   cursor.SetParentOrigin(ParentOrigin::TOP_LEFT);
-  cursor.SetAnchorPoint(AnchorPoint::BOTTOM_CENTER);
+  cursor.SetAnchorPoint(AnchorPoint::BOTTOM_LEFT);
   cursor.SetVisible(false);
 
   return cursor;
@@ -2887,7 +2852,7 @@ void TextInput::DrawCursor(const std::size_t nthChar)
 {
   // Get height of cursor and set its size
   Size size( CURSOR_THICKNESS, 0.0f );
-  if (!mTextLayoutInfo.mCharacterLayoutInfoTable.empty())
+  if( !mTextLayoutInfo.mCharacterLayoutInfoTable.empty() )
   {
     size.height = GetRowRectFromCharacterPosition( GetVisualPosition( mCursorPosition ) ).height;
   }
@@ -2981,11 +2946,13 @@ void TextInput::CreateGrabHandle( Dali::Image image )
 void TextInput::CreateGrabArea( Actor& parent )
 {
   mGrabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
+  mGrabArea.SetName( "GrabArea" );
   mGrabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
   mGrabArea.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), RelativeToConstraint( DEFAULT_GRAB_HANDLE_RELATIVE_SIZE ) ) );  // grab area to be larger than text actor
   mGrabArea.TouchedSignal().Connect(this,&TextInput::OnPressDown);
   mTapDetector.Attach( mGrabArea );
   mPanGestureDetector.Attach( mGrabArea );
+  mLongPressDetector.Attach( mGrabArea );
 
   parent.Add(mGrabArea);
 }
@@ -3841,7 +3808,7 @@ void TextInput::ShowPopupCutCopyPaste()
   ShowPopup();
 }
 
-void TextInput::SetUpPopupSelection()
+void TextInput::SetUpPopupSelection( bool showCutButton )
 {
   ClearPopup();
   mPopupPanel.CreateOrderedListOfOptions(); // todo Move this so only run when order has changed
@@ -3850,7 +3817,7 @@ void TextInput::SetUpPopupSelection()
   {
     mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsSelectAll, true );
     mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsSelect, true );
-    mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsCut, true );
+    mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsCut, showCutButton );
   }
   // if clipboard has valid contents then offer paste option
   if( mClipboard && mClipboard.NumberOfItems() )
@@ -4240,7 +4207,7 @@ Vector3 TextInput::GetActualPositionFromCharacterPosition(std::size_t characterP
       // between RTL and LTR text...
       if(characterPosition != mTextLayoutInfo.mCharacterLogicalToVisualMap.size())
       {
-        std::size_t visualCharacterAltPosition = mTextLayoutInfo.mCharacterLogicalToVisualMap[characterPosition] - 1;
+        std::size_t visualCharacterAltPosition = mTextLayoutInfo.mCharacterLogicalToVisualMap[characterPosition]; // VCC TODO: find why in the previous patch it was a -1 here.
 
         DALI_ASSERT_ALWAYS(visualCharacterAltPosition < mTextLayoutInfo.mCharacterLayoutInfoTable.size());
         const Toolkit::TextView::CharacterLayoutInfo& infoAlt = mTextLayoutInfo.mCharacterLayoutInfoTable[ visualCharacterAltPosition ];
@@ -4583,16 +4550,7 @@ void TextInput::SelectText(std::size_t start, std::size_t end)
     // When replacing highlighted text keyboard should ignore current word at cursor hence notify keyboard that the cursor is at the start of the highlight.
     mSelectingText = true;
 
-    mCursorPosition = std::min( start, end ); // Set cursor position to start of highlighted text.
-
-    ImfManager imfManager = ImfManager::Get();
-    if ( imfManager )
-    {
-      imfManager.SetCursorPosition ( mCursorPosition );
-      imfManager.SetSurroundingText( GetText() );
-      imfManager.NotifyCursorPosition();
-    }
-    // As the imfManager has been notified of the new cursor position we do not need to reset the pre-edit as it will be updated instead.
+    std::size_t selectionStartPosition = std::min( start, end );
 
     // Hide grab handle when selecting.
     ShowGrabHandleAndSetVisibility( false );
@@ -4606,7 +4564,7 @@ void TextInput::SelectText(std::size_t start, std::size_t end)
       UpdateHighlight();
 
       const TextStyle oldInputStyle( mInputStyle );
-      mInputStyle = GetStyleAt( mCursorPosition ); // Inherit style from selected position.
+      mInputStyle = GetStyleAt( selectionStartPosition ); // Inherit style from selected position.
 
       if( oldInputStyle != mInputStyle )
       {
@@ -4686,7 +4644,7 @@ void TextInput::KeyboardStatusChanged(bool keyboardShown)
 }
 
 // Removes highlight and resumes edit mode state
-void TextInput::RemoveHighlight()
+void TextInput::RemoveHighlight( bool hidePopup )
 {
   DALI_LOG_INFO(gLogFilter, Debug::General, "RemoveHighlight\n");
 
@@ -4716,7 +4674,10 @@ void TextInput::RemoveHighlight()
     // NOTE: We cannot dereference mHighlightMesh, due
     // to a bug in how the scene-graph MeshRenderer uses the Mesh data incorrectly.
 
-    HidePopup();
+    if ( hidePopup )
+    {
+      HidePopup();
+    }
   }
 
   mSelectionHandleOnePosition = 0;
index dfbb2c5..c9e3b18 100644 (file)
@@ -1084,8 +1084,10 @@ public:  // Public to allow internal testing.
 
   /**
    * Setup the selection popup and clipboard if relevant so the correct options are shown when ShowPopup is called.
+   * @param[in] showCutButton Flag to show or hide cut button, in some cases like whitespace we do not want to cut just select.
+   * default is true.
    */
-  void SetUpPopupSelection();
+  void SetUpPopupSelection( bool showCutButton = true );
 
   /**
    * Return the logical index containing the character position closest to the source.
@@ -1218,8 +1220,9 @@ public:  // Public to allow internal testing.
 
   /**
    * Hide highlight shown between selection handles.
+   * @param[in] hidePopup flag to hide the popup too, default is to hide popup.
    */
-  void RemoveHighlight();
+  void RemoveHighlight( bool hidePopup = true );
 
   /**
    * Highlights text that has been selected
index fab32ca..23c943c 100644 (file)
@@ -5,7 +5,7 @@
  * 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
+ * http://www.apache.org/license/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,
 #include <dali-toolkit/internal/controls/text-view/relayout-utilities.h>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/text-view/text-processor.h>
+#include <dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.h>
+#include <dali-toolkit/internal/controls/text-view/text-view-word-processor.h>
 #include <dali-toolkit/internal/controls/text-view/text-view-processor-helper-functions.h>
+#include <dali-toolkit/internal/controls/text-view/text-view-processor-dbg.h>
 
 // EXTERNAL INCLUDES
 #include <cmath>
@@ -213,7 +217,7 @@ struct CurrentTextActorInfo
   Vector3 position;
   Size size;
   Vector4 color;
-  TextViewProcessor::GradientInfo* gradientInfo;
+  TextViewProcessor::CharacterLayoutInfo* characterLayout;
 };
 
 void SetVisualParameters( CurrentTextActorInfo& currentTextActorInfo,
@@ -222,11 +226,12 @@ void SetVisualParameters( CurrentTextActorInfo& currentTextActorInfo,
                           const float lineHeight )
 {
   currentTextActorInfo.textActor.SetTextColor( currentTextActorInfo.color );
-  if( NULL != currentTextActorInfo.gradientInfo )
+  if( ( NULL != currentTextActorInfo.characterLayout ) &&
+      ( NULL != currentTextActorInfo.characterLayout->mGradientInfo ) )
   {
-    currentTextActorInfo.textActor.SetGradientColor( currentTextActorInfo.gradientInfo->mGradientColor );
-    currentTextActorInfo.textActor.SetGradientStartPoint( currentTextActorInfo.gradientInfo->mStartPoint );
-    currentTextActorInfo.textActor.SetGradientEndPoint( currentTextActorInfo.gradientInfo->mEndPoint );
+    currentTextActorInfo.textActor.SetGradientColor( currentTextActorInfo.characterLayout->mGradientInfo->mGradientColor );
+    currentTextActorInfo.textActor.SetGradientStartPoint( currentTextActorInfo.characterLayout->mGradientInfo->mStartPoint );
+    currentTextActorInfo.textActor.SetGradientEndPoint( currentTextActorInfo.characterLayout->mGradientInfo->mEndPoint );
   }
 
   // The italics offset is used in the offscreen rendering. When text is in italics, it may exceed the text-view's boundary
@@ -343,6 +348,278 @@ void CalculateLineLayout( float parentWidth,
   subLineInfo.mMaxAscender *= shrinkFactor;
 }
 
+
+/**
+ * Sets a character of a line of a bidirectional paragraph in the new position.
+ *
+ * @param[in] wordsLayoutInfo Layout info of all the words of the paragraph.
+ * @param[in] index Index within the paragraph to the character to be set in the new position.
+ * @param[in,out] character Reference to the character in the new position.
+ */
+void SetCharacter( const TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo,
+                   std::size_t index,
+                   TextViewProcessor::CharacterLayoutInfo& character )
+{
+  // Traverse all the characters of the paragraph till the one pointed by index is found.
+  std::size_t traversedCharacters = 0u;
+  for( TextViewProcessor::WordLayoutInfoContainer::const_iterator wordIt = wordsLayoutInfo.begin(),
+         wordEndIt = wordsLayoutInfo.end();
+       wordIt != wordEndIt;
+       ++wordIt )
+  {
+    const TextViewProcessor::WordLayoutInfo& word( *wordIt );
+
+    const std::size_t numberOfCharacters = word.mCharactersLayoutInfo.size();
+    if( index < traversedCharacters + numberOfCharacters  )
+    {
+      character = *( word.mCharactersLayoutInfo.begin() + ( index - traversedCharacters ) );
+      return;
+    }
+    traversedCharacters += numberOfCharacters;
+  }
+}
+
+/**
+ * Reorders the layout info of each line of the paragraph.
+ *
+ * Uses the visual to logical conversion table to order the text, styles and character's layout (metrics).
+ *
+ * @param[in,out] rtlParagraph Layout info for the paragraph with rtl text.
+ */
+void ReorderLayout( TextViewProcessor::ParagraphLayoutInfo& paragraph )
+{
+  // Clear any previous right to left layout.
+  if( NULL != paragraph.mRightToLeftLayout )
+  {
+    paragraph.mRightToLeftLayout->Clear();
+    paragraph.mRightToLeftLayout->mPreviousLayoutCleared = true;
+  }
+  else
+  {
+    // Create a new right to left layout if there isn't any.
+    paragraph.mRightToLeftLayout = new TextViewProcessor::RightToLeftParagraphLayout();
+  }
+
+  // Reorder Text and Styles.
+
+  // Reserve space for the styles.
+  paragraph.mRightToLeftLayout->mTextStyles.Reserve( paragraph.mTextStyles.Count() );
+
+  // Traverses all the bidirectional info per line.
+  for( Vector<TextProcessor::BidirectionalLineInfo*>::ConstIterator it = paragraph.mBidirectionalLinesInfo.Begin(), endIt = paragraph.mBidirectionalLinesInfo.End(); it != endIt; ++it )
+  {
+    TextProcessor::BidirectionalLineInfo* info( *it );
+
+    const std::size_t characterParagraphIndex = info->mCharacterParagraphIndex;
+    const Vector<int>& visualToLogicalMap = info->mVisualToLogicalMap;
+
+    // The text can be appended as it's already reordered.
+    paragraph.mRightToLeftLayout->mText.Append( info->mText );
+
+    // The visual to logical map needs to be used to reorder the styles.
+    for( std::size_t index = 0u, size = visualToLogicalMap.Count(); index < size; ++index )
+    {
+      paragraph.mRightToLeftLayout->mTextStyles.PushBack( *( paragraph.mTextStyles.Begin() + ( characterParagraphIndex + *( visualToLogicalMap.Begin() + index ) ) ) );
+    }
+  }
+
+  // Reorder Layout Info.
+
+  // Reserve space for the new word layout.
+  paragraph.mRightToLeftLayout->mWordsLayoutInfo.reserve( paragraph.mWordsLayoutInfo.size() );
+
+  // Traverses all the bidirectional info per line.
+  for( Vector<TextProcessor::BidirectionalLineInfo*>::ConstIterator it = paragraph.mBidirectionalLinesInfo.Begin(), endIt = paragraph.mBidirectionalLinesInfo.End(); it != endIt; ++it )
+  {
+    TextProcessor::BidirectionalLineInfo* info( *it );
+
+    // Reserve space for all characters.
+    TextViewProcessor::CharacterLayoutInfoContainer characters;
+    characters.resize( info->mNumberOfCharacters );
+
+    // Uses the visual to logical map to set every character in its new position.
+    for( std::size_t index = 0u; index < info->mNumberOfCharacters; ++index )
+    {
+      SetCharacter( paragraph.mWordsLayoutInfo,
+                    info->mCharacterParagraphIndex + info->mVisualToLogicalMap[index],
+                    *( characters.begin() + index ) );
+    }
+
+    // Sets the new 'x' position for each character.
+    float xPosition = 0.f;
+    for( TextViewProcessor::CharacterLayoutInfoContainer::iterator it = characters.begin(), endIt = characters.end(); it != endIt; ++it )
+    {
+      TextViewProcessor::CharacterLayoutInfo& character( *it );
+
+      character.mPosition.x = xPosition;
+      xPosition += character.mSize.width;
+    }
+
+    // Split the reordered text in words.
+    std::size_t previousPosition = 0u;
+    Vector<std::size_t> positions;
+    TextProcessor::SplitInWords( info->mText, positions );
+
+    // Sets the characters into the words they belong to.
+    for( Vector<size_t>::ConstIterator it = positions.Begin(), endIt = positions.End(); it != endIt; ++it )
+    {
+      const std::size_t position = *it;
+
+      TextViewProcessor::WordLayoutInfo word;
+      word.mCharactersLayoutInfo.insert( word.mCharactersLayoutInfo.end(),
+                                         characters.begin() + previousPosition,
+                                         characters.begin() + position );
+
+      if( !word.mCharactersLayoutInfo.empty() )
+      {
+        // Updates the layout of the word.
+        TextViewProcessor::UpdateLayoutInfo( word );
+
+        paragraph.mRightToLeftLayout->mWordsLayoutInfo.push_back( word );
+      }
+
+      // white space or new paragraph.
+      TextViewProcessor::WordLayoutInfo space;
+      space.mCharactersLayoutInfo.insert( space.mCharactersLayoutInfo.end(),
+                                          characters.begin() + position,
+                                          characters.begin() + position + 1u );
+
+      TextViewProcessor::UpdateLayoutInfo( space );
+
+      paragraph.mRightToLeftLayout->mWordsLayoutInfo.push_back( space );
+
+      previousPosition = position + 1u;
+    }
+
+    // The last word.
+    if( previousPosition < paragraph.mRightToLeftLayout->mText.GetLength() )
+    {
+      TextViewProcessor::WordLayoutInfo word;
+      word.mCharactersLayoutInfo.insert( word.mCharactersLayoutInfo.end(),
+                                         characters.begin() + previousPosition,
+                                         characters.end() );
+
+      TextViewProcessor::UpdateLayoutInfo( word );
+
+      paragraph.mRightToLeftLayout->mWordsLayoutInfo.push_back( word );
+    }
+  }
+}
+
+/**
+ * Creates the bidirectional info needed to reorder each line of the paragraph.
+ *
+ * @param[in,out] relayoutData Natural size (metrics), layout, text-actor info.
+ * @param[in,out] paragraph Layout info for the paragraph.
+ * @param[in] characterGlobalIndex Index to the character within the whole text.
+ * @param[in] lineLayoutInfoIndex Index to the table of lines.
+ */
+void CreateBidirectionalInfoForLines( TextView::RelayoutData& relayoutData,
+                                      TextViewProcessor::ParagraphLayoutInfo& paragraph,
+                                      std::size_t& characterGlobalIndex,
+                                      std::size_t& lineLayoutInfoIndex )
+{
+  const std::size_t lineLayoutInfoSize = relayoutData.mLines.size(); // Number or laid out lines.
+  bool lineLayoutEnd = false;            // Whether lineLayoutInfoIndex points at the last laid out line.
+
+  // Clear previously created bidirectional info.
+  paragraph.ClearBidirectionalInfo();
+
+  std::size_t characterParagraphIndex = 0u;   // Index to the character (within the paragraph).
+  for( TextViewProcessor::WordLayoutInfoContainer::iterator wordIt = paragraph.mWordsLayoutInfo.begin(), wordEndIt = paragraph.mWordsLayoutInfo.end();
+       wordIt != wordEndIt;
+       ++wordIt )
+  {
+    TextViewProcessor::WordLayoutInfo& word( *wordIt );
+
+    for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterIt = word.mCharactersLayoutInfo.begin(), characterEndIt = word.mCharactersLayoutInfo.end();
+         characterIt != characterEndIt;
+         ++characterIt )
+    {
+      TextProcessor::BidirectionalLineInfo* bidirectionalLineInfo = NULL;
+
+      // Check if there is a new line.
+      const bool newLine = !lineLayoutEnd && ( characterGlobalIndex == relayoutData.mLines[lineLayoutInfoIndex].mCharacterGlobalIndex );
+
+      if( newLine )
+      {
+        // Point to the next line.
+        ++lineLayoutInfoIndex;
+        if( lineLayoutInfoIndex >= lineLayoutInfoSize )
+        {
+          // Arrived at last line.
+          lineLayoutEnd = true; // Avoids access out of bounds in the relayoutData.mLines vector.
+        }
+
+        // Number of characters of the line.
+        const size_t numberOfCharacters = ( lineLayoutEnd ? relayoutData.mTextLayoutInfo.mNumberOfCharacters : relayoutData.mLines[lineLayoutInfoIndex].mCharacterGlobalIndex ) - characterGlobalIndex;
+
+        // There is right to left characters in this line. It needs to be reordered.
+        bidirectionalLineInfo = new TextProcessor::BidirectionalLineInfo();
+        bidirectionalLineInfo->mCharacterParagraphIndex = characterParagraphIndex;
+        bidirectionalLineInfo->mNumberOfCharacters = numberOfCharacters;
+
+        // Set all the Text's characters in the visual order and creates the mapping tables.
+        TextProcessor::ReorderLine( paragraph.mBidirectionalParagraphInfo,
+                                    bidirectionalLineInfo );
+
+        paragraph.mBidirectionalLinesInfo.PushBack( bidirectionalLineInfo );
+
+        for( std::size_t index = 0u; index < numberOfCharacters; ++index )
+        {
+          relayoutData.mCharacterLogicalToVisualMap.push_back( characterGlobalIndex + bidirectionalLineInfo->mLogicalToVisualMap[index] );
+          relayoutData.mCharacterVisualToLogicalMap.push_back( characterGlobalIndex + bidirectionalLineInfo->mVisualToLogicalMap[index] );
+        }
+      }
+
+      ++characterGlobalIndex;
+      ++characterParagraphIndex;
+    } // characters
+  } // words
+}
+
+void ReorderRightToLeftLayout( TextView::RelayoutData& relayoutData )
+{
+  // Reset conversion tables shared through public-api
+  relayoutData.mCharacterLogicalToVisualMap.clear();
+  relayoutData.mCharacterVisualToLogicalMap.clear();
+
+  std::size_t characterGlobalIndex = 0u; // Index to the global character (within the whole text).
+  std::size_t lineLayoutInfoIndex = 0u;  // Index to the line info.
+
+  for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(), paragraphEndIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
+       paragraphIt != paragraphEndIt;
+       ++paragraphIt )
+  {
+    TextViewProcessor::ParagraphLayoutInfo& paragraph( *paragraphIt );
+
+    if( NULL != paragraph.mBidirectionalParagraphInfo )
+    {
+      // There is right to left text in this paragraph.
+
+      // Creates the bidirectional info needed to reorder each line of the paragraph.
+      CreateBidirectionalInfoForLines( relayoutData,
+                                       paragraph,
+                                       characterGlobalIndex,
+                                       lineLayoutInfoIndex );
+
+      // Reorder each line of the paragraph
+      ReorderLayout( paragraph );
+    }
+    else
+    {
+      // Identity in case the paragraph has no right to left text.
+      for( std::size_t index = 0u; index < paragraph.mNumberOfCharacters; ++index )
+      {
+        const std::size_t globalIndex = characterGlobalIndex + index;
+        relayoutData.mCharacterLogicalToVisualMap.push_back( globalIndex );
+        relayoutData.mCharacterVisualToLogicalMap.push_back( globalIndex );
+      }
+      characterGlobalIndex += paragraph.mNumberOfCharacters;
+    }
+  } // paragraphs
+}
+
 float CalculateXoffset( Toolkit::Alignment::Type horizontalTextAlignment, float parentWidth, float wholeTextWidth )
 {
   float xOffset( 0.f );
@@ -513,8 +790,11 @@ void UpdateAlignment( const TextView::LayoutParameters& layoutParameters,
   const float textHorizontalOffset = CalculateXoffset( layoutParameters.mHorizontalAlignment, relayoutData.mTextViewSize.width, relayoutData.mTextSizeForRelayoutOption.width );
   const float textVerticalOffset = CalculateYoffset( layoutParameters.mVerticalAlignment, relayoutData.mTextViewSize.height, relayoutData.mTextSizeForRelayoutOption.height );
 
-  std::size_t lineJustificationIndex = 0u; // Index to the first position of the vector which stores all line justification info.
-  std::size_t infoTableCharacterIndex = 0u;
+  // Index to the global character (within the whole text).
+  std::size_t characterGlobalIndex = 0u;
+
+  // Index to the line info.
+  std::size_t lineLayoutInfoIndex = 0u;
 
   relayoutParameters.mIndices.mParagraphIndex = 0u;
 
@@ -527,10 +807,16 @@ void UpdateAlignment( const TextView::LayoutParameters& layoutParameters,
 
     float justificationOffset = 0.f;
 
+    const std::size_t lineLayoutInfoSize = relayoutData.mLines.size(); // Number of lines.
+    bool lineLayoutEnd = false;            // Whether lineLayoutInfoIndex points at the last line.
+
     relayoutParameters.mIndices.mWordIndex = 0u;
 
-    for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.begin(),
-           endWordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
+    const bool isRightToLeftLayout = NULL != paragraphLayoutInfo.mRightToLeftLayout;
+    TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo = isRightToLeftLayout ? paragraphLayoutInfo.mRightToLeftLayout->mWordsLayoutInfo : paragraphLayoutInfo.mWordsLayoutInfo;
+
+    for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = wordsLayoutInfo.begin(),
+           endWordLayoutIt = wordsLayoutInfo.end();
          wordLayoutIt != endWordLayoutIt;
          ++wordLayoutIt, ++relayoutParameters.mIndices.mWordIndex )
     {
@@ -541,19 +827,24 @@ void UpdateAlignment( const TextView::LayoutParameters& layoutParameters,
       for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
              endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
            characterLayoutIt != endCharacterLayoutIt;
-           ++characterLayoutIt, ++relayoutParameters.mIndices.mCharacterIndex, ++infoTableCharacterIndex )
+           ++characterLayoutIt, ++relayoutParameters.mIndices.mCharacterIndex, ++characterGlobalIndex )
       {
         TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
 
-        // Calculate line justification offset.
-        if( lineJustificationIndex < relayoutData.mLineJustificationInfo.size() )
+        // Check if there is a new line.
+        const bool newLine = !lineLayoutEnd && ( characterGlobalIndex == relayoutData.mLines[lineLayoutInfoIndex].mCharacterGlobalIndex );
+
+        if( newLine )
         {
-          const TextView::LineJustificationInfo lineJustificationInfo( *( relayoutData.mLineJustificationInfo.begin() + lineJustificationIndex ) );
+          // Calculate line justification offset.
+          justificationOffset = CalculateJustificationOffset( layoutParameters.mLineJustification, relayoutData.mTextSizeForRelayoutOption.width, relayoutData.mLines[lineLayoutInfoIndex].mSize.width );
 
-          if( relayoutParameters.mIndices == lineJustificationInfo.mIndices )
+          // Point to the next line.
+          ++lineLayoutInfoIndex;
+          if( lineLayoutInfoIndex >= lineLayoutInfoSize )
           {
-            justificationOffset = CalculateJustificationOffset( layoutParameters.mLineJustification, relayoutData.mTextSizeForRelayoutOption.width, lineJustificationInfo.mLineLength );
-            ++lineJustificationIndex; // increase the index to point the next position in the vector.
+            // Arrived at last line.
+            lineLayoutEnd = true; // Avoids access out of bounds in the relayoutData.mLines vector.
           }
         }
 
@@ -565,7 +856,7 @@ void UpdateAlignment( const TextView::LayoutParameters& layoutParameters,
         // Updates the size and position table for text-input with the alignment offset.
         Vector3 positionOffset( characterLayoutInfo.mPosition );
 
-        std::vector<Toolkit::TextView::CharacterLayoutInfo>::iterator infoTableIt = relayoutData.mCharacterLayoutInfoTable.begin() + infoTableCharacterIndex;
+        std::vector<Toolkit::TextView::CharacterLayoutInfo>::iterator infoTableIt = relayoutData.mCharacterLayoutInfoTable.begin() + characterGlobalIndex;
         Toolkit::TextView::CharacterLayoutInfo& characterTableInfo( *infoTableIt );
 
         characterTableInfo.mPosition.x = positionOffset.x + characterLayoutInfo.mOffset.x;
@@ -646,8 +937,8 @@ void UpdateLayoutInfoTable( Vector4& minMaxXY,
                                                                                characterLayoutInfo.mSize.height * relayoutData.mShrinkFactor ),
                                                                          positionOffset,
                                                                          ( TextViewProcessor::ParagraphSeparator == wordLayoutInfo.mType ),
-                                                                         false, // VCC set the correct direction if needed.
-                                                                         true,
+                                                                         characterLayoutInfo.mIsRightToLeft, // whether the character is right to left.
+                                                                         true,  // whether the character is visible.
                                                                          descender );
 
   relayoutData.mCharacterLayoutInfoTable.push_back( characterLayoutTableInfo );
@@ -657,6 +948,7 @@ void UpdateLayoutInfoTable( Vector4& minMaxXY,
 
 void CalculateVisibilityForFade( const Internal::TextView::LayoutParameters& layoutParameters,
                                  TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo,
+                                 const TextStyle& style,
                                  RelayoutParameters& relayoutParameters,
                                  FadeParameters& fadeParameters,
                                  TextView::RelayoutData& relayoutData )
@@ -813,35 +1105,40 @@ void CalculateVisibilityForFade( const Internal::TextView::LayoutParameters& lay
     Vector2 startPoint = Vector2::ZERO;
     Vector2 endPoint = Vector2::ZERO;
 
-    if( NULL == characterLayoutInfo.mGradientInfo )
-    {
-      characterLayoutInfo.mGradientInfo = new TextViewProcessor::GradientInfo();
-    }
-
     if( !( rightFadeOut && leftFadeOut ) )
     {
       // Current implementation can't set gradient parameters for a text-actor exceeding at the same time the left and the right boundaries.
       if( rightFadeOut )
       {
-        gradientColor = characterLayoutInfo.mStyledText.mStyle.GetTextColor();
+        gradientColor = style.GetTextColor();
 
         // Calculates gradient coeficients.
         characterLayoutInfo.mColorAlpha = gradientColor.a * std::min( 1.f, fadeParameters.mRightAlphaCoeficients.x * position.x + fadeParameters.mRightAlphaCoeficients.y );
         gradientColor.a *= std::max( 0.f, fadeParameters.mRightAlphaCoeficients.x * characterPositionPlusWidth + fadeParameters.mRightAlphaCoeficients.y );
 
-        startPoint = Vector2( std::max( 0.f, ( fadeParameters.mRightFadeThresholdOffset - position.x ) / size.width ), 0.5f );
-        endPoint = Vector2( std::min( 1.f, ( relayoutData.mTextViewSize.width - position.x ) / size.width ), 0.5f );
+        startPoint = Vector2( std::max( 0.f, std::min( 1.f, ( fadeParameters.mRightFadeThresholdOffset - position.x ) / size.width ) ), 0.5f );
+        endPoint = Vector2( std::min( 1.f, std::max( 0.f, ( relayoutData.mTextViewSize.width - position.x ) / size.width ) ), 0.5f );
+
+        if( NULL == characterLayoutInfo.mGradientInfo )
+        {
+          characterLayoutInfo.mGradientInfo = new TextViewProcessor::GradientInfo();
+        }
       }
       else if( leftFadeOut )
       {
-        gradientColor = characterLayoutInfo.mStyledText.mStyle.GetTextColor();
+        gradientColor = style.GetTextColor();
 
         // Calculates gradient coeficients.
         characterLayoutInfo.mColorAlpha = std::min( 1.f, fadeParameters.mLeftAlphaCoeficients.x * characterPositionPlusWidth + fadeParameters.mLeftAlphaCoeficients.y );
         gradientColor.a *= gradientColor.a * std::max( 0.f, fadeParameters.mLeftAlphaCoeficients.x * position.x + fadeParameters.mLeftAlphaCoeficients.y );
 
-        startPoint = Vector2( std::max( 0.f, ( fadeParameters.mLeftFadeThresholdOffset - position.x ) / size.width ), 0.5f );
-        endPoint = Vector2( std::min( 1.f, -position.x / size.width ), 0.5f );
+        startPoint = Vector2( std::max( 0.f, std::min( 1.f, ( fadeParameters.mLeftFadeThresholdOffset - position.x ) / size.width ) ), 0.5f );
+        endPoint = Vector2( std::min( 1.f, std::max( 0.f, -position.x / size.width ) ), 0.5f );
+
+        if( NULL == characterLayoutInfo.mGradientInfo )
+        {
+          characterLayoutInfo.mGradientInfo = new TextViewProcessor::GradientInfo();
+        }
       }
     }
 
@@ -850,31 +1147,44 @@ void CalculateVisibilityForFade( const Internal::TextView::LayoutParameters& lay
       // Current implementation can't set gradient parameters for a text-actor exceeding at the same time the top and the bottom boundaries.
       if( bottomFadeOut )
       {
-        gradientColor = characterLayoutInfo.mStyledText.mStyle.GetTextColor();
+        gradientColor = style.GetTextColor();
 
         // Calculates gradient coeficients.
         characterLayoutInfo.mColorAlpha = gradientColor.a * std::min( 1.f, fadeParameters.mBottomAlphaCoeficients.x * characterPositionMinusHeight + fadeParameters.mBottomAlphaCoeficients.y );
         gradientColor.a *= std::max( 0.f, fadeParameters.mBottomAlphaCoeficients.x * position.y + fadeParameters.mBottomAlphaCoeficients.y );
 
-        startPoint = Vector2( 0.5f, std::max( 0.f, ( fadeParameters.mBottomFadeThresholdOffset - characterPositionMinusHeight ) / size.height ) );
-        endPoint = Vector2( 0.5f, std::min( 1.f, ( relayoutData.mTextViewSize.height - characterPositionMinusHeight ) / size.height ) );
+        startPoint = Vector2( 0.5f, std::max( 0.f, std::min( 1.f, ( fadeParameters.mBottomFadeThresholdOffset - characterPositionMinusHeight ) / size.height ) ) );
+        endPoint = Vector2( 0.5f, std::min( 1.f, std::max( 0.f, ( relayoutData.mTextViewSize.height - characterPositionMinusHeight ) / size.height ) ) );
+
+        if( NULL == characterLayoutInfo.mGradientInfo )
+        {
+          characterLayoutInfo.mGradientInfo = new TextViewProcessor::GradientInfo();
+        }
       }
       else if( topFadeOut )
       {
-        gradientColor = characterLayoutInfo.mStyledText.mStyle.GetTextColor();
+        gradientColor = style.GetTextColor();
 
         // Calculates gradient coeficients.
         characterLayoutInfo.mColorAlpha *= gradientColor.a * std::min( 1.f, fadeParameters.mTopAlphaCoeficients.x * position.y + fadeParameters.mTopAlphaCoeficients.y );
         gradientColor.a *= std::max( 0.f, fadeParameters.mTopAlphaCoeficients.x * characterPositionMinusHeight + fadeParameters.mTopAlphaCoeficients.y );
 
-        startPoint = Vector2( 0.5f, std::max( 0.f, ( fadeParameters.mTopFadeThresholdOffset - characterPositionMinusHeight ) / size.height ) );
-        endPoint = Vector2( 0.5f, std::min( 1.f,  -characterPositionMinusHeight / size.height ) );
+        startPoint = Vector2( 0.5f, std::max( 0.f, std::min( 1.f, ( fadeParameters.mTopFadeThresholdOffset - characterPositionMinusHeight ) / size.height ) ) );
+        endPoint = Vector2( 0.5f, std::min( 1.f,  std::max( 0.f, -characterPositionMinusHeight / size.height ) ) );
+
+        if( NULL == characterLayoutInfo.mGradientInfo )
+        {
+          characterLayoutInfo.mGradientInfo = new TextViewProcessor::GradientInfo();
+        }
       }
     }
 
-    characterLayoutInfo.mGradientInfo->mGradientColor = gradientColor;
-    characterLayoutInfo.mGradientInfo->mStartPoint = startPoint;
-    characterLayoutInfo.mGradientInfo->mEndPoint = endPoint;
+    if( NULL != characterLayoutInfo.mGradientInfo )
+    {
+      characterLayoutInfo.mGradientInfo->mGradientColor = gradientColor;
+      characterLayoutInfo.mGradientInfo->mStartPoint = startPoint;
+      characterLayoutInfo.mGradientInfo->mEndPoint = endPoint;
+    }
   }
   else
   {
@@ -1034,16 +1344,18 @@ void CreateEllipsizeTextActor( const EllipsizeParameters& ellipsizeParameters,
   float bearingOffset = 0.f;
 
   // Create ellipsize text-actor.
+  std::size_t characterIndex = 0u;
   for( TextViewProcessor::CharacterLayoutInfoContainer::const_iterator ellipsizeCharacterLayoutIt = relayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo.mCharactersLayoutInfo.begin(),
          endEllipsizeCharacterLayoutIt = relayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo.mCharactersLayoutInfo.end();
        ellipsizeCharacterLayoutIt != endEllipsizeCharacterLayoutIt;
-       ++ellipsizeCharacterLayoutIt )
+       ++ellipsizeCharacterLayoutIt, ++characterIndex )
   {
     const TextViewProcessor::CharacterLayoutInfo& ellipsizeCharacterLayoutInfo( *ellipsizeCharacterLayoutIt );
+    const TextStyle& style = *( *( relayoutData.mTextLayoutInfo.mEllipsisTextStyles.Begin() + characterIndex ) );
 
     if( isColorGlyph ||
         ( isColorGlyph != ellipsizeCharacterLayoutInfo.mIsColorGlyph ) ||
-        ( ellipsizeStyle != ellipsizeCharacterLayoutInfo.mStyledText.mStyle ) )
+        ( ellipsizeStyle != style ) )
     {
       // The style is different, so a new text-actor is needed.
       if( !ellipsizeText.IsEmpty() )
@@ -1061,8 +1373,8 @@ void CreateEllipsizeTextActor( const EllipsizeParameters& ellipsizeParameters,
       }
 
       // Resets the current ellipsize info.
-      ellipsizeText = ellipsizeCharacterLayoutInfo.mStyledText.mText;
-      ellipsizeStyle = ellipsizeCharacterLayoutInfo.mStyledText.mStyle;
+      ellipsizeText = Text( relayoutData.mTextLayoutInfo.mEllipsisText[characterIndex] );
+      ellipsizeStyle = style;
       ellipsizeSize = ellipsizeCharacterLayoutInfo.mSize;
       isColorGlyph = ellipsizeCharacterLayoutInfo.mIsColorGlyph;
 
@@ -1071,7 +1383,7 @@ void CreateEllipsizeTextActor( const EllipsizeParameters& ellipsizeParameters,
     else
     {
       // Updates text and size with the new character.
-      ellipsizeText.Append( ellipsizeCharacterLayoutInfo.mStyledText.mText );
+      ellipsizeText.Append( relayoutData.mTextLayoutInfo.mEllipsisText[characterIndex] );
       TextViewProcessor::UpdateSize( ellipsizeSize, ellipsizeCharacterLayoutInfo.mSize );
     }
   }
@@ -1131,8 +1443,11 @@ void EllipsizeLine( const TextView::LayoutParameters& layoutParameters,
 
     std::size_t wordCount = 0u;
 
-    for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.begin() + firstIndices.mWordIndex,
-           endWordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.begin() + lastIndices.mWordIndex + 1u;
+    const bool isRightToLeftLayout = NULL != paragraphLayoutInfo.mRightToLeftLayout;
+    TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo = isRightToLeftLayout ? paragraphLayoutInfo.mRightToLeftLayout->mWordsLayoutInfo : paragraphLayoutInfo.mWordsLayoutInfo;
+
+    for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = wordsLayoutInfo.begin() + firstIndices.mWordIndex,
+           endWordLayoutIt = wordsLayoutInfo.begin() + lastIndices.mWordIndex + 1u;
          wordLayoutIt != endWordLayoutIt;
          ++wordLayoutIt, ++wordCount )
     {
@@ -1193,9 +1508,13 @@ void SetTextVisible( TextView::RelayoutData& relayoutData )
        ++paragraphLayoutIt )
   {
     TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphLayoutIt );
+    std::size_t characterIndex = 0u;
+
+    const bool isRightToLeftLayout = NULL != paragraphLayoutInfo.mRightToLeftLayout;
+    TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo = isRightToLeftLayout ? paragraphLayoutInfo.mRightToLeftLayout->mWordsLayoutInfo : paragraphLayoutInfo.mWordsLayoutInfo;
 
-    for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.begin(),
-           endWordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
+    for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = wordsLayoutInfo.begin(),
+           endWordLayoutIt = wordsLayoutInfo.end();
          wordLayoutIt != endWordLayoutIt;
          ++wordLayoutIt )
     {
@@ -1204,14 +1523,14 @@ void SetTextVisible( TextView::RelayoutData& relayoutData )
       for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
              endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
            characterLayoutIt != endCharacterLayoutIt;
-           ++characterLayoutIt )
+           ++characterLayoutIt, ++characterIndex )
       {
         TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
 
         characterLayoutInfo.mIsVisible = true;
         delete characterLayoutInfo.mGradientInfo;
         characterLayoutInfo.mGradientInfo = NULL;
-        characterLayoutInfo.mColorAlpha = characterLayoutInfo.mStyledText.mStyle.GetTextColor().a;
+        characterLayoutInfo.mColorAlpha = ( *( paragraphLayoutInfo.mTextStyles.Begin() + characterIndex ) )->GetTextColor().a;
       } // end characters
     } // end words
   } // end paragraphs
@@ -1272,10 +1591,14 @@ void UpdateVisibilityForFade( const TextView::LayoutParameters& layoutParameters
   {
     TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphLayoutIt );
 
+    std::size_t characterIndex = 0u;
     relayoutParameters.mIndices.mWordIndex = 0u;
 
-    for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.begin(),
-           endWordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
+    const bool isRightToLeftLayout = NULL != paragraphLayoutInfo.mRightToLeftLayout;
+    TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo = isRightToLeftLayout ? paragraphLayoutInfo.mRightToLeftLayout->mWordsLayoutInfo : paragraphLayoutInfo.mWordsLayoutInfo;
+
+    for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = wordsLayoutInfo.begin(),
+           endWordLayoutIt = wordsLayoutInfo.end();
          wordLayoutIt != endWordLayoutIt;
          ++wordLayoutIt, ++relayoutParameters.mIndices.mWordIndex )
     {
@@ -1288,7 +1611,7 @@ void UpdateVisibilityForFade( const TextView::LayoutParameters& layoutParameters
       for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
              endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
            characterLayoutIt != endCharacterLayoutIt;
-           ++characterLayoutIt, ++relayoutParameters.mIndices.mCharacterIndex, ++infoTableCharacterIndex )
+           ++characterLayoutIt, ++relayoutParameters.mIndices.mCharacterIndex, ++infoTableCharacterIndex, ++characterIndex )
       {
         TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
 
@@ -1298,6 +1621,7 @@ void UpdateVisibilityForFade( const TextView::LayoutParameters& layoutParameters
         // Calculates the visibility for the current character.
         CalculateVisibilityForFade( layoutParameters,
                                     characterLayoutInfo,
+                                    *( *( paragraphLayoutInfo.mTextStyles.Begin() + characterIndex ) ),
                                     relayoutParameters,
                                     fadeParameters,
                                     relayoutData );
@@ -1524,7 +1848,12 @@ void CreateTextActor( const TextView::VisualParameters& visualParameters,
   // Set the text-actor for the current traversed text.
   if( currentTextActorInfo.textActor )
   {
-    currentTextActorInfo.textActor.SetText( currentTextActorInfo.text );
+    if( ( NULL != currentTextActorInfo.characterLayout ) &&
+        currentTextActorInfo.characterLayout->mSetText )
+    {
+      currentTextActorInfo.textActor.SetText( currentTextActorInfo.text );
+      currentTextActorInfo.characterLayout->mSetText = false;
+    }
     currentTextActorInfo.textActor.SetPosition( currentTextActorInfo.position );
     currentTextActorInfo.textActor.SetSize( currentTextActorInfo.size );
 
@@ -1534,8 +1863,18 @@ void CreateTextActor( const TextView::VisualParameters& visualParameters,
                          paragraph.mSize.height );
   }
 
+  float rightToLeftOffset = 0.f;
+  if( character.IsWhiteSpace() )
+  {
+    // In left to right text, a word never starts with a white space but
+    // it may happen in right to left text as the text is reversed.
+    // The text alignment and justification offset is calculated without this white space.
+    // It causes a missalignment which can be corrected by removing the size of the white space.
+    rightToLeftOffset = characterLayout.mSize.width * relayoutData.mShrinkFactor;
+  }
+
   currentTextActorInfo.text = Text( character );
-  currentTextActorInfo.position = Vector3( characterLayout.mPosition.x + characterLayout.mOffset.x,
+  currentTextActorInfo.position = Vector3( characterLayout.mPosition.x + characterLayout.mOffset.x - rightToLeftOffset,
                                            characterLayout.mPosition.y + characterLayout.mOffset.y,
                                            characterLayout.mPosition.z );
   currentTextActorInfo.size = characterLayout.mSize * relayoutData.mShrinkFactor;
@@ -1543,8 +1882,6 @@ void CreateTextActor( const TextView::VisualParameters& visualParameters,
   currentTextActorInfo.color = style.GetTextColor();
   currentTextActorInfo.color.a = characterLayout.mColorAlpha;
 
-  currentTextActorInfo.gradientInfo = characterLayout.mGradientInfo;
-
   TextActor textActor = TextActor::DownCast( characterLayout.mGlyphActor );
 
   if( createGlyphActors )
@@ -1570,6 +1907,9 @@ void CreateTextActor( const TextView::VisualParameters& visualParameters,
         textActor.SetTextStyle( style );
       }
     }
+    characterLayout.mSetText = true;
+    currentTextActorInfo.characterLayout = &characterLayout;
+
     characterLayout.mGlyphActor = textActor;
   }
 
@@ -1589,12 +1929,13 @@ void CreateTextActor( const TextView::VisualParameters& visualParameters,
  */
 void UpdateTextActorInfoForParagraph( const TextView::VisualParameters& visualParameters,
                                       TextView::RelayoutData& relayoutData,
-                                      TextViewProcessor::ParagraphLayoutInfo& paragraph,
+                                      TextViewProcessor::ParagraphLayoutInfo& paragraphLayout,
                                       std::size_t& characterGlobalIndex,
                                       std::size_t& lineLayoutInfoIndex,
                                       bool createGlyphActors )
 {
   CurrentTextActorInfo currentTextActorInfo;
+  currentTextActorInfo.characterLayout = NULL;
 
   const std::size_t lineLayoutInfoSize = relayoutData.mLines.size(); // Number of lines.
   bool lineLayoutEnd = false;            // Whether lineLayoutInfoIndex points at the last line.
@@ -1610,14 +1951,24 @@ void UpdateTextActorInfoForParagraph( const TextView::VisualParameters& visualPa
 
   std::vector<TextActor> textActorsToRemove; // Keep a vector of text-actors to be included into the cache.
 
+  // Retrieve the layout info to traverse. If there is right to left text it retrieves the right to left layout.
+  const bool isRightToLeftLayout = NULL != paragraphLayout.mRightToLeftLayout;
+
+  TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo = isRightToLeftLayout ? paragraphLayout.mRightToLeftLayout->mWordsLayoutInfo : paragraphLayout.mWordsLayoutInfo;
+  Text& text = isRightToLeftLayout ? paragraphLayout.mRightToLeftLayout->mText : paragraphLayout.mText;
+  Vector<TextStyle*>& textStyles = isRightToLeftLayout ? paragraphLayout.mRightToLeftLayout->mTextStyles : paragraphLayout.mTextStyles;
+
+  // In case the previous right to left layout has been cleared, all text-actors have been removed as well. If this bool is set to true, text-actors will be created again.
+  const bool previousRightToLeftLayoutCleared = isRightToLeftLayout ? paragraphLayout.mRightToLeftLayout->mPreviousLayoutCleared : false;
+
   std::size_t characterParagraphIndex = 0u;   // Index to the character (within the paragraph).
-  for( TextViewProcessor::WordLayoutInfoContainer::iterator wordIt = paragraph.mWordsLayoutInfo.begin(), wordEndIt = paragraph.mWordsLayoutInfo.end();
+  for( TextViewProcessor::WordLayoutInfoContainer::iterator wordIt = wordsLayoutInfo.begin(), wordEndIt = wordsLayoutInfo.end();
        wordIt != wordEndIt;
        ++wordIt )
   {
-    TextViewProcessor::WordLayoutInfo& word( *wordIt );
+    TextViewProcessor::WordLayoutInfo& wordLayout( *wordIt );
 
-    for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterIt = word.mCharactersLayoutInfo.begin(), characterEndIt = word.mCharactersLayoutInfo.end();
+    for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterIt = wordLayout.mCharactersLayoutInfo.begin(), characterEndIt = wordLayout.mCharactersLayoutInfo.end();
          characterIt != characterEndIt;
          ++characterIt )
     {
@@ -1639,14 +1990,14 @@ void UpdateTextActorInfoForParagraph( const TextView::VisualParameters& visualPa
       }
 
       // Do not create a glyph-actor if there is no text.
-      const Character character = characterLayout.mStyledText.mText[0u]; // there are only one character per character layout.
-      const TextStyle& style = characterLayout.mStyledText.mStyle;
+      const Character character = text[characterParagraphIndex];
+      const TextStyle& style = *( *( textStyles.Begin() + characterParagraphIndex ) );
 
       bool appendCharacter = false;
 
       if( characterLayout.mIsColorGlyph ||
-          !character.IsWhiteSpace() || // A new paragraph character is also a white space.
-          ( character.IsWhiteSpace() && style.IsUnderlineEnabled() ) )
+          ( TextViewProcessor::NoSeparator == wordLayout.mType ) ||
+          ( ( TextViewProcessor::WordSeparator == wordLayout.mType ) && style.IsUnderlineEnabled() ) )
       {
         // Do not create a glyph-actor if it's a white space (without underline) or a new paragraph character.
 
@@ -1673,9 +2024,6 @@ void UpdateTextActorInfoForParagraph( const TextView::VisualParameters& visualPa
           characterLayout.mSetText = false;
           characterLayout.mSetStyle = false;
 
-          // There is a new style or a new line.
-          glyphActorCreatedForLine = true;
-
           if( characterLayout.mIsColorGlyph )
           {
             CreateEmoticon( visualParameters,
@@ -1686,14 +2034,17 @@ void UpdateTextActorInfoForParagraph( const TextView::VisualParameters& visualPa
           {
             CreateTextActor( visualParameters,
                              relayoutData,
-                             paragraph,
+                             paragraphLayout,
                              characterLayout,
                              character,
                              style,
                              currentTextActorInfo,
-                             createGlyphActors );
+                             createGlyphActors || previousRightToLeftLayoutCleared );
           }
 
+          // There is a new style or a new line.
+          glyphActorCreatedForLine = true;
+
           // Update style to be checked with next characters.
           currentStyle = style;
           currentGradientInfo = characterLayout.mGradientInfo;
@@ -1734,7 +2085,7 @@ void UpdateTextActorInfoForParagraph( const TextView::VisualParameters& visualPa
       if( appendCharacter )
       {
         // Add the character to the current text-actor and update the size.
-        if( characterLayout.mIsVisible && ( TextViewProcessor::ParagraphSeparator != word.mType ) )
+        if( characterLayout.mIsVisible && ( TextViewProcessor::ParagraphSeparator != wordLayout.mType ) )
         {
           currentTextActorInfo.text.Append( character );
 
@@ -1753,14 +2104,19 @@ void UpdateTextActorInfoForParagraph( const TextView::VisualParameters& visualPa
   {
     if( currentTextActorInfo.textActor )
     {
-      currentTextActorInfo.textActor.SetText( currentTextActorInfo.text );
+      if( ( NULL != currentTextActorInfo.characterLayout ) &&
+          currentTextActorInfo.characterLayout->mSetText )
+      {
+        currentTextActorInfo.textActor.SetText( currentTextActorInfo.text );
+        currentTextActorInfo.characterLayout->mSetText = false;
+      }
       currentTextActorInfo.textActor.SetPosition( currentTextActorInfo.position );
       currentTextActorInfo.textActor.SetSize( currentTextActorInfo.size );
 
       SetVisualParameters( currentTextActorInfo,
                            visualParameters,
                            relayoutData,
-                           paragraph.mSize.height );
+                           paragraphLayout.mSize.height );
     }
   }
 
@@ -1827,7 +2183,12 @@ void CalculateUnderlineInfo( TextView::RelayoutData& relayoutData, TextViewRelay
   {
     TextViewProcessor::ParagraphLayoutInfo& paragraph( *paragraphIt );
 
-    for( TextViewProcessor::WordLayoutInfoContainer::iterator wordIt = paragraph.mWordsLayoutInfo.begin(), wordEndIt = paragraph.mWordsLayoutInfo.end();
+    std::size_t characterIndex = 0u;
+
+    const bool isRightToLeftLayout = NULL != paragraph.mRightToLeftLayout;
+    TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo = isRightToLeftLayout ? paragraph.mRightToLeftLayout->mWordsLayoutInfo : paragraph.mWordsLayoutInfo;
+
+    for( TextViewProcessor::WordLayoutInfoContainer::iterator wordIt = wordsLayoutInfo.begin(), wordEndIt = wordsLayoutInfo.end();
          wordIt != wordEndIt;
          ++wordIt )
     {
@@ -1835,9 +2196,10 @@ void CalculateUnderlineInfo( TextView::RelayoutData& relayoutData, TextViewRelay
 
       for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterIt = word.mCharactersLayoutInfo.begin(), characterEndIt = word.mCharactersLayoutInfo.end();
            characterIt != characterEndIt;
-           ++characterIt )
+           ++characterIt, ++characterIndex )
       {
         TextViewProcessor::CharacterLayoutInfo& character( *characterIt );
+        const TextStyle& style = *( *( paragraph.mTextStyles.Begin() + characterIndex ) );
 
         // Check if current character is the first of a new line
         const bool isNewLine = ( textUnderlineStatus.mLineGlobalIndex < relayoutData.mLines.size() ) &&
@@ -1847,7 +2209,7 @@ void CalculateUnderlineInfo( TextView::RelayoutData& relayoutData, TextViewRelay
           ++textUnderlineStatus.mLineGlobalIndex; // If it's a new line, point to the next one.
         }
 
-        if( character.mStyledText.mStyle.IsUnderlineEnabled() )
+        if( style.IsUnderlineEnabled() )
         {
           if( !textUnderlineStatus.mCurrentUnderlineStatus || // Current character is underlined but previous one it wasn't.
               isNewLine )                                     // Current character is underlined and is the first of current line.
@@ -1927,8 +2289,12 @@ void SetUnderlineInfo( TextView::RelayoutData& relayoutData )
        ++paragraphIt )
   {
     TextViewProcessor::ParagraphLayoutInfo& paragraph( *paragraphIt );
+    std::size_t characterIndex = 0u;
+
+    const bool isRightToLeftLayout = NULL != paragraph.mRightToLeftLayout;
+    TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo = isRightToLeftLayout ? paragraph.mRightToLeftLayout->mWordsLayoutInfo : paragraph.mWordsLayoutInfo;
 
-    for( TextViewProcessor::WordLayoutInfoContainer::iterator wordIt = paragraph.mWordsLayoutInfo.begin(), wordEndIt = paragraph.mWordsLayoutInfo.end();
+    for( TextViewProcessor::WordLayoutInfoContainer::iterator wordIt = wordsLayoutInfo.begin(), wordEndIt = wordsLayoutInfo.end();
          wordIt != wordEndIt;
          ++wordIt )
     {
@@ -1936,9 +2302,10 @@ void SetUnderlineInfo( TextView::RelayoutData& relayoutData )
 
       for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterIt = word.mCharactersLayoutInfo.begin(), characterEndIt = word.mCharactersLayoutInfo.end();
            characterIt != characterEndIt;
-           ++characterIt )
+           ++characterIt, ++characterIndex )
       {
         TextViewProcessor::CharacterLayoutInfo& character( *characterIt );
+        TextStyle& style = *( *( paragraph.mTextStyles.Begin() + characterIndex ) );
 
         // Check if current character is the first of a new line
 
@@ -1957,7 +2324,7 @@ void SetUnderlineInfo( TextView::RelayoutData& relayoutData )
           }
         }
 
-        if( character.mStyledText.mStyle.IsUnderlineEnabled() )
+        if( style.IsUnderlineEnabled() )
         {
           if( textUnderlineStatus.mCurrentUnderlineStatus )
           {
@@ -1982,7 +2349,7 @@ void SetUnderlineInfo( TextView::RelayoutData& relayoutData )
           const float positionOffset = ( underlineInfo.mMaxHeight - character.mSize.height ) - bearingOffset;
 
           // Sets the underline's parameters.
-          character.mStyledText.mStyle.SetUnderline( true, underlineInfo.mMaxThickness, underlineInfo.mPosition - positionOffset );
+          style.SetUnderline( true, underlineInfo.mMaxThickness, underlineInfo.mPosition - positionOffset );
 
           // Mark the character to be set the new style into the text-actor.
           character.mSetStyle = true;
@@ -2038,8 +2405,12 @@ void InsertToTextView( Actor textView,
   {
     TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphLayoutIt );
 
-    for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.begin(),
-           endWordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
+    // Retrieve the layout info to traverse. If there is right to left text it retrieves the right to left layout.
+    const bool isRightToLeftLayout = NULL != paragraphLayoutInfo.mRightToLeftLayout;
+    TextViewProcessor::WordLayoutInfoContainer& wordsLayoutInfo = isRightToLeftLayout ? paragraphLayoutInfo.mRightToLeftLayout->mWordsLayoutInfo : paragraphLayoutInfo.mWordsLayoutInfo;
+
+    for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = wordsLayoutInfo.begin(),
+           endWordLayoutIt = wordsLayoutInfo.end();
          wordLayoutIt != endWordLayoutIt;
          ++wordLayoutIt )
     {
index aff3ae3..5150186 100644 (file)
@@ -19,8 +19,9 @@
  */
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/alignment/alignment.h>
+#include <dali-toolkit/public-api/controls/text-view/text-view.h>
 #include <dali-toolkit/internal/controls/text-view/text-view-impl.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-types.h>
 
 namespace Dali
 {
@@ -265,6 +266,13 @@ void CalculateLineLayout( float parentWidth,
                           LineLayoutInfo& layoutInfo );
 
 /**
+ * Reorders the text layout of each line of each paragraph of the text.
+ *
+ * @param[in,out] relayoutData The text-view's data structures.
+ */
+void ReorderRightToLeftLayout( TextView::RelayoutData& relayoutData );
+
+/**
  * Calculates the \e x offset position for the whole text.
  *
  * @param[in] horizontalTextAlignment The horizontal alignment type.
@@ -358,12 +366,14 @@ void UpdateLayoutInfoTable( Vector4& minMaxXY,
  *
  * @param[in] layoutParameters The layout parameters.
  * @param[in] characterLayoutInfo Character layout info.
+ * @param[in] style The style of the character. Used to get the color (and alpha) of the character.
  * @param[in,out] relayoutParameters Temporary layout parameters.
  * @param[in,out] fadeParameters Temporary fade parameters.
  * @param[in,out] relayoutData The text-view's data structures.
  */
 void CalculateVisibilityForFade( const Internal::TextView::LayoutParameters& layoutParameters,
                                  TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo,
+                                 const TextStyle& style,
                                  RelayoutParameters& relayoutParameters,
                                  FadeParameters& fadeParameters,
                                  TextView::RelayoutData& relayoutData );
@@ -391,7 +401,11 @@ void CreateEllipsizeTextActor( const EllipsizeParameters& ellipsizeParameters,
                                TextView::RelayoutData& relayoutData );
 
 /**
+ * Replace the text which exceeds the boundary by the ellipsis text.
  *
+ * @param[in] layoutParameters The layout parameters.
+ * @param[in,out] ellipsisParameters Temporary ellipsis parameters.
+ * @param[in,out] relayoutData The text-view's data structures.
  */
 void EllipsizeLine( const TextView::LayoutParameters& layoutParameters,
                     EllipsizeParameters& ellipsizeParameters,
index 10933a7..613b0a6 100644 (file)
@@ -72,14 +72,6 @@ Vector3 NoShrinkWhenExceedPosition( const TextViewRelayout::RelayoutParameters&
                                              1.f, // Shrink factor
                                              subLineInfo );
 
-      // Stores some info to calculate the line justification in a post-process.
-      TextView::LineJustificationInfo justificationInfo;
-
-      justificationInfo.mIndices = relayoutParameters.mIndices;
-      justificationInfo.mLineLength = subLineInfo.mLineLength;
-
-      relayoutData.mLineJustificationInfo.push_back( justificationInfo );
-
       Toolkit::TextView::LineLayoutInfo lineInfo;
       lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex;    // Index to the first character of the next line.
       lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
@@ -234,10 +226,11 @@ void Relayout( Actor textView,
 {
   if( relayoutOperationMask & TextView::RELAYOUT_SIZE_POSITION )
   {
-    relayoutData.mLineJustificationInfo.clear();
     CalculateSizeAndPosition( layoutParameters,
                               relayoutData );
 
+    TextViewRelayout::ReorderRightToLeftLayout( relayoutData );
+
     TextViewRelayout::SetUnderlineInfo( relayoutData );
   }
 
index 98ee6b8..f74966d 100644 (file)
@@ -71,14 +71,6 @@ Vector3 SplitPosition( const TextViewRelayout::RelayoutParameters& relayoutParam
                                              1.f, // Shrink factor
                                              subLineInfo );
 
-      // Stores some info to calculate the line justification in a post-process.
-      TextView::LineJustificationInfo justificationInfo;
-
-      justificationInfo.mIndices = relayoutParameters.mIndices;
-      justificationInfo.mLineLength = subLineInfo.mLineLength;
-
-      relayoutData.mLineJustificationInfo.push_back( justificationInfo );
-
       Toolkit::TextView::LineLayoutInfo lineInfo;
       lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex;    // Index to the first character of the next line.
       lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
@@ -158,22 +150,6 @@ void CalculateSizeAndPosition( const TextView::LayoutParameters& layoutParameter
       relayoutParameters.mWordSize = wordLayoutInfo.mSize;
       relayoutParameters.mIndices.mCharacterIndex = 0u;
 
-      if( relayoutParameters.mIsNewLine )
-      {
-        // Stores some info to calculate the line justification in a post-process.
-        const bool isSplitOriginal = layoutParameters.mExceedPolicy == TextView::SplitOriginal;
-
-        if( !isSplitOriginal )
-        {
-          TextView::LineJustificationInfo justificationInfo;
-
-          justificationInfo.mIndices = relayoutParameters.mIndices;
-          justificationInfo.mLineLength = relayoutParameters.mParagraphSize.width;
-
-          relayoutData.mLineJustificationInfo.push_back( justificationInfo );
-        }
-      }
-
       for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
              endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
            characterLayoutIt != endCharacterLayoutIt;
@@ -290,10 +266,11 @@ void Relayout( Actor textView,
 {
   if( relayoutOperationMask & TextView::RELAYOUT_SIZE_POSITION )
   {
-    relayoutData.mLineJustificationInfo.clear();
     CalculateSizeAndPosition( layoutParameters,
                               relayoutData );
 
+    TextViewRelayout::ReorderRightToLeftLayout( relayoutData );
+
     TextViewRelayout::SetUnderlineInfo( relayoutData );
   }
 
index 4081150..b5bd9f6 100644 (file)
@@ -83,14 +83,6 @@ Vector3 OriginalPosition( const TextViewRelayout::RelayoutParameters& relayoutPa
         }
       }
 
-      // Stores some info to calculate the line justification in a post-process.
-      TextView::LineJustificationInfo justificationInfo;
-
-      justificationInfo.mIndices = relayoutParameters.mIndices;
-      justificationInfo.mLineLength = subLineInfo.mLineLength;
-
-      relayoutData.mLineJustificationInfo.push_back( justificationInfo );
-
       Toolkit::TextView::LineLayoutInfo lineInfo;
       lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex;    // Index to the first character of the next line.
       lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
@@ -147,14 +139,6 @@ Vector3 SplitWhenExceedPosition( const TextViewRelayout::RelayoutParameters& rel
                                              1.f, // Shrink factor.
                                              subLineInfo );
 
-      // Stores some info to calculate the line justification in a post-process.
-      TextView::LineJustificationInfo justificationInfo;
-
-      justificationInfo.mIndices = relayoutParameters.mIndices;
-      justificationInfo.mLineLength = subLineInfo.mLineLength;
-
-      relayoutData.mLineJustificationInfo.push_back( justificationInfo );
-
       Toolkit::TextView::LineLayoutInfo lineInfo;
       lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex;    // Index to the first character of the next line.
       lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
@@ -211,14 +195,6 @@ Vector3 ShrinkWidthWhenExceedPosition( const TextViewRelayout::RelayoutParameter
                                              relayoutData.mShrinkFactor,
                                              subLineInfo );
 
-      // Stores some info to calculate the line justification in a post-process.
-      TextView::LineJustificationInfo justificationInfo;
-
-      justificationInfo.mIndices = relayoutParameters.mIndices;
-      justificationInfo.mLineLength = subLineInfo.mLineLength;
-
-      relayoutData.mLineJustificationInfo.push_back( justificationInfo );
-
       Toolkit::TextView::LineLayoutInfo lineInfo;
       lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex;    // Index to the first character of the next line.
       lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
@@ -242,8 +218,6 @@ void CalculatePositionsForShrinkWhenExceed( TextView::RelayoutData& relayoutData
   const float parentWidth = relayoutData.mTextViewSize.width;
   TextViewProcessor::TextLayoutInfo& textLayoutInfo = relayoutData.mTextLayoutInfo;
 
-  relayoutData.mLineJustificationInfo.clear();
-
   // Reset the text height. This value is returned in order to shrink further or not the text.
   newTextHeight = 0.f;
 
@@ -332,14 +306,6 @@ void CalculatePositionsForShrinkWhenExceed( TextView::RelayoutData& relayoutData
           lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
           lineInfo.mAscender = subLineInfo.mMaxAscender;                                // Ascender of this piece of paragraph.
           relayoutData.mLines.push_back( lineInfo );
-
-          // Stores some info to calculate the line justification in a post-process.
-          TextView::LineJustificationInfo justificationInfo;
-
-          justificationInfo.mIndices = indices;
-          justificationInfo.mLineLength = subLineInfo.mLineLength;
-
-          relayoutData.mLineJustificationInfo.push_back( justificationInfo );
         }
         else
         {
@@ -618,10 +584,11 @@ void Relayout( Actor textView,
 {
   if( relayoutOperationMask & TextView::RELAYOUT_SIZE_POSITION )
   {
-    relayoutData.mLineJustificationInfo.clear();
     CalculateSizeAndPosition( layoutParameters,
                               relayoutData );
 
+    TextViewRelayout::ReorderRightToLeftLayout( relayoutData );
+
     TextViewRelayout::SetUnderlineInfo( relayoutData );
   }
 
diff --git a/base/dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.cpp b/base/dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.cpp
new file mode 100644 (file)
index 0000000..8131b47
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2014 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/controls/text-view/text-processor-bidirectional-info.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace TextProcessor
+{
+
+BidirectionalParagraphInfo::BidirectionalParagraphInfo()
+: mDirection( FRIBIDI_TYPE_ON ),
+  mCharactersTypeBuffer(),
+  mLevelsBuffer(),
+  mLogicalUnicodeBuffer()
+{
+}
+
+BidirectionalParagraphInfo::~BidirectionalParagraphInfo()
+{
+}
+
+BidirectionalParagraphInfo::BidirectionalParagraphInfo( const BidirectionalParagraphInfo& info )
+: mDirection( info.mDirection ),
+  mCharactersTypeBuffer( info.mCharactersTypeBuffer ),
+  mLevelsBuffer( info.mLevelsBuffer ),
+  mLogicalUnicodeBuffer( info.mLogicalUnicodeBuffer )
+{
+}
+
+BidirectionalParagraphInfo& BidirectionalParagraphInfo::operator=( const BidirectionalParagraphInfo& info )
+{
+  if( this != &info )
+  {
+    mDirection = info.mDirection;
+    mCharactersTypeBuffer = info.mCharactersTypeBuffer;
+    mLevelsBuffer = info.mLevelsBuffer;
+    mLogicalUnicodeBuffer = info.mLogicalUnicodeBuffer;
+  }
+
+  return *this;
+}
+
+BidirectionalLineInfo::BidirectionalLineInfo()
+: mCharacterParagraphIndex(),
+  mNumberOfCharacters(),
+  mText(),
+  mVisualToLogicalMap(),
+  mLogicalToVisualMap()
+{
+}
+
+BidirectionalLineInfo::~BidirectionalLineInfo()
+{
+}
+
+BidirectionalLineInfo::BidirectionalLineInfo( const BidirectionalLineInfo& info )
+: mCharacterParagraphIndex( info.mCharacterParagraphIndex ),
+  mNumberOfCharacters( info.mNumberOfCharacters ),
+  mText( info.mText ),
+  mVisualToLogicalMap( info.mVisualToLogicalMap ),
+  mLogicalToVisualMap( info.mLogicalToVisualMap )
+{
+}
+
+BidirectionalLineInfo& BidirectionalLineInfo::operator=( const BidirectionalLineInfo& info )
+{
+  if( this != &info )
+  {
+    mCharacterParagraphIndex = info.mCharacterParagraphIndex;
+    mNumberOfCharacters = info.mNumberOfCharacters;
+    mText = info.mText;
+    mVisualToLogicalMap = info.mVisualToLogicalMap;
+    mLogicalToVisualMap = info.mLogicalToVisualMap;
+  }
+
+  return *this;
+}
+
+bool BeginsRightToLeftCharacter( const Text& text )
+{
+  for( size_t i = 0u, length = text.GetLength(); i < length; ++i )
+  {
+    Character::CharacterDirection direction = text[i].GetCharacterDirection();
+    if( direction != Character::Neutral )
+    {
+      return ( direction == Character::RightToLeft || direction == Character::RightToLeftWeak );
+    }
+  }
+
+  return false;
+}
+
+bool ContainsRightToLeftCharacter( const Dali::Text& text )
+{
+  for( size_t i = 0u, length = text.GetLength(); i < length; ++i )
+  {
+    Character::CharacterDirection direction = ( text[i] ).GetCharacterDirection();
+    if( ( Character::RightToLeft == direction ) || ( Character::RightToLeftWeak == direction ) )
+    {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void ProcessBidirectionalText( Text& paragraph, BidirectionalParagraphInfo* info )
+{
+  if( paragraph.IsEmpty() )
+  {
+    // nothing to do if the paragraph is empty.
+    return;
+  }
+
+  const std::size_t stringSize = paragraph.GetText().size();
+
+  // Text buffer in logical order. Coded in unicode.
+  info->mLogicalUnicodeBuffer.resize( stringSize + 1u, 0u );
+  FriBidiChar* logicalUnicodeBufferPointer = &info->mLogicalUnicodeBuffer[0u];
+
+  // Converts from utf8 to unicode.
+  const std::size_t length = fribidi_charset_to_unicode( FRIBIDI_CHAR_SET_UTF8, paragraph.GetText().c_str(), stringSize, logicalUnicodeBufferPointer );
+
+  // Character type buffer.
+  info->mCharactersTypeBuffer.resize( length, 0u );
+
+  // Levels buffer.
+  info->mLevelsBuffer.resize( length, 0u );
+
+  // Joining type buffer.
+  std::vector<FriBidiJoiningType> joiningTypeBuffer;
+  joiningTypeBuffer.resize( length, 0u );
+
+  // Pointers to the buffers.
+  FriBidiCharType* charactersTypeBufferPointer = &info->mCharactersTypeBuffer[0u];
+  FriBidiLevel* levelsBufferPointer = &info->mLevelsBuffer[0u];
+  FriBidiJoiningType* joiningTypeBufferPointer = &joiningTypeBuffer[0u];
+
+  // Retrieves the type of each character.
+  fribidi_get_bidi_types( logicalUnicodeBufferPointer, length, charactersTypeBufferPointer );
+
+  // Retrieves the paragraph direction.
+  info->mDirection = fribidi_get_par_direction( charactersTypeBufferPointer, length );
+
+  // Retrieve the embedding levels.
+  fribidi_get_par_embedding_levels( charactersTypeBufferPointer, length, &info->mDirection, levelsBufferPointer );
+
+  // Retrieve the joining types.
+  fribidi_get_joining_types( logicalUnicodeBufferPointer, length, joiningTypeBufferPointer );
+
+  fribidi_join_arabic( charactersTypeBufferPointer, length, levelsBufferPointer, joiningTypeBufferPointer );
+
+  const FriBidiFlags flags = FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC;
+
+  fribidi_shape( flags, levelsBufferPointer, length, joiningTypeBufferPointer, logicalUnicodeBufferPointer );
+
+  std::vector<char> bidiTextConverted;
+
+  bidiTextConverted.resize( length * 4u + 1u ); // Maximum bytes to represent one UTF-8 character is 6.
+                                                // Currently Dali doesn't support this UTF-8 extension. Dali only supports 'regular' UTF-8 which has a maximum of 4 bytes per character.
+
+  fribidi_unicode_to_charset( FRIBIDI_CHAR_SET_UTF8, logicalUnicodeBufferPointer, length, &bidiTextConverted[0] );
+
+  paragraph = Text( &bidiTextConverted[0u] );
+}
+
+void ReorderLine( BidirectionalParagraphInfo* paragraphInfo,
+                  BidirectionalLineInfo* lineInfo )
+{
+  const FriBidiFlags flags = FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC;
+
+  lineInfo->mVisualToLogicalMap.Resize( lineInfo->mNumberOfCharacters, 0u );
+  lineInfo->mLogicalToVisualMap.Resize( lineInfo->mNumberOfCharacters, 0u );
+
+  std::vector<FriBidiChar> visualUnicodeBuffer;
+  visualUnicodeBuffer.insert( visualUnicodeBuffer.end(),
+                              paragraphInfo->mLogicalUnicodeBuffer.begin() + lineInfo->mCharacterParagraphIndex,
+                              paragraphInfo->mLogicalUnicodeBuffer.begin() + ( lineInfo->mCharacterParagraphIndex + lineInfo->mNumberOfCharacters ) );
+
+  // Pointers to the buffers.
+  FriBidiCharType* charactersTypeBufferPointer = &paragraphInfo->mCharactersTypeBuffer[lineInfo->mCharacterParagraphIndex];
+  FriBidiLevel* levelsBufferPointer = &paragraphInfo->mLevelsBuffer[lineInfo->mCharacterParagraphIndex];
+  FriBidiChar* visualUnicodeBufferPointer = &visualUnicodeBuffer[0u];
+  FriBidiStrIndex* visualToLogicalMapPointer = &lineInfo->mVisualToLogicalMap[0u];
+
+  // Initialize the visual to logical mapping table to the identity. Otherwise fribidi_reorder_line fails to retrieve a valid mapping table.
+  for( std::size_t index = 0u; index < lineInfo->mNumberOfCharacters; ++index )
+  {
+    lineInfo->mVisualToLogicalMap[ index ] = index;
+  }
+
+  fribidi_reorder_line( flags,
+                        charactersTypeBufferPointer,
+                        lineInfo->mNumberOfCharacters,
+                        0u,
+                        paragraphInfo->mDirection,
+                        levelsBufferPointer,
+                        visualUnicodeBufferPointer,
+                        visualToLogicalMapPointer );
+
+  // Fill the logical to visual mapping table.
+  for( std::size_t index = 0u; index < lineInfo->mNumberOfCharacters; ++index )
+  {
+    lineInfo->mLogicalToVisualMap[ lineInfo->mVisualToLogicalMap[ index ] ] = index;
+  }
+
+  std::vector<char> bidiTextConverted;
+
+  bidiTextConverted.resize( lineInfo->mNumberOfCharacters * 4u + 1u ); // Maximum bytes to represent one UTF-8 character is 6.
+                                                                       // Currently Dali doesn't support this UTF-8 extension.
+                                                                       // Dali only supports 'regular' UTF-8 which has a maximum of 4 bytes per character.
+
+  fribidi_unicode_to_charset( FRIBIDI_CHAR_SET_UTF8, visualUnicodeBufferPointer, lineInfo->mNumberOfCharacters, &bidiTextConverted[0u] );
+
+  lineInfo->mText = Text( &bidiTextConverted[0u] );
+}
+
+} // namespace TextProcessor
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/base/dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.h b/base/dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.h
new file mode 100644 (file)
index 0000000..77d6ee9
--- /dev/null
@@ -0,0 +1,157 @@
+#ifndef __DALI_TOOLKIT_TEXT_PROCESSOR_BIDIRECTIONAL_INFO_H__
+#define __DALI_TOOLKIT_TEXT_PROCESSOR_BIDIRECTIONAL_INFO_H__
+
+/*
+ * Copyright (c) 2014 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/text/text.h>
+
+// EXTERNAL INCLUDES
+#include <fribidi/fribidi.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace TextProcessor
+{
+
+/**
+ * Stores the text containing right to left characters and info for each character needed by fribidi to reorder a line.
+ */
+struct BidirectionalParagraphInfo
+{
+  /**
+   * Default constructor.
+   *
+   * Initializes all members to their default values.
+   */
+  BidirectionalParagraphInfo();
+
+  /**
+   * Default destructor.
+   */
+  ~BidirectionalParagraphInfo();
+
+  /**
+   * Copy constructor.
+   */
+  BidirectionalParagraphInfo( const BidirectionalParagraphInfo& info );
+
+  /**
+   * Assignment operator.
+   */
+  BidirectionalParagraphInfo& operator=( const BidirectionalParagraphInfo& info );
+
+  FriBidiParType               mDirection;            ///< The paragraph direction.
+  std::vector<FriBidiCharType> mCharactersTypeBuffer; ///< Character type buffer.
+  std::vector<FriBidiLevel>    mLevelsBuffer;         ///< Levels buffer.
+  std::vector<FriBidiChar>     mLogicalUnicodeBuffer; ///< Text buffer in logical order. Coded in unicode.
+};
+
+/**
+ * Stores the reordered text, the conversion tables for a paragraph's line,
+ * the index to the first character of the line and the number of characters.
+ */
+struct BidirectionalLineInfo
+{
+  /**
+   * Default constructor.
+   *
+   * Initializes all members to their default values.
+   */
+  BidirectionalLineInfo();
+
+  /**
+   * Default destructor.
+   */
+  ~BidirectionalLineInfo();
+
+  /**
+   * Copy constructor.
+   */
+  BidirectionalLineInfo( const BidirectionalLineInfo& info );
+
+  /**
+   * Assignment operator.
+   */
+  BidirectionalLineInfo& operator=( const BidirectionalLineInfo& info );
+
+  std::size_t mCharacterParagraphIndex; ///< Index within the paragraph of the first character of the line.
+  std::size_t mNumberOfCharacters;      ///< Number of characters of the line.
+  Text        mText;                    ///< Text in visual order.
+  Vector<int> mVisualToLogicalMap;      ///< The character position map from the visual output text to the logical input text.
+  Vector<int> mLogicalToVisualMap;      ///< The character position map from the logical input text to the visual output text.
+};
+
+/**
+ * Whether the text begins with right-to-left (bidirectional) character.
+ * @param [in] text The given text.
+ * @return \e true if the text begins right-to-left character.
+ */
+bool BeginsRightToLeftCharacter( const Text& text );
+
+/**
+ * Whether the text contains any right-to-left (bidirectional) character.
+ * @param [in] text The given text.
+ * @return \e true if the text contains right-to-left character.
+ */
+bool ContainsRightToLeftCharacter( const Text& text );
+
+/**
+ * Processes a bidirectional paragraph's text.
+ *
+ * It stores the paragraph's direction (the direction of the first non neutral character),
+ * the direction of all characters, and the ligatures in case of arabic glyphs.
+ *
+ * It doesn't reorder the paragraph as this task must be done per line.
+ * The stored info is needed to reorder each line of the paragraph.
+ *
+ * @param[in] paragraph The paragraph to be processed.
+ * @param[out] info Struct containing the needed info to reorder each line of the paragraph.
+ */
+void ProcessBidirectionalText( Text& paragraph,
+                               BidirectionalParagraphInfo* info );
+
+/**
+ * Reorders one line of the paragraph according the Unicode Bidirectional Algorithm.
+ *
+ * The result is the text in the visual order and the conversion tables: logical <--> visual order
+ *
+ * @param[in] paragraphInfo Struct containing the needed info to reorder each line of the paragraph.
+ * @param[in,out] lineInfo Struct containing (in) A character index pointing the first character of the line and the number of characters, (out) the reordered line and the conversion tables.
+ */
+void ReorderLine( BidirectionalParagraphInfo* paragraphInfo,
+                  BidirectionalLineInfo* lineInfo );
+
+} // namespace TextProcessor
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_PROCESSOR_BIDIRECTIONAL_INFO_H__
+
index f374479..99b7b59 100644 (file)
@@ -18,9 +18,6 @@
 // FILE HEADER
 #include <dali-toolkit/internal/controls/text-view/text-processor.h>
 
-// EXTERNAL INCLUDES
-#include <fribidi/fribidi.h>
-
 namespace Dali
 {
 
@@ -33,234 +30,78 @@ namespace Internal
 namespace TextProcessor
 {
 
-void SplitInParagraphs( const MarkupProcessor::StyledTextArray& text,
-                   std::vector<MarkupProcessor::StyledTextArray>& paragraphs )
+void SplitInParagraphs( const MarkupProcessor::StyledTextArray& styledTextArray,
+                        std::vector<Text>& paragraphs,
+                        std::vector< Vector<TextStyle*> >& styles )
 {
-  MarkupProcessor::StyledTextArray paragraph;
-  for( MarkupProcessor::StyledTextArray::const_iterator it = text.begin(), endIt = text.end(); it != endIt; ++it )
+  // Stores the text for a paragraph.
+  Text paragraph;
+
+  // Stores the styles for each character of the paragraph.
+  Vector<TextStyle*> stylesForParagraph;
+
+  // Traverses all styled texts of the array.
+  for( MarkupProcessor::StyledTextArray::const_iterator it = styledTextArray.begin(), endIt = styledTextArray.end(); it != endIt; ++it )
   {
     const MarkupProcessor::StyledText& styledText( *it );
 
+    // Traverses all the characters of the styled text (It may have more than one).
     for( size_t i = 0u, length = styledText.mText.GetLength(); i < length; ++i )
     {
       const Dali::Character character = styledText.mText[i];
 
       if( character.IsNewLine() ) // LF
       {
-        Text newText( character );
-        MarkupProcessor::StyledText newStyledText( newText, styledText.mStyle );
-        paragraph.push_back( newStyledText );
+        // The character is a new paragraph character.
 
-        paragraphs.push_back( paragraph );
-        paragraph.clear();
-      }
-      else
-      {
-        Text newText( character );
-        MarkupProcessor::StyledText newStyledText( newText, styledText.mStyle );
-        paragraph.push_back( newStyledText );
-      }
-    }
-  }
+        // Append the new paragraph character.
+        paragraph.Append( character );
 
-  // This paragraph could be empty if the last character of the previous paragraph is a 'new paragraph' character
-  // and is the last of the text.
-  paragraphs.push_back( paragraph );
-}
+        // Creates a new text style for the character and insert it to the vector of styles for that paragraph.
+        TextStyle* style = new TextStyle( styledText.mStyle );
+        stylesForParagraph.PushBack( style );
 
-void SplitInWords( const MarkupProcessor::StyledTextArray& paragraph,
-                   std::vector<MarkupProcessor::StyledTextArray>& words )
-{
-  MarkupProcessor::StyledTextArray word;
-  for( MarkupProcessor::StyledTextArray::const_iterator it = paragraph.begin(), endIt = paragraph.end(); it != endIt; ++it )
-  {
-    const MarkupProcessor::StyledText& styledText( *it );
-    const Dali::Character character = styledText.mText[0u];
+        // Inserts the paragraph and the styles to the vector of paragraphs and the vector of styles.
+        paragraphs.push_back( paragraph );
+        styles.push_back( stylesForParagraph );
 
-    if( character.IsWhiteSpace() )
-    {
-      // When a separator is found, the previous word is added to the list,
-      // then a new word is initialized and the separator is also added as a word.
-      if( !word.empty() )
-      {
-        words.push_back( word );
-        word.clear(); // initializes a new word.
+        // Clears the text and the vector of styles for the next paragraph.
+        paragraph = Text();
+        stylesForParagraph.Clear();
       }
-
-      // Separator added as a word.
-      MarkupProcessor::StyledText separatorChar;
-      separatorChar.mText.Append( character );
-      separatorChar.mStyle = styledText.mStyle;
-
-      MarkupProcessor::StyledTextArray separatorWord;
-      separatorWord.push_back( separatorChar );
-
-      words.push_back( separatorWord );
-    }
-    else
-    {
-      MarkupProcessor::StyledText styledChar;
-      styledChar.mStyle = styledText.mStyle;
-      styledChar.mText.Append( character );
-
-      // Add the character to the current word.
-      word.push_back( styledChar );
-    }
-  }
-
-  //Finally the last word need to be added.
-  if( !word.empty() )
-  {
-    words.push_back( word );
-  }
-}
-
-bool BeginsRightToLeftCharacter( const MarkupProcessor::StyledTextArray& styledText )
-{
-  for( MarkupProcessor::StyledTextArray::const_iterator it = styledText.begin(), endIt = styledText.end(); it != endIt; ++it )
-  {
-    const Text& text( (*it).mText );
-
-    for( size_t i = 0u, length = text.GetLength(); i < length; ++i )
-    {
-      Character::CharacterDirection direction = text[i].GetCharacterDirection();
-      if( direction != Character::Neutral )
+      else
       {
-        return ( direction == Character::RightToLeft || direction == Character::RightToLeftWeak );
-      }
-    }
-  }
-
-  return false;
-}
-
-bool BeginsRightToLeftCharacter( const Text& text )
-{
-  for( size_t i = 0u, length = text.GetLength(); i < length; ++i )
-  {
-    Character::CharacterDirection direction = text[i].GetCharacterDirection();
-    if( direction != Character::Neutral )
-    {
-      return ( direction == Character::RightToLeft || direction == Character::RightToLeftWeak );
-    }
-  }
-
-  return false;
-}
+        // The character is not a new paragraph character.
 
-bool ContainsRightToLeftCharacter( const MarkupProcessor::StyledTextArray& styledText )
-{
-  for( MarkupProcessor::StyledTextArray::const_iterator it = styledText.begin(), endIt = styledText.end(); it != endIt; ++it )
-  {
-    const Text& text( (*it).mText );
+        // Append it to the paragraph's text
+        paragraph.Append( character );
 
-    for( size_t i = 0u, length = text.GetLength(); i < length; ++i )
-    {
-      Character::CharacterDirection direction = text[i].GetCharacterDirection();
-      if( ( Character::RightToLeft == direction ) || ( Character::RightToLeftWeak == direction ) )
-      {
-        return true;
+        // Add the style to the vector of styles for that paragraph.
+        TextStyle* style = new TextStyle( styledText.mStyle );
+        stylesForParagraph.PushBack( style );
       }
     }
   }
 
-  return false;
-}
-
-bool ContainsRightToLeftCharacter( const Dali::Text& text )
-{
-  for( size_t i = 0u, length = text.GetLength(); i < length; ++i )
-  {
-    Character::CharacterDirection direction = ( text[i] ).GetCharacterDirection();
-    if( ( Character::RightToLeft == direction ) || ( Character::RightToLeftWeak == direction ) )
-    {
-      return true;
-    }
-  }
-
-  return false;
+  // This paragraph could be empty if the last character of the previous paragraph is a 'new paragraph' character
+  // and is the last of the text.
+  paragraphs.push_back( paragraph );
+  styles.push_back( stylesForParagraph );
 }
 
-void ConvertBidirectionalText( const MarkupProcessor::StyledTextArray& line,
-                               MarkupProcessor::StyledTextArray& convertedText,
-                               std::vector<int>& logicalToVisualMap,
-                               std::vector<int>& visualToLogicalMap )
+void SplitInWords( const Dali::Text& paragraph,
+                   Vector<std::size_t>& positions )
 {
-  // Clean vectors first. This function doesn't use any previous value.
-  logicalToVisualMap.clear();
-  visualToLogicalMap.clear();
-  convertedText.clear();
-
-  if( line.empty() )
-  {
-    // nothing to do if the line is empty.
-    return;
-  }
-
-  // Get the plain text from the line to be reordered by the BiDirectional algorithm.
-  std::string textToBeConverted;
-  GetPlainString( line, textToBeConverted );
-
-  const std::size_t stringSize = textToBeConverted.size();
-
-  std::vector<FriBidiChar> logicalStrBuffer;
-  std::vector<FriBidiChar> visualStrBuffer;
-  // unicode length <= UTF-8 length in bytes (reserve one extra for terminator)
-  // pad these buffers with 0's, as it's unclear what fribidi_log2vis does w.r.t.
-  // the length of it's output content (appears the same as input content, and does
-  // not seem to generate bidi marks i.e. FRIBIDI_CHAR_LRM/FRIBIDI_CHAR_RLM)
-  logicalStrBuffer.resize( stringSize+1u, 0u );
-  visualStrBuffer.resize( stringSize+1u, 0u );
-  FriBidiChar *logicalStr( &logicalStrBuffer[0u] );
-  FriBidiChar *visualStr( &visualStrBuffer[0u] );
-
-  // Convert UTF-8 string to unicode string
-  const std::size_t length = fribidi_charset_to_unicode( FRIBIDI_CHAR_SET_UTF8, textToBeConverted.c_str(), stringSize, logicalStr );
-
-  if( 0u == length )
-  {
-    DALI_ASSERT_DEBUG( !"TextProcessor::ConvertBidirectionalText. Error when calling at fribidi_charset_to_unicode" );
+  const std::size_t length = paragraph.GetLength();
 
-    return;
-  }
-
-  logicalToVisualMap.resize( length );
-  visualToLogicalMap.resize( length );
-
-  // Convert and reorder the string as specified by the Unicode Bidirectional Algorithm
-  FriBidiCharType baseDirection = FRIBIDI_TYPE_ON;
-  fribidi_boolean log2vis = fribidi_log2vis( logicalStr, length, &baseDirection, visualStr, &logicalToVisualMap[0u], &visualToLogicalMap[0u], NULL );
-
-  if(log2vis)
-  {
-    // Convert the unicode string back to the UTF-8 string
-    std::vector<char> bidiTextConverted;
-
-    bidiTextConverted.resize( length * 4u + 1u ); // Maximum bytes to represent one UTF-8 character is 6.
-                                                // Currently Dali doesn't support this UTF-8 extension. Dali only supports 'regular' UTF-8 which has a maximum of 4 bytes per character.
-
-    fribidi_unicode_to_charset( FRIBIDI_CHAR_SET_UTF8, visualStr, length, &bidiTextConverted[0u] );
+  // Magic number: Let's soupose there is ~6 characters per word. Used to do less memory reallocation inside Vector.
+  const size_t magicNumberOfWords = ( length / 6u ) + 1u;
 
-    textToBeConverted = &bidiTextConverted[0u];
+  // Find the positions of the new paragraph characters.
+  positions.Reserve( magicNumberOfWords );
 
-    // After reorder the text, rebuild the text with the original styles is needed.
-    // To assign the original style is needed to use the characterLogicalToVisualMap table.
-    Text text( &bidiTextConverted[0u] );
-
-    // Split the line in words.
-    // Add the correct styles for the characters after they are reordered.
-
-    for( size_t i = 0u; i < length; ++i )
-    {
-      const Character character( text[i] );
-
-      MarkupProcessor::StyledText styledText;
-      styledText.mText.Append( character );
-      styledText.mStyle = line[visualToLogicalMap[i]].mStyle;
-
-      convertedText.push_back( styledText );
-    }
-  }
+  // Find the position of all white spaces. A new paragraph character is also considered a white space but it doesn't matter at this point.
+  paragraph.Find( Text::WHITE_SPACE, 0u, length - 1u, positions );
 }
 
 /**
@@ -276,7 +117,7 @@ bool IsWhiteSpace( const MarkupProcessor::StyledTextArray& text, size_t offset )
   DALI_ASSERT_DEBUG( offset < text.size() );
 
   // assume 1 Character per StyledText
-  return text[offset].mText[0u].IsWhiteSpace();
+  return ( *( text.begin() + offset ) ).mText[0u].IsWhiteSpace();
 }
 
 void FindNearestWord( const MarkupProcessor::StyledTextArray& text, size_t offset, size_t& start, size_t& end)
@@ -327,6 +168,20 @@ void FindNearestWord( const MarkupProcessor::StyledTextArray& text, size_t offse
     j++;
   }
 
+  // If both markers at same position and is whitespace then word is a whitespace word
+  if ( i == j )
+  {
+    while(j < size && IsWhiteSpace(text, j))
+    {
+      j++;
+    }
+
+    while(i > 0 && IsWhiteSpace(text, i-1))
+    {
+      i--;
+    }
+  }
+
   start = i;
   end = j;
 }
index 6324805..9814c09 100644 (file)
@@ -32,6 +32,8 @@ namespace Internal
 
 namespace TextProcessor
 {
+// Forward declarations.
+struct BidirectionalParagraphInfo;
 
 /**
  * Splits the given text in paragraphs.
@@ -39,60 +41,22 @@ namespace TextProcessor
  * @note Assumes the StyledTextArray has 1 Character per Text element. (which is the case for text in TextInput, but
  * not necessarily the case for text in TextView)
  *
- * @param [in] text The given text.
+ * @param [in] styledTextArray The given text.
  * @param [out] paragraphs The text split in paragraphs.
+ * @param [out] styles The styles of each character of each paragraph.
  */
-void SplitInParagraphs( const MarkupProcessor::StyledTextArray& text,
-                        std::vector<MarkupProcessor::StyledTextArray>& paragraphs );
+void SplitInParagraphs( const MarkupProcessor::StyledTextArray& styledTextArray,
+                        std::vector<Text>& paragraphs,
+                        std::vector< Vector<TextStyle*> >& styles );
 
 /**
- * Splits the given paragraph in words.
- *
- * @note Assumes the StyledTextArray has 1 Character per Text element. (which is the case for text in TextInput, but
- * not necessarily the case for text in TextView)
+ * Finds the position of all word separators (currently white spaces and new paragraph characters '\n') in the given text.
  *
  * @param [in] paragraph The given paragraph.
- * @param [out] words The paragraph split in words.
- */
-void SplitInWords( const MarkupProcessor::StyledTextArray& paragraph,
-                   std::vector<MarkupProcessor::StyledTextArray>& words );
-
-/**
- * Whether the text begins with right-to-left (bidirectional) character.
- * @param [in] text The given text.
- * @return \e true if the text begins right-to-left character.
- */
-bool BeginsRightToLeftCharacter( const Text& text );
-
-/**
- * @copydoc BeginsRightToLeftCharacter( const Text& text )
- */
-bool BeginsRightToLeftCharacter( const MarkupProcessor::StyledTextArray& text );
-
-/**
- * Whether the text contains any right-to-left (bidirectional) character.
- * @param [in] text The given text.
- * @return \e true if the text contains right-to-left character.
- */
-bool ContainsRightToLeftCharacter( const Text& text );
-
-/**
- * @copydoc ContainsRightToLeftCharacter( const Text& text )
- */
-bool ContainsRightToLeftCharacter( const MarkupProcessor::StyledTextArray& text );
-
-/**
- * Convert the text as specified by the Unicode Bidirectional Algorithm.
- * The text is converted only if it is bidirectional.
- * @param[in] line The line of text to be converted.
- * @param[out] convertedText The text converted.
- * @param[out] logicalToVisualMap The character position map from the logical input text to the visual output text.
- * @param[out] visualToLogicalMap The character position map from the visual output text to the logical input text.
+ * @param [out] positions Positions within the paragraph of all word sepatators.
  */
- void ConvertBidirectionalText( const MarkupProcessor::StyledTextArray& line,
-                                MarkupProcessor::StyledTextArray& convertedText,
-                                std::vector<int>& logicalToVisualMap,
-                                std::vector<int>& visualToLogicalMap );
+void SplitInWords( const Text& paragraph,
+                   Vector<std::size_t>& positions );
 
 /**
  * Finds the nearest word in a string to a specified
index 3373ab7..a3a8ced 100644 (file)
@@ -73,13 +73,13 @@ CharacterLayoutInfo::CharacterLayoutInfo()
   mPosition(),
   mOffset(),
   mGlyphActor(),
-  mStyledText(),
   mColorAlpha( 1.f ),
   mGradientInfo( NULL ),
   mIsVisible( true ),
-  mSetText( true ),
-  mSetStyle( true ),
-  mIsColorGlyph( false )
+  mSetText( false ),
+  mSetStyle( false ),
+  mIsColorGlyph( false ),
+  mIsRightToLeft( false )
 {
 }
 
@@ -98,13 +98,13 @@ CharacterLayoutInfo::CharacterLayoutInfo( const CharacterLayoutInfo& character )
   mPosition( character.mPosition ),
   mOffset( character.mOffset ),
   mGlyphActor( character.mGlyphActor ),
-  mStyledText( character.mStyledText ),
   mColorAlpha( character.mColorAlpha ),
   mGradientInfo( ( NULL == character.mGradientInfo ) ? NULL : new GradientInfo( *character.mGradientInfo ) ), // Copies the gradient info.
   mIsVisible( character.mIsVisible ),
   mSetText( character.mSetText ),
   mSetStyle( character.mSetStyle ),
-  mIsColorGlyph( character.mIsColorGlyph )
+  mIsColorGlyph( character.mIsColorGlyph ),
+  mIsRightToLeft( character.mIsRightToLeft )
 {
 }
 
@@ -120,7 +120,6 @@ CharacterLayoutInfo& CharacterLayoutInfo::operator=( const CharacterLayoutInfo&
   mOffset = character.mOffset;
 
   mGlyphActor = character.mGlyphActor;
-  mStyledText = character.mStyledText;
 
   mColorAlpha = character.mColorAlpha;
 
@@ -150,6 +149,7 @@ CharacterLayoutInfo& CharacterLayoutInfo::operator=( const CharacterLayoutInfo&
   mSetText = character.mSetText;
   mSetStyle = character.mSetStyle;
   mIsColorGlyph = character.mIsColorGlyph;
+  mIsRightToLeft = character.mIsRightToLeft;
 
   return *this;
 }
index 0079170..9cce54a 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali-toolkit/internal/controls/text-view/split-by-new-line-char-policies.h>
 #include <dali-toolkit/internal/controls/text-view/split-by-word-policies.h>
 #include <dali-toolkit/internal/controls/text-view/split-by-char-policies.h>
+#include <dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.h>
 #include <dali-toolkit/internal/controls/text-view/text-view-processor.h>
 #include <dali-toolkit/internal/controls/text-view/text-view-word-processor.h>
 #include <dali-toolkit/internal/controls/text-view/relayout-utilities.h>
@@ -193,23 +194,38 @@ void TextView::InsertTextAt( std::size_t position, const std::string& text )
 
 void TextView::InsertTextAt( std::size_t position, const MarkupProcessor::StyledTextArray& text )
 {
-  // Creates metadata with the Insert operation.
-  TextViewProcessorMetadata metadata;
-  metadata.mType = TextView::TextInserted;
-  metadata.mPosition = position;
-  metadata.mText = text;
+  std::string textStr;
+  MarkupProcessor::GetPlainString( text, textStr );
 
-  // Store metadata.
-  mTextViewProcessorOperations.push_back( metadata );
+  if( TextProcessor::ContainsRightToLeftCharacter( Text( textStr ) ) ||
+      TextProcessor::ContainsRightToLeftCharacter( Text( GetText() ) ) )
+  {
+    // Temporary fix. Creates the whole layout if there is rtl text.
 
-  // Updates current styled text.
-  mCurrentStyledText.insert( mCurrentStyledText.begin() + position, text.begin(), text.end() );
+    MarkupProcessor::StyledTextArray textToSet = mCurrentStyledText;
+    textToSet.insert( textToSet.begin() + position, text.begin(), text.end() );
+    SetText( textToSet );
+  }
+  else
+  {
+    // Creates metadata with the Insert operation.
+    TextViewProcessorMetadata metadata;
+    metadata.mType = TextView::TextInserted;
+    metadata.mPosition = position;
+    metadata.mText = text;
 
-  // Request to be relaid out
-  RelayoutRequest();
+    // Store metadata.
+    mTextViewProcessorOperations.push_back( metadata );
 
-  // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
-  mRelayoutOperations = RELAYOUT_ALL;
+    // Updates current styled text.
+    mCurrentStyledText.insert( mCurrentStyledText.begin() + position, text.begin(), text.end() );
+
+    // Request to be relaid out
+    RelayoutRequest();
+
+    // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
+    mRelayoutOperations = RELAYOUT_ALL;
+  }
 }
 
 void TextView::ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const std::string& text )
@@ -224,49 +240,84 @@ void TextView::ReplaceTextFromTo( std::size_t position, std::size_t numberOfChar
 
 void TextView::ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const MarkupProcessor::StyledTextArray& text )
 {
-  // Creates metadata with the Insert operation.
-  TextViewProcessorMetadata metadata;
-  metadata.mType = TextView::TextReplaced;
-  metadata.mPosition = position;
-  metadata.mNumberOfCharacters = numberOfCharacters;
-  metadata.mText = text;
+  std::string textStr;
+  MarkupProcessor::GetPlainString( text, textStr );
 
-  // Store metadata.
-  mTextViewProcessorOperations.push_back( metadata );
+  if( TextProcessor::ContainsRightToLeftCharacter( Text( textStr ) ) ||
+      TextProcessor::ContainsRightToLeftCharacter( Text( GetText() ) ) )
+  {
+    // Temporary fix. Creates the whole layout if there is rtl text.
 
-  // Updates current styled text.
-  MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
-  mCurrentStyledText.erase( it, it + numberOfCharacters );
-  it = mCurrentStyledText.begin() + position;
-  mCurrentStyledText.insert( it, text.begin(), text.end() );
+    // Updates current styled text.
+    MarkupProcessor::StyledTextArray textToSet = mCurrentStyledText;
 
-  // Request to be relaid out
-  RelayoutRequest();
+    MarkupProcessor::StyledTextArray::iterator it = textToSet.begin() + position;
+    textToSet.erase( it, it + numberOfCharacters );
+    it = textToSet.begin() + position;
+    textToSet.insert( it, text.begin(), text.end() );
 
-  // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
-  mRelayoutOperations = RELAYOUT_ALL;
+    SetText( textToSet );
+  }
+  else
+  {
+    // Creates metadata with the Insert operation.
+    TextViewProcessorMetadata metadata;
+    metadata.mType = TextView::TextReplaced;
+    metadata.mPosition = position;
+    metadata.mNumberOfCharacters = numberOfCharacters;
+    metadata.mText = text;
+
+    // Store metadata.
+    mTextViewProcessorOperations.push_back( metadata );
+
+    // Updates current styled text.
+    MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
+    mCurrentStyledText.erase( it, it + numberOfCharacters );
+    it = mCurrentStyledText.begin() + position;
+    mCurrentStyledText.insert( it, text.begin(), text.end() );
+
+    // Request to be relaid out
+    RelayoutRequest();
+
+    // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
+    mRelayoutOperations = RELAYOUT_ALL;
+  }
 }
 
 void TextView::RemoveTextFrom( std::size_t position, std::size_t numberOfCharacters )
 {
-  // Creates metadata with the Remove operation.
-  TextViewProcessorMetadata metadata;
-  metadata.mType = TextView::TextRemoved;
-  metadata.mPosition = position;
-  metadata.mNumberOfCharacters = numberOfCharacters;
+  if( TextProcessor::ContainsRightToLeftCharacter( Text( GetText() ) ) )
+  {
+    // Temporary fix. Creates the whole layout if there is rtl text.
 
-  // Store metadata.
-  mTextViewProcessorOperations.push_back( metadata );
+    // Updates current styled text.
+    MarkupProcessor::StyledTextArray textToSet = mCurrentStyledText;
+    MarkupProcessor::StyledTextArray::iterator it = textToSet.begin() + position;
+    textToSet.erase( it, it + numberOfCharacters );
 
-  // Updates current styled text.
-  MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
-  mCurrentStyledText.erase( it, it + numberOfCharacters );
+    SetText( textToSet );
+  }
+  else
+  {
+    // Creates metadata with the Remove operation.
+    TextViewProcessorMetadata metadata;
+    metadata.mType = TextView::TextRemoved;
+    metadata.mPosition = position;
+    metadata.mNumberOfCharacters = numberOfCharacters;
 
-  // Request to be relaid out
-  RelayoutRequest();
+    // Store metadata.
+    mTextViewProcessorOperations.push_back( metadata );
 
-  // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
-  mRelayoutOperations = RELAYOUT_ALL;
+    // Updates current styled text.
+    MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
+    mCurrentStyledText.erase( it, it + numberOfCharacters );
+
+    // Request to be relaid out
+    RelayoutRequest();
+
+    // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
+    mRelayoutOperations = RELAYOUT_ALL;
+  }
 }
 
 std::string TextView::GetText() const
@@ -377,14 +428,18 @@ void TextView::SetStyleToCurrentText( const TextStyle& style, TextStyle::Mask ma
   }
 
   // Sets the new style to the ellipsize text
-  if( !mLayoutParameters.mEllipsizeText.empty() )
+  // TODO: fix this as a call to SetEllipsizeText will trigger the creation of new text actors.
+  if( 0u < mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles.Count() )
   {
-    for( MarkupProcessor::StyledTextArray::iterator it = mLayoutParameters.mEllipsizeText.begin(), endIt = mLayoutParameters.mEllipsizeText.end(); it != endIt; ++it )
+    for( Vector<TextStyle*>::Iterator it = mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles.Begin(),
+           endIt = mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles.End();
+         it != endIt;
+         ++it )
     {
-      (*it).mStyle.Copy( style, mask );
+      (*it)->Copy( style, mask );
     }
 
-    SetEllipsizeText( mLayoutParameters.mEllipsizeText );
+    SetEllipsizeText( mRelayoutData.mTextLayoutInfo.mEllipsisText, mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles );
   }
 }
 
@@ -547,17 +602,35 @@ void TextView::SetEllipsizeText( const std::string& ellipsizeText )
   MarkupProcessor::StyledTextArray styledText;
   MarkupProcessor::GetStyledTextArray( ellipsizeText, styledText, IsMarkupProcessingEnabled() );
 
+  // Creates the ellipsis layout info and sets the text and styles.
   SetEllipsizeText( styledText );
 }
 
 void TextView::SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsizeText )
 {
-  mLayoutParameters.mEllipsizeText = ellipsizeText;
+  // Converts the styled text array into a Text and a vector of TextStyles.
+  Text text;
+  Vector<TextStyle*> styles;
+  for( MarkupProcessor::StyledTextArray::const_iterator it = ellipsizeText.begin(), endIt = ellipsizeText.end(); it != endIt; ++it )
+  {
+    const MarkupProcessor::StyledText& styledText( *it );
 
-  mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
+    text.Append( styledText.mText );
+    styles.PushBack( new TextStyle( styledText.mStyle ) );
+  }
 
-  TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
-                                         mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
+  // Creates the ellipsis layout info and sets the text and styles.
+  SetEllipsizeText( text, styles );
+}
+
+void TextView::SetEllipsizeText( const Text& ellipsizeText, const Vector<TextStyle*>& ellipsizeStyles )
+{
+  // Sets the text and styles for the ellipsis text.
+  mRelayoutData.mTextLayoutInfo.mEllipsisText = ellipsizeText;
+  mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles = ellipsizeStyles;
+
+  // Creates the ellipsis layout info.
+  CreateEllipsizeLayout();
 
   // Request to be relaid out
   RelayoutRequest();
@@ -567,13 +640,7 @@ void TextView::SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsi
 
 std::string TextView::GetEllipsizeText() const
 {
-  std::string text;
-  for( MarkupProcessor::StyledTextArray::const_iterator it = mLayoutParameters.mEllipsizeText.begin(), endIt = mLayoutParameters.mEllipsizeText.end(); it != endIt; ++it )
-  {
-    text.append( (*it).mText.GetText() );
-  }
-
-  return text;
+  return mRelayoutData.mTextLayoutInfo.mEllipsisText.GetText();
 }
 
 void TextView::GetTextLayoutInfo()
@@ -632,7 +699,6 @@ void TextView::GetTextLayoutInfo()
       {
         mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
       }
-
     }
   }
 }
@@ -861,12 +927,8 @@ TextView::LayoutParameters::LayoutParameters()
   mVerticalAlignment( Toolkit::Alignment::VerticalCenter ),
   mLineJustification( Toolkit::TextView::Left ),
   mLineHeightOffset( 0.f ),
-  mEllipsizeText(),
   mMarkUpEnabled( false )
 {
-  // Sets ellipsize text
-  MarkupProcessor::StyledTextArray styledEllipsize;
-  MarkupProcessor::GetStyledTextArray( std::string( "..." ), mEllipsizeText, false );
 }
 
 TextView::LayoutParameters::~LayoutParameters()
@@ -879,7 +941,6 @@ TextView::LayoutParameters::LayoutParameters( Toolkit::TextView::MultilinePolicy
                                               Toolkit::Alignment::Type             alignmentType,
                                               Toolkit::TextView::LineJustification lineJustification,
                                               float                                lineHeightOffset,
-                                              const std::string&                   ellipsizeText,
                                               bool                                 markUpEnabled )
 : mMultilinePolicy( multilinePolicy ),
   mWidthExceedPolicy( widthExceedPolicy ),
@@ -888,7 +949,6 @@ TextView::LayoutParameters::LayoutParameters( Toolkit::TextView::MultilinePolicy
   mVerticalAlignment(),
   mLineJustification( lineJustification ),
   mLineHeightOffset( lineHeightOffset ),
-  mEllipsizeText(),
   mMarkUpEnabled( markUpEnabled )
 {
   // Sets alignment
@@ -901,10 +961,6 @@ TextView::LayoutParameters::LayoutParameters( Toolkit::TextView::MultilinePolicy
 
   mHorizontalAlignment = horizontalAlignment;
   mVerticalAlignment = verticalAlignment;
-
-  // Sets ellipsize text
-  MarkupProcessor::StyledTextArray styledEllipsize;
-  MarkupProcessor::GetStyledTextArray( ellipsizeText, mEllipsizeText, mMarkUpEnabled );
 }
 
 TextView::LayoutParameters::LayoutParameters( const TextView::LayoutParameters& layoutParameters )
@@ -915,7 +971,6 @@ TextView::LayoutParameters::LayoutParameters( const TextView::LayoutParameters&
   mVerticalAlignment( layoutParameters.mVerticalAlignment ),
   mLineJustification( layoutParameters.mLineJustification ),
   mLineHeightOffset( layoutParameters.mLineHeightOffset ),
-  mEllipsizeText( layoutParameters.mEllipsizeText ),
   mMarkUpEnabled( layoutParameters.mMarkUpEnabled )
 {
 }
@@ -929,7 +984,6 @@ TextView::LayoutParameters& TextView::LayoutParameters::operator=( const TextVie
   mVerticalAlignment = layoutParameters.mVerticalAlignment;
   mLineJustification = layoutParameters.mLineJustification;
   mLineHeightOffset = layoutParameters.mLineHeightOffset;
-  mEllipsizeText = layoutParameters.mEllipsizeText;
   mMarkUpEnabled = layoutParameters.mMarkUpEnabled;
 
   return *this;
@@ -1018,7 +1072,6 @@ TextView::TextView()
                      static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
                      Toolkit::TextView::Left,
                      PointSize( 0.f ),
-                     std::string( "..." ),
                      false ),
   mVisualParameters(),
   mRelayoutData(),
@@ -1034,8 +1087,8 @@ TextView::TextView()
   mPreviousSnapshotModeEnabled( false ),
   mMarkUpEnabled( false )
 {
-  TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
-                                         mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
+  // Creates the ellipsis layout info.
+  CreateEllipsizeLayout();
 }
 
 TextView::~TextView()
@@ -1149,9 +1202,8 @@ void TextView::OnInitialize()
 
 void TextView::OnFontChange( bool defaultFontChange, bool defaultFontSizeChange )
 {
-  mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
-  TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
-                                         mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
+  // Creates the ellipsis layout info.
+  CreateEllipsizeLayout();
 
   SetText( mCurrentStyledText );
 }
@@ -1191,6 +1243,17 @@ void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
     }
   }
 
+  if( ( Toolkit::TextView::Fade == mLayoutParameters.mWidthExceedPolicy ) ||
+      ( Toolkit::TextView::Fade == mLayoutParameters.mHeightExceedPolicy ) )
+  {
+    if( mRelayoutOperations & RELAYOUT_ALIGNMENT )
+    {
+      // If the text of the alignment changes and a fade exceed policy is set,
+      // some characters may need new TextActor.
+      mRelayoutOperations = RELAYOUT_ALL;
+    }
+  }
+
   // Remove glyph-actors from text-view
   if( !mRelayoutData.mGlyphActors.empty() && ( mRelayoutOperations & RELAYOUT_REMOVE_TEXT_ACTORS ) )
   {
@@ -1880,6 +1943,16 @@ Actor TextView::GetRootActor() const
   return rootActor;
 }
 
+void TextView::CreateEllipsizeLayout()
+{
+  // Creates the ellipsis layout info for the ellipsis text and styles.
+  mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
+  mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo.mCharactersLayoutInfo.resize( mRelayoutData.mTextLayoutInfo.mEllipsisText.GetLength(), TextViewProcessor::CharacterLayoutInfo() );
+  TextViewProcessor::CreateWordTextInfo( mRelayoutData.mTextLayoutInfo.mEllipsisText,
+                                         mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles,
+                                         mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
+}
+
 void TextView::OnMarkupEnabledPeopertySet( Property::Value propertyValue )
 {
   bool newValue( propertyValue.Get<bool>() );
index 220871b..70c149a 100644 (file)
@@ -90,7 +90,7 @@ public:
 
     TextViewProcessorMetadataType    mType;               ///< Stores the type of operation.
     std::size_t                      mPosition;           ///< Character position within the text.
-    std::size_t                      mNumberOfCharacters; ///< Number of characters to be removed/ replaced.
+    std::size_t                      mNumberOfCharacters; ///< Number of characters to be removed/replaced.
     MarkupProcessor::StyledTextArray mText;               ///< The new text.
     TextStyle::Mask                  mStyleMask;          ///< The style mask.
   };
@@ -245,6 +245,11 @@ public:
   void SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsizeText );
 
   /**
+   * @copydoc SetEllipsizeText()
+   */
+  void SetEllipsizeText( const Text& ellipsizeText, const Vector<TextStyle*>& ellipsizeStyles );
+
+  /**
    * @copydoc GetEllipsizeText()
    */
   std::string GetEllipsizeText() const;
@@ -524,6 +529,11 @@ private:
   Actor GetRootActor() const;
 
   /**
+   * Creates the ellipsize text layout.
+   */
+  void CreateEllipsizeLayout();
+
+  /**
    * Handle SetProperty for markup processing.
    * @param[in] propertyValue The new property value.
    */
@@ -604,7 +614,6 @@ public:
                       Toolkit::Alignment::Type               alignment,
                       Toolkit::TextView::LineJustification   lineJustification,
                       float                                  lineHeightOffset,
-                      const std::string&                     ellipsizeText,
                       bool                                   markUpEnabled );
 
     /**
@@ -618,15 +627,14 @@ public:
     LayoutParameters& operator=( const LayoutParameters& layoutParameters );
 
     Toolkit::TextView::MultilinePolicy   mMultilinePolicy;     ///< Stores the multiline policy.
-    TextView::ExceedPolicy               mExceedPolicy;        ///< Stores a combination of both policies;
+    TextView::ExceedPolicy               mExceedPolicy;        ///< Stores a combination of both policies.
     Toolkit::TextView::ExceedPolicy      mWidthExceedPolicy;   ///< Stores the text width exceed policy.
     Toolkit::TextView::ExceedPolicy      mHeightExceedPolicy;  ///< Stores the text height exceed policy.
     Toolkit::Alignment::Type             mHorizontalAlignment; ///< Stores the horizontal alignment for the whole text.
     Toolkit::Alignment::Type             mVerticalAlignment;   ///< Stores the vertical alignment for the whole text.
     Toolkit::TextView::LineJustification mLineJustification;   ///< Stores the line justification.
     float                                mLineHeightOffset;    ///< Line height offset to be addded to the font line height (measured in PointSize).
-    MarkupProcessor::StyledTextArray     mEllipsizeText;       ///< Stores the ellipsize text
-    bool                                 mMarkUpEnabled:1;     ///< Is markup string scanning enabled
+    bool                                 mMarkUpEnabled:1;     ///< Is markup string scanning enabled.
   };
 
   /**
@@ -658,15 +666,6 @@ public:
   };
 
   /**
-   * Temporary data used to calculate line justification.
-   */
-  struct LineJustificationInfo
-  {
-    TextViewProcessor::TextInfoIndices mIndices;    ///< Indices to the first character of the new line.
-    float                              mLineLength; ///< Length of the line (or portion of line).
-  };
-
-  /**
    * The results of the relayout process.
    */
   struct RelayoutData
@@ -696,7 +695,6 @@ public:
     Toolkit::TextView::CharacterLayoutInfoContainer mCharacterLayoutInfoTable;    ///< Stores layout info per character sorted by the character's visual index.
     Toolkit::TextView::LineLayoutInfoContainer      mLines;                       ///< Stores an index to the first character of each line.
     Size                                            mTextSizeForRelayoutOption;   ///< Stores the text size after relayout.
-    std::vector<LineJustificationInfo>              mLineJustificationInfo;       ///< Stores justification info per line.
     TextActorCache                                  mTextActorCache;              ///< Stores previously created text-actors to be reused.
   };
 
index be29790..70a0309 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali-toolkit/internal/controls/text-view/text-view-word-processor.h>
 #include <dali-toolkit/internal/controls/text-view/text-view-processor-helper-functions.h>
 #include <dali-toolkit/internal/controls/text-view/text-processor.h>
+#include <dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.h>
 
 namespace Dali
 {
@@ -39,26 +40,74 @@ namespace TextViewProcessor
 // Layout info.
 /////////////////////
 
+void RightToLeftParagraphLayout::Clear()
+{
+  mWordsLayoutInfo.clear();
+  mText = Text();
+  mTextStyles.Clear();
+}
+
 ParagraphLayoutInfo::ParagraphLayoutInfo()
 : mSize(),
   mAscender( 0.f ),
   mLineHeightOffset( 0.f ),
+  mFirstCharacter( 0u ),
   mNumberOfCharacters( 0u ),
-  mWordsLayoutInfo()
+  mWordsLayoutInfo(),
+  mText(),
+  mTextStyles(),
+  mRightToLeftLayout( NULL ),
+  mBidirectionalParagraphInfo( NULL ),
+  mBidirectionalLinesInfo()
 {
 }
 
 ParagraphLayoutInfo::~ParagraphLayoutInfo()
 {
+  if( NULL != mRightToLeftLayout )
+  {
+    // TextStyle pointers are the same than the ones stored at ParagraphLayoutInfo::mTextStyles.
+    // Do not delete them, just clear the vector.
+    mRightToLeftLayout->mTextStyles.Clear();
+
+    delete mRightToLeftLayout;
+  }
+
+  // Clears text styles. It destroys TextStyle objects.
+  ClearStyles();
+
+  // Deletes the bidirectional info for the whole paragraph.
+  delete mBidirectionalParagraphInfo;
+
+  // Clears the bidirectional info for all lines. Destroys the BidirectionalLineInfo objects.
+  ClearBidirectionalInfo();
 }
 
 ParagraphLayoutInfo::ParagraphLayoutInfo( const ParagraphLayoutInfo& paragraph )
 : mSize( paragraph.mSize ),
   mAscender( paragraph.mAscender ),
   mLineHeightOffset( paragraph.mLineHeightOffset ),
+  mFirstCharacter( paragraph.mFirstCharacter ),
   mNumberOfCharacters( paragraph.mNumberOfCharacters ),
-  mWordsLayoutInfo( paragraph.mWordsLayoutInfo )
+  mWordsLayoutInfo( paragraph.mWordsLayoutInfo ),
+  mText( paragraph.mText ),
+  mTextStyles(),
+  mRightToLeftLayout( NULL ),
+  // Copies bidirectional info for the whole paragraph.
+  mBidirectionalParagraphInfo( ( NULL == paragraph.mBidirectionalParagraphInfo ) ? NULL : new TextProcessor::BidirectionalParagraphInfo( *paragraph.mBidirectionalParagraphInfo ) ),
+  mBidirectionalLinesInfo()
 {
+  // Copies styles.
+  for( Vector<TextStyle*>::ConstIterator it = paragraph.mTextStyles.Begin(), endIt = paragraph.mTextStyles.End(); it != endIt; ++it )
+  {
+    mTextStyles.PushBack( new TextStyle( *(*it) ) );
+  }
+
+  // Copies bidirectional info for each line.
+  for( Vector<TextProcessor::BidirectionalLineInfo*>::ConstIterator it = mBidirectionalLinesInfo.Begin(), endIt = mBidirectionalLinesInfo.End(); it != endIt; ++it )
+  {
+    mBidirectionalLinesInfo.PushBack( new TextProcessor::BidirectionalLineInfo( *( *it ) ) );
+  }
 }
 
 ParagraphLayoutInfo& ParagraphLayoutInfo::operator=( const ParagraphLayoutInfo& paragraph )
@@ -66,150 +115,207 @@ ParagraphLayoutInfo& ParagraphLayoutInfo::operator=( const ParagraphLayoutInfo&
   mSize = paragraph.mSize;
   mAscender = paragraph.mAscender;
   mLineHeightOffset = paragraph.mLineHeightOffset;
+  mFirstCharacter = paragraph.mFirstCharacter;
   mNumberOfCharacters = paragraph.mNumberOfCharacters;
   mWordsLayoutInfo = paragraph.mWordsLayoutInfo;
+  mText = paragraph.mText;
 
-  return *this;
-}
+  // If it has styles, destroy them.
+  ClearStyles();
 
-void CreateParagraphInfo( const MarkupProcessor::StyledTextArray& paragraph,
-                          TextView::RelayoutData& relayoutData,
-                          ParagraphLayoutInfo& paragraphLayoutInfo )
-{
-  // Split the paragraph in words.
-  // TODO: Proper RTL support.
-  MarkupProcessor::StyledTextArray convertedParagraph;
-  if( TextProcessor::ContainsRightToLeftCharacter( paragraph ) )
+  // Copies styles.
+  for( Vector<TextStyle*>::ConstIterator it = paragraph.mTextStyles.Begin(), endIt = paragraph.mTextStyles.End(); it != endIt; ++it )
   {
-    // If the text is bidirectional, the characters will be converted and reordered
-    // as specified by the Unicode Bidirectional Algorithm.
+    mTextStyles.PushBack( new TextStyle( *(*it) ) );
+  }
 
-    // Reorders the paragraph and converts arabic glyphs (if any).
-    TextProcessor::ConvertBidirectionalText( paragraph,
-                                             convertedParagraph,
-                                             relayoutData.mCharacterLogicalToVisualMap,
-                                             relayoutData.mCharacterVisualToLogicalMap);
+  // Copies the paragraph's bidirectiona info.
+  if( NULL == paragraph.mBidirectionalParagraphInfo )
+  {
+    // The source doesn't have bidirectiona info. Deletes the current one.
+    delete mBidirectionalParagraphInfo;
+    mBidirectionalParagraphInfo = NULL;
   }
   else
   {
-    // No bidirectional text to process.
-    convertedParagraph = paragraph;
-
-    // Create trivial bidirectional map tables.
-    std::size_t index = 0u;
-    for( MarkupProcessor::StyledTextArray::const_iterator it = convertedParagraph.begin(), endIt = convertedParagraph.end(); it != endIt; ++it )
+    // The source has bidirectional info.
+    if( NULL != mBidirectionalParagraphInfo )
     {
-      const MarkupProcessor::StyledText& styledText( *it );
-
-      for( std::size_t i = 0u, length = styledText.mText.GetLength(); i < length; ++i )
-      {
-        relayoutData.mCharacterLogicalToVisualMap.push_back( relayoutData.mTextLayoutInfo.mNumberOfCharacters + index );
-        relayoutData.mCharacterVisualToLogicalMap.push_back( relayoutData.mTextLayoutInfo.mNumberOfCharacters + index );
-        ++index;
-      }
+      // It it has, copy to it.
+      *mBidirectionalParagraphInfo = *paragraph.mBidirectionalParagraphInfo;
+    }
+    else
+    {
+      // If it doesn't have, create a new one.
+      mBidirectionalParagraphInfo = new TextProcessor::BidirectionalParagraphInfo( *paragraph.mBidirectionalParagraphInfo );
     }
   }
 
-  // Split the paragraph in words
-  std::vector<MarkupProcessor::StyledTextArray> words;
-  TextProcessor::SplitInWords( convertedParagraph, words );
+  // If it has bidirectiona info per line, destroy them.
+  ClearBidirectionalInfo();
 
-  // if last word has a new paragraph separator, create a new word.
-  if( !words.empty() )
+  // Copies bidirectional info per line.
+  for( Vector<TextProcessor::BidirectionalLineInfo*>::ConstIterator it = mBidirectionalLinesInfo.Begin(), endIt = mBidirectionalLinesInfo.End(); it != endIt; ++it )
   {
-    MarkupProcessor::StyledTextArray& word( *( words.end() - 1u ) );
-    if( word.size() > 1u )
-    {
-      // do nothing if the word has only one character.
-      MarkupProcessor::StyledText& styledText( *( word.end() - 1u ) );
-      if( !styledText.mText.IsEmpty() )
-      {
-        const std::size_t length = styledText.mText.GetLength();
-        if( styledText.mText[length-1u].IsNewLine() )
-        {
-          // Last character of this word is a new paragraph character.
+    mBidirectionalLinesInfo.PushBack( new TextProcessor::BidirectionalLineInfo( *( *it ) ) );
+  }
 
-          // Remove paragraph separator character from current word.
-          styledText.mText.Remove( length - 1u, 1u );
+  return *this;
+}
 
-          // Create a new word with the paragraph separator character.
-          MarkupProcessor::StyledText newParagraphText( Text( styledText.mText[length-1u] ), styledText.mStyle );
+void ParagraphLayoutInfo::ClearBidirectionalInfo()
+{
+  // Destroys the bidirectional infor per line.
+  for( Vector<TextProcessor::BidirectionalLineInfo*>::Iterator it = mBidirectionalLinesInfo.Begin(), endIt = mBidirectionalLinesInfo.End(); it != endIt; ++it )
+  {
+    delete *it;
+  }
+  mBidirectionalLinesInfo.Clear();
+}
 
-          MarkupProcessor::StyledTextArray newParagraphWord;
-          newParagraphWord.push_back( newParagraphText );
+void ParagraphLayoutInfo::ClearStyles()
+{
+  // Destroys the styles.
+  for( Vector<TextStyle*>::Iterator it = mTextStyles.Begin(), endIt = mTextStyles.End(); it != endIt; ++it )
+  {
+    delete *it;
+  }
+  mTextStyles.Clear();
+}
 
-          words.push_back( newParagraphWord );
-        }
-      }
-    }
+void CreateParagraphInfo( TextView::RelayoutData& relayoutData,
+                          ParagraphLayoutInfo& paragraphLayoutInfo )
+{
+  if( TextProcessor::ContainsRightToLeftCharacter( paragraphLayoutInfo.mText ) )
+  {
+    // If the text is bidirectional, the characters will be converted and reordered
+    // as specified by the Unicode Bidirectional Algorithm.
+
+    paragraphLayoutInfo.mBidirectionalParagraphInfo = new TextProcessor::BidirectionalParagraphInfo();
+
+    TextProcessor::ProcessBidirectionalText( paragraphLayoutInfo.mText, paragraphLayoutInfo.mBidirectionalParagraphInfo );
   }
 
-  std::string lastCharacterFont; // Keeps the font used by the last character. It's used to set the font to a word separator.
+  // Split the paragraph in words. It retrieves the positions of white spaces and the last '\n' if there is one.
+  Vector<std::size_t> positions;
+  TextProcessor::SplitInWords( paragraphLayoutInfo.mText, positions );
 
-  // Traverse all words.
-  for( std::vector<MarkupProcessor::StyledTextArray>::const_iterator wordIt = words.begin(), wordEndIt = words.end(); wordIt != wordEndIt; ++wordIt )
-  {
-    const MarkupProcessor::StyledTextArray& word( *wordIt );
+  const std::size_t lastCharacterIndex = paragraphLayoutInfo.mText.GetLength() - 1u;
+  const bool isLastCharacterParagraphSeparator = paragraphLayoutInfo.mText.IsNewLine( lastCharacterIndex );
 
-    // Data structures for the new word.
-    WordLayoutInfo wordLayoutInfo;
+  // The number of words is ~the number of white spaces found + 1u.
+  // White spaces are also words.
+  // New line characters are also white spaces. If the last character is a white space the +1 is not needed.
+  const std::size_t numberOfWords = 2u * positions.Count() + ( isLastCharacterParagraphSeparator ? 0u : 1u );
 
-    CreateWordTextInfo( word,
-                        wordLayoutInfo );
+  // Reserve space for all the words.
+  paragraphLayoutInfo.mWordsLayoutInfo.resize( numberOfWords, WordLayoutInfo() );
+
+  // Traverses all positions creating and setting all character layout info objects to every word.
+  std::size_t wordIndex = 0u;
+  Vector<std::size_t>::ConstIterator positionIt = positions.Begin();
+  Vector<std::size_t>::ConstIterator positionEndIt = positions.End();
+  std::size_t from = 0u;
+  for( std::size_t positionIndex = 0u, size = positions.Count() + 1u; positionIndex < size; ++positionIndex )
+  {
+    const bool isEndPosition = positionIt == positionEndIt;
+    const std::size_t to = isEndPosition ? lastCharacterIndex + 1u : *positionIt;
 
-    // White space's size could be different depending on the type of font. It's important to use the same font than the previous character to
-    // avoid 'jumps' of characters when there is a switch between one text-actor per character and one text-actor per line and/or style.
-    if( WordSeparator == wordLayoutInfo.mType )
+    if( from < to )
     {
-      // If current word is a word separator (white space) then the font of the last character is set.
-      for( CharacterLayoutInfoContainer::iterator characterIt = wordLayoutInfo.mCharactersLayoutInfo.begin(), characterEndIt = wordLayoutInfo.mCharactersLayoutInfo.end();
-           characterIt != characterEndIt;
-           ++characterIt )
-      {
-        CharacterLayoutInfo& characterLayout( *characterIt );
+      // The word is not a white space.
+      WordLayoutInfo& wordLayoutInfo = *( paragraphLayoutInfo.mWordsLayoutInfo.begin() + wordIndex );
+      ++wordIndex;
+      // Sets the index within the paragraph to the first character of the word.
+      wordLayoutInfo.mFirstCharacter = from;
+      // Creates character layout info objects.
+      wordLayoutInfo.mCharactersLayoutInfo.resize( ( to - from ), CharacterLayoutInfo() );
+    }
 
-        characterLayout.mStyledText.mStyle.SetFontName( lastCharacterFont );
-      }
+    if( !isEndPosition )
+    {
+      // Create a word for the white space.
+      WordLayoutInfo& wordLayoutInfo = *( paragraphLayoutInfo.mWordsLayoutInfo.begin() + wordIndex );
+      ++wordIndex;
+      // Sets the index within the paragraph to the white space.
+      wordLayoutInfo.mFirstCharacter = to;
+      wordLayoutInfo.mType = WordSeparator;
+
+      CharacterLayoutInfo characterLayoutInfo;
+      wordLayoutInfo.mCharactersLayoutInfo.push_back( characterLayoutInfo );
+    }
+
+    from = to + 1u;
+
+    if( !isEndPosition )
+    {
+      // next white space position.
+      ++positionIt;
     }
     else
     {
-      // kepps the font of the last character.
-      if( !wordLayoutInfo.mCharactersLayoutInfo.empty() )
+      // All white space positiona have been traversed.
+      // It may be some extra words. i.e if the text is \n.
+      // Erase them.
+      paragraphLayoutInfo.mWordsLayoutInfo.erase( paragraphLayoutInfo.mWordsLayoutInfo.begin() + wordIndex, paragraphLayoutInfo.mWordsLayoutInfo.end() );
+
+      // Check if the last character is a new paragraph character.
+      if( isLastCharacterParagraphSeparator )
       {
-        lastCharacterFont = ( *( wordLayoutInfo.mCharactersLayoutInfo.end() - 1u ) ).mStyledText.mStyle.GetFontName();
+        ( *( paragraphLayoutInfo.mWordsLayoutInfo.end() - 1u ) ).mType = ParagraphSeparator;
       }
     }
+  }
 
-    // Update the max word width figure.
-    relayoutData.mTextLayoutInfo.mMaxWordWidth = std::max( relayoutData.mTextLayoutInfo.mMaxWordWidth, wordLayoutInfo.mSize.width );
+  // Traverse all words and fill the layout info.
+  for( WordLayoutInfoContainer::iterator it = paragraphLayoutInfo.mWordsLayoutInfo.begin(), endIt = paragraphLayoutInfo.mWordsLayoutInfo.end(); it != endIt; ++it )
+  {
+    WordLayoutInfo& wordLayoutInfo( *it );
+
+    CreateWordTextInfo( paragraphLayoutInfo.mText,
+                        paragraphLayoutInfo.mTextStyles,
+                        wordLayoutInfo );
 
     // Update layout info for the current paragraph.
+    UpdateSize( paragraphLayoutInfo.mSize, wordLayoutInfo.mSize );
     paragraphLayoutInfo.mAscender = std::max( paragraphLayoutInfo.mAscender, wordLayoutInfo.mAscender );
     paragraphLayoutInfo.mNumberOfCharacters += wordLayoutInfo.mCharactersLayoutInfo.size();
-    UpdateSize( paragraphLayoutInfo.mSize, wordLayoutInfo.mSize );
 
-    // Add the word to the current paragraph.
-    paragraphLayoutInfo.mWordsLayoutInfo.push_back( wordLayoutInfo );
+    // Update the max word width figure.
+    relayoutData.mTextLayoutInfo.mMaxWordWidth = std::max( relayoutData.mTextLayoutInfo.mMaxWordWidth, wordLayoutInfo.mSize.width );
   } // end of words
 }
 
 void UpdateLayoutInfo( ParagraphLayoutInfo& paragraphLayoutInfo, float lineHeightOffset )
 {
   // Update layout info.
+
+  // Initialize members to be updated.
   paragraphLayoutInfo.mSize = Size::ZERO;
   paragraphLayoutInfo.mAscender = 0.f;
   paragraphLayoutInfo.mNumberOfCharacters = 0u;
+
+  // Traverses all words.
   for( WordLayoutInfoContainer::iterator it = paragraphLayoutInfo.mWordsLayoutInfo.begin(), endIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
        it != endIt;
        ++it )
   {
     WordLayoutInfo& word( *it );
 
+    // Sets the index within the paragraph to the first character of the word.
+    word.mFirstCharacter = paragraphLayoutInfo.mNumberOfCharacters;
+
+    // Updates the paragraph's size.
     UpdateSize( paragraphLayoutInfo.mSize, word.mSize );
+
+    // Updates the paragraph's max asender.
     paragraphLayoutInfo.mAscender = std::max( paragraphLayoutInfo.mAscender, word.mAscender );
+
+    // Updates the paragraph's number of characters.
     paragraphLayoutInfo.mNumberOfCharacters += word.mCharactersLayoutInfo.size();
   }
 
+  // Sets the line height offset.
   paragraphLayoutInfo.mSize.height += lineHeightOffset;
   paragraphLayoutInfo.mLineHeightOffset = lineHeightOffset;
 }
@@ -476,6 +582,26 @@ void SplitParagraph( const TextInfoIndices& indices,
 
   // 6) update layout info of the first paragraph.
   UpdateLayoutInfo( firstParagraphLayoutInfo, lineHeightOffset );
+
+  // 7) Split text and styles.
+
+  // Copies the whole text to the last part of the paragraph.
+  lastParagraphLayoutInfo.mText = firstParagraphLayoutInfo.mText;
+
+  // Removes from the first part of the paragraph the text that goes to the last part.
+  firstParagraphLayoutInfo.mText.Remove( indices.mCharacterParagraphIndex, firstParagraphLayoutInfo.mText.GetLength() - indices.mCharacterParagraphIndex );
+
+  // Removes from the last part of the paragraph the text that remains in the first part.
+  lastParagraphLayoutInfo.mText.Remove( 0u, indices.mCharacterParagraphIndex );
+
+  // Sets the character's styles for the last part of the paragraph.
+  lastParagraphLayoutInfo.mTextStyles.Insert( lastParagraphLayoutInfo.mTextStyles.End(),
+                                         firstParagraphLayoutInfo.mTextStyles.Begin() + indices.mCharacterParagraphIndex,
+                                         firstParagraphLayoutInfo.mTextStyles.End() );
+
+  // Removes the character's styles that go to the last part of the paragraph.
+  firstParagraphLayoutInfo.mTextStyles.Erase( firstParagraphLayoutInfo.mTextStyles.Begin() + indices.mCharacterParagraphIndex,
+                                         firstParagraphLayoutInfo.mTextStyles.End() );
 }
 
 void MergeParagraph( ParagraphLayoutInfo& firstParagraphLayoutInfo,
@@ -528,14 +654,29 @@ void MergeParagraph( ParagraphLayoutInfo& firstParagraphLayoutInfo,
   // Merge layout info
 
   // Insert the layout of the words.
+  const std::size_t numberOfWords = firstParagraphLayoutInfo.mWordsLayoutInfo.size();
   firstParagraphLayoutInfo.mWordsLayoutInfo.insert( firstParagraphLayoutInfo.mWordsLayoutInfo.end(),
                                                    lastParagraphLayoutInfo.mWordsLayoutInfo.begin() + index, lastParagraphLayoutInfo.mWordsLayoutInfo.end() );
 
+  // Increase the index of the first character of each inserted word.
+  for( WordLayoutInfoContainer::iterator it = firstParagraphLayoutInfo.mWordsLayoutInfo.begin() + numberOfWords, endIt = firstParagraphLayoutInfo.mWordsLayoutInfo.end(); it != endIt; ++it )
+  {
+    WordLayoutInfo& word( *it );
+    word.mFirstCharacter += firstParagraphLayoutInfo.mNumberOfCharacters;
+  }
+
   // Update the size and other layout parameters.
   UpdateSize( firstParagraphLayoutInfo.mSize, lastParagraphLayoutInfo.mSize );
   firstParagraphLayoutInfo.mAscender = std::max( firstParagraphLayoutInfo.mAscender, lastParagraphLayoutInfo.mAscender );
   firstParagraphLayoutInfo.mLineHeightOffset = std::max( firstParagraphLayoutInfo.mLineHeightOffset, lastParagraphLayoutInfo.mLineHeightOffset );
   firstParagraphLayoutInfo.mNumberOfCharacters += lastParagraphLayoutInfo.mNumberOfCharacters;
+
+  // Merge text and styles.
+  firstParagraphLayoutInfo.mText.Append( lastParagraphLayoutInfo.mText );
+  for( Vector<TextStyle*>::ConstIterator it = lastParagraphLayoutInfo.mTextStyles.Begin(), endIt = lastParagraphLayoutInfo.mTextStyles.End(); it != endIt; ++it )
+  {
+    firstParagraphLayoutInfo.mTextStyles.PushBack( new TextStyle( *(*it) ) );
+  }
 }
 
 WordLayoutInfo GetLastWordLayoutInfo( const ParagraphLayoutInfo& paragraphLayoutInfo )
index b43489c..3e9b0f0 100644 (file)
@@ -36,12 +36,10 @@ namespace TextViewProcessor
 /**
  * Creates a data structure with info to layout the paragraph, and data structures with useful info to modify the layout data structure if characters are added or removed.
  *
- * @param[in] paragraph The styled paragraph.
  * @param[in,out] relayoutData Natural size (metrics), layout, text-actor info and conversion from visual to logical order and vice versa (for RTL text).
  * @param[out] paragraphLayoutInfo Layout info for the whole paragraph.
  */
-void CreateParagraphInfo( const MarkupProcessor::StyledTextArray& line,
-                          TextView::RelayoutData& relayoutData,
+void CreateParagraphInfo( TextView::RelayoutData& relayoutData,
                           ParagraphLayoutInfo& paragraphLayoutInfo );
 
 /**
index b3a59c7..713c681 100644 (file)
@@ -19,7 +19,7 @@
 #include <dali-toolkit/internal/controls/text-view/text-view-processor-dbg.h>
 
 // INTERNAL INCLUDES
-#include <dali/public-api/actors/text-actor.h>
+#include <dali-toolkit/internal/controls/text-view/text-view-processor-types.h>
 
 namespace Dali
 {
@@ -39,30 +39,9 @@ Debug::Filter* gTextViewProcessorLogFilter = Debug::Filter::New(Debug::NoLogging
 
 void dbgPrint( const WordLayoutInfo& word )
 {
-  for( CharacterLayoutInfoContainer::const_iterator characterIt = word.mCharactersLayoutInfo.begin(), endCharacterIt = word.mCharactersLayoutInfo.end();
-       characterIt != endCharacterIt;
-       ++characterIt )
-  {
-    const CharacterLayoutInfo& character( *characterIt );
-
-    std::cout << "[" << character.mSize << std::endl;
-    std::cout << " ascender " << character.mAscender << std::endl;
-
-    TextActor textActor = TextActor::DownCast( character.mGlyphActor );
-    if( textActor )
-    {
-      std::cout << "[" << textActor.GetText() << "]";
-    }
-    else
-    {
-      std::cout << "[ImageActor]" << std::endl;
-    }
-    std::cout << "{" << character.mStyledText.mText.GetText() << "}";
-  }
-  std::cout << "     size " << word.mSize << std::endl;
-  std::cout << " ascender " << word.mAscender << std::endl;
-  std::cout << " num char " << word.mCharactersLayoutInfo.size() << std::endl;
-  std::cout << "     type ";
+  std::cout << "       size " << word.mSize << std::endl;
+  std::cout << "   ascender " << word.mAscender << std::endl;
+  std::cout << "       type ";
   switch( word.mType )
   {
     case NoSeparator:
@@ -81,11 +60,24 @@ void dbgPrint( const WordLayoutInfo& word )
       break;
     }
   }
+  std::cout << " first char " << word.mFirstCharacter << std::endl;
+  std::cout << "   num char " << word.mCharactersLayoutInfo.size() << std::endl;
+  for( CharacterLayoutInfoContainer::const_iterator characterIt = word.mCharactersLayoutInfo.begin(), endCharacterIt = word.mCharactersLayoutInfo.end();
+       characterIt != endCharacterIt;
+       ++characterIt )
+  {
+    const CharacterLayoutInfo& character( *characterIt );
+
+    std::cout << "[" << character.mSize << std::endl;
+    std::cout << " ascender " << character.mAscender << std::endl;
+  }
 }
 
 void dbgPrint( const ParagraphLayoutInfo& paragraph )
 {
   std::cout << "< ";
+  std::cout << "  text : [" << paragraph.mText.GetText() << "]" << std::endl;
+  std::cout << "  number of styles : " << paragraph.mTextStyles.Count() << std::endl;
   std::cout << paragraph.mSize;
   for( WordLayoutInfoContainer::const_iterator wordIt = paragraph.mWordsLayoutInfo.begin(), endWordIt = paragraph.mWordsLayoutInfo.end();
        wordIt != endWordIt;
@@ -157,6 +149,7 @@ void dbgPrint( const TextInfoIndices& indices )
   std::cout << "          paragraph : " << indices.mParagraphIndex << std::endl;
   std::cout << "               word : " << indices.mWordIndex << std::endl;
   std::cout << "               char : " << indices.mCharacterIndex << std::endl;
+  std::cout << "  char in paragraph : " << indices.mCharacterParagraphIndex << std::endl;
 }
 
 void dbgPrint( const MarkupProcessor::StyledTextArray& textArray )
@@ -169,18 +162,6 @@ void dbgPrint( const MarkupProcessor::StyledTextArray& textArray )
   }
 }
 
-void dbgPrintText( const WordLayoutInfo& word )
-{
-  for( CharacterLayoutInfoContainer::const_iterator characterIt = word.mCharactersLayoutInfo.begin(), endCharacterIt = word.mCharactersLayoutInfo.end();
-       characterIt != endCharacterIt;
-       ++characterIt )
-  {
-    const CharacterLayoutInfo& character( *characterIt );
-
-    std::cout << character.mStyledText.mText.GetText();
-  }
-}
-
 } // namespace TextViewProcessor
 
 } // namespace Internal
index b5131e4..2529bb8 100644 (file)
  */
 
 // INTERNAL INCLUDES
-#include <dali/integration-api/debug.h>
 #include <dali-toolkit/public-api/markup-processor/markup-processor.h>
-#include <dali-toolkit/internal/controls/text-view/text-view-processor-types.h>
+#include <dali/integration-api/debug.h>
 
 namespace Dali
 {
 
+//Forward declarations.
+class TextStyle;
+
 namespace Toolkit
 {
 
@@ -35,6 +37,12 @@ namespace Internal
 namespace TextViewProcessor
 {
 
+//Forward declarations.
+struct WordLayoutInfo;
+struct ParagraphLayoutInfo;
+struct TextLayoutInfo;
+struct TextInfoIndices;
+
 #if defined(DEBUG_ENABLED)
 extern Debug::Filter* gTextViewProcessorLogFilter;
 #endif
@@ -46,8 +54,6 @@ void dbgPrint( const TextStyle& style );
 void dbgPrint( const TextInfoIndices& indices );
 void dbgPrint( const MarkupProcessor::StyledTextArray& text );
 
-void dbgPrintText( const WordLayoutInfo& word );
-
 } // namespace TextViewProcessor
 
 } // namespace Internal
index 1855b6e..43a5f4e 100644 (file)
@@ -58,20 +58,20 @@ TextSeparatorType GetTextSeparatorType( const Character& character )
   return ( character.IsNewLine() ? ParagraphSeparator : ( character.IsWhiteSpace() ? WordSeparator : NoSeparator ) );
 }
 
-void ChooseFontFamilyName( MarkupProcessor::StyledText& text )
+void ChooseFontFamilyName( const Character& character, TextStyle& style )
 {
   DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, "-->TextViewProcessor::ChooseFontFamilyName\n" );
-  DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, "   input font name: [%s]\n", text.mStyle.GetFontName().c_str() );
+  DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, "   input font name: [%s]\n", style.GetFontName().c_str() );
 
   bool userDefinedFontFamilyName = false;
 
   // First check if there is a font defined in the style and it supports the given text.
-  if( !text.mStyle.GetFontName().empty() )
+  if( !style.GetFontName().empty() )
   {
-    const FontParameters fontParams( text.mStyle.GetFontName(), text.mStyle.GetFontStyle() , text.mStyle.GetFontPointSize() );
+    const FontParameters fontParams( style.GetFontName(), style.GetFontStyle() , style.GetFontPointSize() );
     const Font font = Font::New( fontParams );
 
-    if( !font.IsDefaultSystemFont() && font.AllGlyphsSupported( text.mText ) )
+    if( !font.IsDefaultSystemFont() && font.AllGlyphsSupported( character ) )
     {
       userDefinedFontFamilyName = true;
     }
@@ -82,20 +82,20 @@ void ChooseFontFamilyName( MarkupProcessor::StyledText& text )
     const Font defaultSystemFont = Font::New();
 
     // At this point no font is set or doesn't support the given text.
-    if( !defaultSystemFont.AllGlyphsSupported( text.mText ) )
+    if( !defaultSystemFont.AllGlyphsSupported( character ) )
     {
       // If the default system font doesn't support the given text,
       // an appropiate font is selected.
-      text.mStyle.SetFontName( Font::GetFamilyForText( text.mText ) );
+      style.SetFontName( Font::GetFamilyForText( character ) );
       // @TODO Font::GetFamilyForText() should return font family and font style.
     }
     else
     {
       // All characters are supported with default font, so use it
-      text.mStyle.SetFontName( "" );
+      style.SetFontName( "" );
     }
   }
-  DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, "  output font name: [%s]\n", text.mStyle.GetFontName().c_str() );
+  DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, "  output font name: [%s]\n", style.GetFontName().c_str() );
   DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, "<--TextViewProcessor::ChooseFontFamilyName\n" );
 }
 
@@ -123,6 +123,7 @@ void GetIndicesFromGlobalCharacterIndex( const std::size_t index,
        ++paragraphIt, ++indices.mParagraphIndex )
   {
     const ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphIt );
+    std::size_t currentCharactersTraversed = currentIndex; // stores how many characters have been traversed until this paragraph.
 
     if( currentIndex + paragraphLayoutInfo.mNumberOfCharacters > index )
     {
@@ -138,6 +139,7 @@ void GetIndicesFromGlobalCharacterIndex( const std::size_t index,
         {
           // The character is in this word
           indices.mCharacterIndex = index - currentIndex;
+          indices.mCharacterParagraphIndex = index - currentCharactersTraversed;
           found = true;
         }
         else
index ef9fb2a..c543e32 100644 (file)
@@ -71,13 +71,14 @@ void UpdateSize( Size& size1, const Size& size2, SizeGrowType type = GrowWidth )
 TextSeparatorType GetTextSeparatorType( const Character& character );
 
 /**
- * Choose a suitable font family name for the given styled text.
+ * Choose a suitable font family name for the given character.
  *
- * It may modify the text-style of the given text by setting a suitable font-family.
+ * It may modify the text-style of the given character by setting a suitable font-family.
  *
- * @param[in,out] text Text with style.
+ * @param[in] character The character.
+ * @param[in,out] style The style of the character.
  */
-void ChooseFontFamilyName( MarkupProcessor::StyledText& text );
+void ChooseFontFamilyName( const Character& character, TextStyle& style );
 
 /**
  * Retrieves the line, word and character indices for the given global character's index.
index a4d1873..8cb689b 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali/public-api/actors/renderable-actor.h>
-#include <dali-toolkit/public-api/markup-processor/markup-processor.h>
+#include <dali/public-api/text/text.h>
 
 namespace Dali
 {
 
+class TextStyle;
+
 namespace Toolkit
 {
 
 namespace Internal
 {
 
+namespace TextProcessor
+{
+// Forward declarations.
+struct BidirectionalParagraphInfo;
+struct BidirectionalLineInfo;
+} // namespace TextProcessor
+
 namespace TextViewProcessor
 {
 
@@ -84,6 +93,7 @@ struct TextInfoIndices
   std::size_t mParagraphIndex;          ///< The paragraph index within the text.
   std::size_t mWordIndex;               ///< The word index within the paragraph.
   std::size_t mCharacterIndex;          ///< The character index within the word.
+  std::size_t mCharacterParagraphIndex; ///< The character index within the paragraph.
 };
 
 /**
@@ -151,25 +161,25 @@ struct CharacterLayoutInfo
   CharacterLayoutInfo& operator=( const CharacterLayoutInfo& character );
 
   // Metrics of the glyph.
-  Size        mSize;               ///< Height of the font and advance (the horizontal distance from the origin of the current character and the next one).
-  float       mBearing;            ///< Vertical distance from the baseline to the top of the glyph's boundary box.
-  float       mAscender;           ///< Distance from the base line to the top of the line.
-  float       mUnderlineThickness; ///< The underline's thickness.
-  float       mUnderlinePosition;  ///< The underline's position.
+  Size        mSize;                ///< Height of the font and advance (the horizontal distance from the origin of the current character and the next one).
+  float       mBearing;             ///< Vertical distance from the baseline to the top of the glyph's boundary box.
+  float       mAscender;            ///< Distance from the base line to the top of the line.
+  float       mUnderlineThickness;  ///< The underline's thickness.
+  float       mUnderlinePosition;   ///< The underline's position.
 
   // Position and alignment offset. It depends on the lay-out.
-  Vector3     mPosition;           ///< Position within the text-view
-  Vector2     mOffset;             ///< Alignment and justification offset.
-
-  RenderableActor             mGlyphActor;   ///< Handle to a text-actor.
-  MarkupProcessor::StyledText mStyledText;   ///< Stores the text and its style.
-  float                       mColorAlpha;   ///< Alpha component for the initial text color when text is faded.
-  GradientInfo*               mGradientInfo; ///< Stores gradient info.
-
-  bool            mIsVisible:1;    ///< Whether the text-actor is visible.
-  bool            mSetText:1;      ///< Whether a new text needs to be set in the text-actor.
-  bool            mSetStyle:1;     ///< Whether a new style needs to be set in the text-actor.
-  bool            mIsColorGlyph:1; ///< Whether this character is an emoticon.
+  Vector3     mPosition;            ///< Position within the text-view
+  Vector2     mOffset;              ///< Alignment and justification offset.
+
+  RenderableActor mGlyphActor;      ///< Handle to a text-actor.
+  float           mColorAlpha;      ///< Alpha component for the initial text color when text is faded.
+  GradientInfo*   mGradientInfo;    ///< Stores gradient info.
+
+  bool            mIsVisible:1;     ///< Whether the text-actor is visible.
+  bool            mSetText:1;       ///< Whether a new text needs to be set in the text-actor.
+  bool            mSetStyle:1;      ///< Whether a new style needs to be set in the text-actor.
+  bool            mIsColorGlyph:1;  ///< Whether this character is an emoticon.
+  bool            mIsRightToLeft:1; ///< Whether this character is right to left.
 };
 typedef std::vector<CharacterLayoutInfo> CharacterLayoutInfoContainer;
 
@@ -205,11 +215,36 @@ struct WordLayoutInfo
   Size                              mSize;                      ///< Size of the word.
   float                             mAscender;                  ///< Max of all ascenders of all characters.
   TextSeparatorType                 mType;                      ///< Whether this word is a word separator, a line separator or is not a separator.
+  std::size_t                       mFirstCharacter;            ///< Index to the first character of the word within the paragraph.
   CharacterLayoutInfoContainer      mCharactersLayoutInfo;      ///< Layout info for all characters.
 };
 typedef std::vector<WordLayoutInfo> WordLayoutInfoContainer;
 
 /**
+ * Stores the reordered layout for right to left text.
+ */
+struct RightToLeftParagraphLayout
+{
+  RightToLeftParagraphLayout()
+  : mWordsLayoutInfo(),
+    mText(),
+    mTextStyles(),
+    mPreviousLayoutCleared( false )
+  {
+  }
+
+  WordLayoutInfoContainer mWordsLayoutInfo;         ///< Layout info for all words.
+  Text                    mText;                    ///< Stores the text.
+  Vector<TextStyle*>      mTextStyles;              ///< Stores the style per each character.
+  bool                    mPreviousLayoutCleared:1; ///< Whether the previous right to left layout has been cleared.
+
+  /**
+   * Clears the word layout vector, the text and the vector of styles.
+   */
+  void Clear();
+};
+
+/**
  * Layout information for a paragraph.
  */
 struct ParagraphLayoutInfo
@@ -224,7 +259,7 @@ struct ParagraphLayoutInfo
   /**
    * Default destructor.
    *
-   * Clears all words.
+   * Clears all words, deletes all text styles, the paragraph bidirectional info and all bidirectional infor for each line.
    */
   ~ParagraphLayoutInfo();
 
@@ -238,11 +273,30 @@ struct ParagraphLayoutInfo
    */
   ParagraphLayoutInfo& operator=( const ParagraphLayoutInfo& paragraph );
 
+  /**
+   * Deletes the bidirectional info for each line.
+   */
+  void ClearBidirectionalInfo();
+
+private:
+
+  /**
+   * Deletes all text styles.
+   */
+  void ClearStyles();
+
+public:
   Size                                          mSize;                       ///< Size of the paragraph.
   float                                         mAscender;                   ///< Max of all ascenders of all words.
   float                                         mLineHeightOffset;           ///< Line height offset.
+  std::size_t                                   mFirstCharacter;             ///< Index to the first character of the paragraph.
   std::size_t                                   mNumberOfCharacters;         ///< Stores the number of characters.
   WordLayoutInfoContainer                       mWordsLayoutInfo;            ///< Layout info for all words.
+  Text                                          mText;                       ///< Stores the text.
+  Vector<TextStyle*>                            mTextStyles;                 ///< Stores the style per each character.
+  RightToLeftParagraphLayout*                   mRightToLeftLayout;          ///< Stores the reordered layout for the paragraph.
+  TextProcessor::BidirectionalParagraphInfo*    mBidirectionalParagraphInfo; ///< Contains bidirectional info for the whole paragraph. Set to NULL if the paragraph has left to right characters only.
+  Vector<TextProcessor::BidirectionalLineInfo*> mBidirectionalLinesInfo;     ///< Contains bidirectional info for each laid-out line.
 };
 typedef std::vector<ParagraphLayoutInfo> ParagraphLayoutInfoContainer;
 
@@ -259,6 +313,13 @@ struct TextLayoutInfo
   TextLayoutInfo();
 
   /**
+   * Defualt destructor.
+   *
+   * Clears the paragraph vector, the ellipsis text and deletes all ellipsis styles.
+   */
+  ~TextLayoutInfo();
+
+  /**
    * Copy constructor.
    */
   TextLayoutInfo( const TextLayoutInfo& text );
@@ -268,12 +329,21 @@ struct TextLayoutInfo
    */
   TextLayoutInfo& operator=( const TextLayoutInfo& text );
 
+private:
+  /**
+   * Deletes all the ellipsis text styles.
+   */
+  void ClearStyles();
+
+public:
   Size                         mWholeTextSize;        ///< width and height of the whole text.
   float                        mMaxWordWidth;         ///< maximum width between all words.
   float                        mMaxItalicsOffset;     ///< When rendering text-view in offscreen an extra width offset is needed to prevent italic characters to be cut if they are in the right edge.
   std::size_t                  mNumberOfCharacters;   ///< Stores the number of characters.
   ParagraphLayoutInfoContainer mParagraphsLayoutInfo; ///< Layout information for all paragraphs.
   WordLayoutInfo               mEllipsizeLayoutInfo;  ///< Layout information for the ellipsize text.
+  Dali::Text                   mEllipsisText;         ///< The ellipsis text.
+  Vector<TextStyle*>           mEllipsisTextStyles;   ///< Stores the style per each character of the ellipsis text.
 };
 
 } // namespace TextViewProcessor
index a485a6e..40f1fab 100644 (file)
 #include <dali-toolkit/internal/controls/text-view/text-view-processor.h>
 
 // INTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
 #include <dali-toolkit/internal/controls/text-view/text-view-word-processor.h>
 #include <dali-toolkit/internal/controls/text-view/text-view-paragraph-processor.h>
 #include <dali-toolkit/internal/controls/text-view/text-view-processor-helper-functions.h>
 #include <dali-toolkit/internal/controls/text-view/text-processor.h>
+#include <dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.h>
 
 namespace Dali
 {
@@ -84,7 +86,8 @@ void UpdateLayoutInfo( TextLayoutInfo& textLayoutInfo )
 TextInfoIndices::TextInfoIndices()
 : mParagraphIndex( 0u ),
   mWordIndex( 0u ),
-  mCharacterIndex( 0u )
+  mCharacterIndex( 0u ),
+  mCharacterParagraphIndex( 0u )
 {
 }
 
@@ -93,7 +96,8 @@ TextInfoIndices::TextInfoIndices( const std::size_t paragraphIndex,
                                   const std::size_t characterIndex )
 : mParagraphIndex( paragraphIndex ),
   mWordIndex( wordIndex ),
-  mCharacterIndex( characterIndex )
+  mCharacterIndex( characterIndex ),
+  mCharacterParagraphIndex( 0u )
 {
 }
 
@@ -101,7 +105,8 @@ bool TextInfoIndices::operator==( const TextInfoIndices& indices ) const
 {
   return ( ( mParagraphIndex == indices.mParagraphIndex ) &&
            ( mWordIndex == indices.mWordIndex ) &&
-           ( mCharacterIndex == indices.mCharacterIndex ) );
+           ( mCharacterIndex == indices.mCharacterIndex ) &&
+           ( mCharacterParagraphIndex == indices.mCharacterParagraphIndex ) );
 }
 
 /////////////////////
@@ -114,8 +119,19 @@ TextLayoutInfo::TextLayoutInfo()
   mMaxItalicsOffset( 0.f ),
   mNumberOfCharacters( 0u ),
   mParagraphsLayoutInfo(),
-  mEllipsizeLayoutInfo()
+  mEllipsizeLayoutInfo(),
+  mEllipsisText( "..." ),
+  mEllipsisTextStyles()
 {
+  // Sets default styles for the default ellipsis text.
+  mEllipsisTextStyles.PushBack( new TextStyle() );
+  mEllipsisTextStyles.PushBack( new TextStyle() );
+  mEllipsisTextStyles.PushBack( new TextStyle() );
+}
+
+TextLayoutInfo::~TextLayoutInfo()
+{
+  ClearStyles();
 }
 
 TextLayoutInfo::TextLayoutInfo( const TextLayoutInfo& text )
@@ -124,8 +140,14 @@ TextLayoutInfo::TextLayoutInfo( const TextLayoutInfo& text )
   mMaxItalicsOffset( text.mMaxItalicsOffset ),
   mNumberOfCharacters( text.mNumberOfCharacters ),
   mParagraphsLayoutInfo( text.mParagraphsLayoutInfo ),
-  mEllipsizeLayoutInfo( text.mEllipsizeLayoutInfo )
+  mEllipsizeLayoutInfo( text.mEllipsizeLayoutInfo ),
+  mEllipsisText( text.mEllipsisText ),
+  mEllipsisTextStyles()
 {
+  for( Vector<TextStyle*>::ConstIterator it = text.mEllipsisTextStyles.Begin(), endIt = text.mEllipsisTextStyles.End(); it != endIt; ++it )
+  {
+    mEllipsisTextStyles.PushBack( new TextStyle( *(*it) ) );
+  }
 }
 
 TextLayoutInfo& TextLayoutInfo::operator=( const TextLayoutInfo& text )
@@ -138,11 +160,27 @@ TextLayoutInfo& TextLayoutInfo::operator=( const TextLayoutInfo& text )
     mNumberOfCharacters = text.mNumberOfCharacters;
     mParagraphsLayoutInfo = text.mParagraphsLayoutInfo;
     mEllipsizeLayoutInfo = text.mEllipsizeLayoutInfo;
-  }
+    mEllipsisText = text.mEllipsisText;
 
+    ClearStyles();
+
+    for( Vector<TextStyle*>::ConstIterator it = text.mEllipsisTextStyles.Begin(), endIt = text.mEllipsisTextStyles.End(); it != endIt; ++it )
+    {
+      mEllipsisTextStyles.PushBack( new TextStyle( *(*it) ) );
+    }
+  }
   return *this;
 }
 
+void TextLayoutInfo::ClearStyles()
+{
+  for( Vector<TextStyle*>::Iterator it = mEllipsisTextStyles.Begin(), endIt = mEllipsisTextStyles.End(); it != endIt; ++it )
+  {
+    delete *it;
+  }
+  mEllipsisTextStyles.Clear();
+}
+
 /////////////////////////////////////////////////////////////////////////////////////////////
 
 void CreateTextInfo( const MarkupProcessor::StyledTextArray& text,
@@ -152,9 +190,11 @@ void CreateTextInfo( const MarkupProcessor::StyledTextArray& text,
   // * Traverse the given text spliting it in paragraphs and each paragraph in words.
   // * White spaces and new paragraph characters are alone in one word.
   // * Bidirectional text is processed in each paragraph.
+  //     It creates the conversion tables
+  //     It does the ligatures if there is arabic glyphs.
+  //     It doesn't reorder the text as it must be done for each line not for the paragraph.
   // * Generates a layout data structure to store layout information (size, position, ascender, text direction, etc) and metrics of all characters.
-  // * Generates a text-actor data structure to store text, style and text-actors.
-  // TODO: finish and test the bidirectional implementation.
+  // * Store text for each paragraph and the style for each character.
 
   // Collect previously created text-actors.
   std::vector<TextActor> textActors;
@@ -168,49 +208,77 @@ void CreateTextInfo( const MarkupProcessor::StyledTextArray& text,
   }
 
   // Store the ellipsize layout info before clearing the previous created info.
+  // TODO: fix this. Don't clear the ellipsis layout, store it somewhere else ...
   const WordLayoutInfo ellipsizeInfo = relayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo;
+  Dali::Text           ellipsisText = relayoutData.mTextLayoutInfo.mEllipsisText;
+  Vector<TextStyle*>   ellipsisTextStyles = relayoutData.mTextLayoutInfo.mEllipsisTextStyles;
+  relayoutData.mTextLayoutInfo.mEllipsisTextStyles.Clear();
 
-  // clear previous created info.
+  // clear previously created info.
   relayoutData.mTextLayoutInfo = TextLayoutInfo();
   relayoutData.mCharacterLogicalToVisualMap.clear();
   relayoutData.mCharacterVisualToLogicalMap.clear();
 
   // Sets the ellipsize layout info.
   relayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = ellipsizeInfo;
+  relayoutData.mTextLayoutInfo.mEllipsisText = ellipsisText;
+  relayoutData.mTextLayoutInfo.mEllipsisTextStyles = ellipsisTextStyles;
 
   // Split the whole text in paragraphs.
-  std::vector<MarkupProcessor::StyledTextArray> paragraphs;
+  // It returns a vector of Text with all the paragraphs.
+  // and for each paragraph a vector of styles per character. TODO: don't create a style per character.
+  std::vector<Text> paragraphs;
+  std::vector< Vector<TextStyle*> > styles;
   TextProcessor::SplitInParagraphs( text,
-                                    paragraphs );
+                                    paragraphs,
+                                    styles );
+
+  // Reserve space for the current number of paragraphs.
+  relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.resize( paragraphs.size(), ParagraphLayoutInfo() );
 
   // Traverse all paragraphs
-  for( std::vector<MarkupProcessor::StyledTextArray>::const_iterator paragraphIt = paragraphs.begin(), paragraphEndIt = paragraphs.end(); paragraphIt != paragraphEndIt; ++paragraphIt )
+  std::size_t paragraphIndex = 0u;
+  std::vector<Text>::iterator paragraphIt, paragraphEndIt;
+  std::vector< Vector<TextStyle*> >::const_iterator styleIt, styleEndIt;
+  for( paragraphIt = paragraphs.begin(), paragraphEndIt = paragraphs.end(),
+         styleIt = styles.begin(), styleEndIt = styles.end();
+       ( paragraphIt != paragraphEndIt ) && ( styleIt != styleEndIt );
+       ++paragraphIndex,
+         ++paragraphIt,
+         ++styleIt )
   {
-    const MarkupProcessor::StyledTextArray& paragraph( *paragraphIt );
+    // Gets the paragraph and the styles for each character.
+    Text& paragraph( *paragraphIt );
+    const Vector<TextStyle*>& textStyles( *styleIt );
+
+    // Retrieve the data structure for the current paragraph.
+    ParagraphLayoutInfo& paragraphLayoutInfo = *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + paragraphIndex );
 
-    // Data structures for the new paragraph
-    ParagraphLayoutInfo paragraphLayoutInfo;
+    // Sets text and styles.
+    paragraphLayoutInfo.mText = paragraph;
+    paragraphLayoutInfo.mTextStyles = textStyles;
 
-    // Fills the paragraph data structures with the layout info.
-    CreateParagraphInfo( paragraph,
-                         relayoutData,
-                         paragraphLayoutInfo );
+    // Fills the paragraph data structure with the layout info.
 
-    if( 0u < paragraphLayoutInfo.mNumberOfCharacters )
+    if( !paragraph.IsEmpty() )
     {
+      CreateParagraphInfo( relayoutData,
+                           paragraphLayoutInfo );
+
       // do not add the line offset if the paragraph has no characters.
       paragraphLayoutInfo.mSize.height += layoutParameters.mLineHeightOffset;
       paragraphLayoutInfo.mLineHeightOffset = layoutParameters.mLineHeightOffset;
     }
     else
     {
-      // line height needs to be added for the last paragraph.
+      // This paragraph has no text. i.e. the previous paragraph ends with '\n'.
+      // Even though, line height needs to be set in order to align the whole text correctly.
 
       float lineHeight = 0.f;
       // Get the last character of the last paragraph.
-      if( !relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.empty() )
+      if( 0u < paragraphIndex )
       {
-        const ParagraphLayoutInfo& paragraphInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end() - 1u ) );
+        const ParagraphLayoutInfo& paragraphInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + ( paragraphIndex - 1u ) ) );
 
         const CharacterLayoutInfo characterInfo = GetLastCharacterLayoutInfo( paragraphInfo );
 
@@ -220,16 +288,21 @@ void CreateTextInfo( const MarkupProcessor::StyledTextArray& text,
       paragraphLayoutInfo.mSize.height = lineHeight;
     }
 
+    // Fills the conversion tables used to get the logical or visual position of a character is case there is right to left text.
+    // If there is right to left text, it needs to be updated every time the text is relaid-out.
+    for( std::size_t index = 0u; index < paragraphLayoutInfo.mNumberOfCharacters; ++index )
+    {
+      relayoutData.mCharacterLogicalToVisualMap.push_back( relayoutData.mTextLayoutInfo.mNumberOfCharacters + index );
+      relayoutData.mCharacterVisualToLogicalMap.push_back( relayoutData.mTextLayoutInfo.mNumberOfCharacters + index );
+    }
+
     // Update layout info for the whole text.
     UpdateSize( relayoutData.mTextLayoutInfo.mWholeTextSize, paragraphLayoutInfo.mSize, GrowHeight );
     relayoutData.mTextLayoutInfo.mNumberOfCharacters += paragraphLayoutInfo.mNumberOfCharacters;
-
-    // Add the paragraph to the current text.
-    relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.push_back( paragraphLayoutInfo );
   } // end of paragraphs
 }
 
-void UpdateTextInfo( const std::size_t position,
+void UpdateTextInfo( std::size_t position,
                      const MarkupProcessor::StyledTextArray& text,
                      const TextView::LayoutParameters& layoutParameters,
                      TextView::RelayoutData& relayoutData )
@@ -242,7 +315,7 @@ void UpdateTextInfo( const std::size_t position,
   // * Merge the last paragraph of the new text to the last part or the split paragraph.
   // * Add paragraphs between first and last of the new text.
   // * Merge the first part of the split paragraph with the first paragraph of the new text.
-  // * Update layout info and create new text actors if needed.
+  // * Update the layout info for the whole text.
 
   // Early returns:
 
@@ -269,6 +342,15 @@ void UpdateTextInfo( const std::size_t position,
     DALI_ASSERT_ALWAYS( !"TextViewProcessor::UpdateTextInfo (insert). Trying to insert text out of bounds." );
   }
 
+
+  // TODO
+  // If in the insertion is involved right to left text,
+  // check the neighbour characters is needed.
+  //   i.e. Arabic characters may have four different glyphs (isolated, end, middle, begin).
+  //        So check the neighbours on each side is needed in order to render
+  //        the correct ligatures.
+
+
   TextView::RelayoutData relayoutDataForNewText;
 
   // Creates layout info for the given text.
@@ -277,8 +359,8 @@ void UpdateTextInfo( const std::size_t position,
                   layoutParameters,
                   relayoutDataForNewText );
 
-  // Update logical-to-visual and visual-to-logical tables.
-  // TODO: check that for mixed RTL/LTR text.
+  // Fills the conversion tables used to get the logical or visual position of a character is case there is right to left text.
+  // If there is right to left text, it needs to be updated every time the text is relaid-out.
   std::size_t index = 0u;
   for( std::size_t i = 0u; i < relayoutDataForNewText.mTextLayoutInfo.mNumberOfCharacters; ++i )
   {
@@ -335,6 +417,13 @@ void UpdateTextInfo( const std::size_t position,
 
         const WordLayoutInfo& wordLayoutInfo( *( paragraphLayoutInfo.mWordsLayoutInfo.end() - 1u ) );
         textInfoIndices.mCharacterIndex = wordLayoutInfo.mCharactersLayoutInfo.size();
+
+        // Sets the character index within the paragraph.
+        textInfoIndices.mCharacterParagraphIndex = 0u;
+        for( WordLayoutInfoContainer::const_iterator it = paragraphLayoutInfo.mWordsLayoutInfo.begin(), endIt = paragraphLayoutInfo.mWordsLayoutInfo.end(); it != endIt; ++it )
+        {
+          textInfoIndices.mCharacterParagraphIndex += wordLayoutInfo.mCharactersLayoutInfo.size();
+        }
       }
     }
   }
@@ -382,8 +471,8 @@ void UpdateTextInfo( const std::size_t position,
   UpdateLayoutInfo( relayoutData.mTextLayoutInfo );
 }
 
-void UpdateTextInfo( const std::size_t position,
-                     const std::size_t numberOfCharacters,
+void UpdateTextInfo( std::size_t position,
+                     std::size_t numberOfCharacters,
                      const TextView::LayoutParameters& layoutParameters,
                      TextView::RelayoutData& relayoutData,
                      const TextOperationOnRemove clearText )
@@ -414,7 +503,8 @@ void UpdateTextInfo( const std::size_t position,
   // Asserts if trying to delete text out of bounds.
   DALI_ASSERT_ALWAYS( position + numberOfCharacters <= relayoutData.mTextLayoutInfo.mNumberOfCharacters && "TextViewProcessor::UpdateTextInfo. ERROR: trying to delete characters out of boundary" );
 
-  // Remove characters from character to visual map and vs //TODO: check this for RTL text!!
+  // Remove characters from character to visual map and vs.
+  // If there is right to left text, it needs to be updated every time the text is relaid-out.
   relayoutData.mCharacterLogicalToVisualMap.erase( relayoutData.mCharacterLogicalToVisualMap.end() - numberOfCharacters, relayoutData.mCharacterLogicalToVisualMap.end() );
   relayoutData.mCharacterVisualToLogicalMap.erase( relayoutData.mCharacterVisualToLogicalMap.end() - numberOfCharacters, relayoutData.mCharacterVisualToLogicalMap.end() );
 
@@ -521,6 +611,19 @@ void UpdateTextInfo( const std::size_t position,
       // As paragraphIndexBegin has been increased just to not to remove the paragraph, decrease now is needed to access it.
       ParagraphLayoutInfo& paragraphLayout( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + textInfoIndicesBegin.mParagraphIndex - 1u ) );
 
+      // Remove the characters from the text and the styles.
+      paragraphLayout.mText.Remove( textInfoIndicesBegin.mCharacterParagraphIndex, paragraphLayout.mNumberOfCharacters - textInfoIndicesBegin.mCharacterParagraphIndex );
+
+      for( Vector<TextStyle*>::Iterator it = paragraphLayout.mTextStyles.Begin() + textInfoIndicesBegin.mCharacterParagraphIndex,
+             endIt = paragraphLayout.mTextStyles.End();
+           it != endIt;
+           ++it )
+      {
+        delete *it;
+      }
+      paragraphLayout.mTextStyles.Erase( paragraphLayout.mTextStyles.Begin() + textInfoIndicesBegin.mCharacterParagraphIndex,
+                                         paragraphLayout.mTextStyles.End() );
+
       if( ( textInfoIndicesBegin.mWordIndex + 1u < paragraphLayout.mWordsLayoutInfo.size() ) || ( 0u == textInfoIndicesBegin.mCharacterIndex ) )
       {
         // Remove extra words within current paragraph. (and current word if whole characters are removed)
@@ -577,6 +680,21 @@ void UpdateTextInfo( const std::size_t position,
       // Get the last paragraph.
       ParagraphLayoutInfo& paragraphLayout( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + paragraphIndex ) );
 
+      // Remove the characters from the text and the styles.
+      const std::size_t lastCharacterIndex = textInfoIndicesEnd.mCharacterParagraphIndex + 1u;
+
+      paragraphLayout.mText.Remove( 0u, lastCharacterIndex );
+
+      for( Vector<TextStyle*>::Iterator it = paragraphLayout.mTextStyles.Begin(),
+             endIt = paragraphLayout.mTextStyles.Begin() + lastCharacterIndex;
+           it != endIt;
+           ++it )
+      {
+        delete *it;
+      }
+      paragraphLayout.mTextStyles.Erase( paragraphLayout.mTextStyles.Begin(),
+                                         paragraphLayout.mTextStyles.Begin() + lastCharacterIndex );
+
       // Check if is needed remove the whole word. (If the character index is pointing just after the end of the word)
       const WordLayoutInfo& wordLayout( *( paragraphLayout.mWordsLayoutInfo.begin() + textInfoIndicesEnd.mWordIndex ) );
       bool removeWholeWord = wordLayout.mCharactersLayoutInfo.size() == textInfoIndicesEnd.mCharacterIndex + 1u;
@@ -634,6 +752,22 @@ void UpdateTextInfo( const std::size_t position,
     // Paragraph which contains the characters to be deleted.
     ParagraphLayoutInfo& paragraphLayout( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + textInfoIndicesBegin.mParagraphIndex ) );
 
+    // Remove the characters from the text and the styles.
+    const std::size_t firstCharacterIndex = textInfoIndicesBegin.mCharacterParagraphIndex;
+    const std::size_t lastCharacterIndex = textInfoIndicesEnd.mCharacterParagraphIndex + 1u;
+
+    paragraphLayout.mText.Remove( firstCharacterIndex, lastCharacterIndex - firstCharacterIndex );
+
+    for( Vector<TextStyle*>::Iterator it = paragraphLayout.mTextStyles.Begin() + firstCharacterIndex,
+           endIt = paragraphLayout.mTextStyles.Begin() + lastCharacterIndex;
+         it != endIt;
+         ++it )
+    {
+      delete *it;
+    }
+    paragraphLayout.mTextStyles.Erase( paragraphLayout.mTextStyles.Begin() + firstCharacterIndex,
+                                       paragraphLayout.mTextStyles.Begin() + lastCharacterIndex );
+
     // Remove the characters from the paragraph layout info. It returns whether the current paragraph can be merged with the next one.
     RemoveCharactersFromParagraphInfo( relayoutData,
                                        numberOfCharacters,
@@ -730,8 +864,8 @@ void UpdateTextInfo( const std::size_t position,
   relayoutData.mTextActorCache.InsertTextActors( removedTextActorsFromBegin );
 }
 
-void UpdateTextInfo( const std::size_t position,
-                     const std::size_t numberOfCharacters,
+void UpdateTextInfo( std::size_t position,
+                     std::size_t numberOfCharacters,
                      const MarkupProcessor::StyledTextArray& text,
                      const TextView::LayoutParameters& layoutParameters,
                      TextView::RelayoutData& relayoutData )
@@ -788,6 +922,17 @@ void UpdateTextInfo( const TextStyle& style,
   {
     ParagraphLayoutInfo& paragraph( *paragraphIt );
 
+    std::size_t index = 0u;
+    for( Vector<TextStyle*>::Iterator it = paragraph.mTextStyles.Begin(), endIt = paragraph.mTextStyles.End(); it != endIt; ++it )
+    {
+      (*it)->Copy( style, mask );
+
+      // Checks if the font family supports all glyphs. If not, chooses a most suitable one.
+      ChooseFontFamilyName( paragraph.mText[index], *(*it) );
+
+      ++index;
+    }
+
     for( WordLayoutInfoContainer::iterator wordIt = paragraph.mWordsLayoutInfo.begin(), wordEndIt = paragraph.mWordsLayoutInfo.end();
          wordIt != wordEndIt;
          ++wordIt )
@@ -800,11 +945,6 @@ void UpdateTextInfo( const TextStyle& style,
       {
         CharacterLayoutInfo& characterLayout( *characterIt );
 
-        characterLayout.mStyledText.mStyle.Copy( style, mask );
-
-        // Checks if the font family supports all glyphs. If not, chooses a most suitable one.
-        ChooseFontFamilyName( characterLayout.mStyledText );
-
         // Mark the character to be set the new style into the text-actor.
         characterLayout.mSetStyle = true;
       } // end characters
index b1426c9..eba4f52 100644 (file)
@@ -39,33 +39,6 @@ namespace
 
 const std::string EMOJI_FONT_NAME( "SamsungEmoji" ); // Emoticons font family name.
 
-/**
- * Updates the word size and ascender.
- *
- * It's called after deleting some characters.
- *
- * @param[in] wordLayout The word layout info.
- */
-void UpdateLayoutInfo( WordLayoutInfo& wordLayout )
-{
-  // Initialize layout info for the whole word.
-  wordLayout.mSize = Size::ZERO;
-  wordLayout.mAscender = 0.f;
-
-  // Traverse the character layout info to update the word layout.
-  for( CharacterLayoutInfoContainer::iterator layoutIt = wordLayout.mCharactersLayoutInfo.begin(), layoutEndIt = wordLayout.mCharactersLayoutInfo.end();
-       layoutIt != layoutEndIt;
-       ++layoutIt )
-  {
-    // Layout info for the current character.
-    CharacterLayoutInfo& layoutInfo( *layoutIt );
-
-    // Update layout info for the current word.
-    UpdateSize( wordLayout.mSize, layoutInfo.mSize );
-    wordLayout.mAscender = std::max( wordLayout.mAscender, layoutInfo.mAscender );
-  }
-}
-
 } // namespace
 
 /////////////////////
@@ -76,6 +49,7 @@ WordLayoutInfo::WordLayoutInfo()
 : mSize(),
   mAscender( 0.f ),
   mType( NoSeparator ),
+  mFirstCharacter( 0u ),
   mCharactersLayoutInfo()
 {
 }
@@ -88,6 +62,7 @@ WordLayoutInfo::WordLayoutInfo( const WordLayoutInfo& word )
 : mSize( word.mSize ),
   mAscender( word.mAscender ),
   mType( word.mType ),
+  mFirstCharacter( word.mFirstCharacter ),
   mCharactersLayoutInfo( word.mCharactersLayoutInfo )
 {
 }
@@ -97,89 +72,110 @@ WordLayoutInfo& WordLayoutInfo::operator=( const WordLayoutInfo& word )
   mSize = word.mSize;
   mAscender = word.mAscender;
   mType = word.mType;
+  mFirstCharacter = word.mFirstCharacter;
   mCharactersLayoutInfo = word.mCharactersLayoutInfo;
 
   return *this;
 }
 
-void CreateWordTextInfo( const MarkupProcessor::StyledTextArray& word,
+void CreateWordTextInfo( const Text& paragraph,
+                         Vector<TextStyle*>& textStyles,
                          WordLayoutInfo& wordLayoutInfo )
 {
   DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, "-->TextViewProcessor::CreateWordTextInfo\n" );
   // Split in characters.
-  for( MarkupProcessor::StyledTextArray::const_iterator charIt = word.begin(), charEndIt = word.end(); charIt != charEndIt; ++charIt )
+  std::size_t characterIndex = wordLayoutInfo.mFirstCharacter;
+  for( CharacterLayoutInfoContainer::iterator it = wordLayoutInfo.mCharactersLayoutInfo.begin(),
+         endIt =  wordLayoutInfo.mCharactersLayoutInfo.end();
+       it != endIt;
+       ++it, ++characterIndex )
   {
-    const MarkupProcessor::StyledText& styledText( *charIt );
+    // Gets a reference of the character's layout info.
+    CharacterLayoutInfo& characterLayoutInfo( *it );
+
+    // Gets the character and the style for that character from the paragraph.
+    Character character = paragraph[characterIndex];
+    TextStyle* textStyle = *( textStyles.Begin() + characterIndex );
 
-    const std::size_t length = styledText.mText.GetLength();
+    // Checks whether the character is an emoticon.
+    characterLayoutInfo.mIsColorGlyph = GlyphImage::IsColorGlyph( character );
+    DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, "  Is color glyph: %s\n", ( characterLayoutInfo.mIsColorGlyph ? "True" : "False" ) );
 
-    // It could be a group of characters.
-    for( std::size_t index = 0u; index < length; ++index )
+    if( characterLayoutInfo.mIsColorGlyph )
     {
-      MarkupProcessor::StyledText styledCharacter;
-      styledCharacter.mStyle = styledText.mStyle;
-      Character character = styledText.mText[index];
-      styledCharacter.mText.Append( character );
+      // If the character is an emoticon a predefined font is set.
+      textStyle->SetFontName( EMOJI_FONT_NAME );
+    }
+    else
+    {
+      // Checks if the font family and the font style set in the text style supports the character.
+      // If not, it chooses the right font for the given character and style.
+      ChooseFontFamilyName( character, *textStyle );
+    }
 
-      // Create layout character info.
-      CharacterLayoutInfo characterLayoutInfo;
+    // Checks whether the charcter is right to left.
+    const Character::CharacterDirection direction = character.GetCharacterDirection();
+    characterLayoutInfo.mIsRightToLeft = ( ( direction == Character::RightToLeft ) ||
+                                           ( direction == Character::RightToLeftWeak ) );
 
-      characterLayoutInfo.mIsColorGlyph = GlyphImage::IsColorGlyph( character );
-      DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, "  Is color glyph: %s\n", ( characterLayoutInfo.mIsColorGlyph ? "True" : "False" ) );
+    // Gets the metrics of the font.
+    const Font font = Font::New( FontParameters( textStyle->GetFontName(), textStyle->GetFontStyle(), textStyle->GetFontPointSize() ) );
+    const Font::Metrics metrics = font.GetMetrics( character );
+    const float ascender = font.GetAscender();
 
-      if( characterLayoutInfo.mIsColorGlyph )
-      {
-        styledCharacter.mStyle.SetFontName( EMOJI_FONT_NAME );
-      }
-      else
-      {
-        //Choose the right font for the given character and style.
-        ChooseFontFamilyName( styledCharacter );
-      }
-
-      // Gets the metrics of the font.
-      const Font font = Font::New( FontParameters( styledCharacter.mStyle.GetFontName(), styledCharacter.mStyle.GetFontStyle(), styledCharacter.mStyle.GetFontPointSize() ) );
-      const Font::Metrics metrics = font.GetMetrics( character );
-      const float ascender = font.GetAscender();
+    // Fill Natural size info for current character.
 
-      // The font line's height is used as character's height.
-      characterLayoutInfo.mSize.height = font.GetLineHeight();
+    // The font line's height is used as character's height.
+    characterLayoutInfo.mSize.height = font.GetLineHeight();
 
-      // The character's advance is used as charcter's width.
-      characterLayoutInfo.mSize.width = metrics.GetAdvance();
+    // The character's advance is used as charcter's width.
+    characterLayoutInfo.mSize.width = metrics.GetAdvance();
 
-      // The ascender and bearing are used to position correctly glyphs of different font sizes.
-      characterLayoutInfo.mAscender = ascender;
-      characterLayoutInfo.mBearing = metrics.GetBearing();
-
-      if( character.IsNewLine() && !characterLayoutInfo.mIsColorGlyph )
-      {
-        // A new paragraph character doesn't have any width.
-        characterLayoutInfo.mSize.width = 0.f;
-      }
+    // The ascender and bearing are used to position correctly glyphs of different font sizes.
+    characterLayoutInfo.mAscender = ascender;
+    characterLayoutInfo.mBearing = metrics.GetBearing();
 
-      // Set's the underline thickness and position.
-      // Both thickness and position includes the vertical pad adjust used in effects like glow or shadow.
-      if( styledCharacter.mStyle.IsUnderlineEnabled() )
-      {
-        characterLayoutInfo.mUnderlineThickness = font.GetUnderlineThickness();
-        characterLayoutInfo.mUnderlinePosition = font.GetUnderlinePosition();
-      }
+    if( character.IsNewLine() && !characterLayoutInfo.mIsColorGlyph )
+    {
+      // A new paragraph character '\n'  doesn't have any width.
+      characterLayoutInfo.mSize.width = 0.f;
+    }
 
-      // stores the styled text.
-      characterLayoutInfo.mStyledText.mText = styledCharacter.mText;
-      characterLayoutInfo.mStyledText.mStyle = styledCharacter.mStyle;
+    // Set's the underline thickness and position.
+    // Both thickness and position includes the vertical pad adjust used in effects like glow or shadow.
+    if( textStyle->IsUnderlineEnabled() )
+    {
+      characterLayoutInfo.mUnderlineThickness = font.GetUnderlineThickness();
+      characterLayoutInfo.mUnderlinePosition = font.GetUnderlinePosition();
+    }
 
-      // Add character layout info to the word layout info and update it.
-      wordLayoutInfo.mCharactersLayoutInfo.push_back( characterLayoutInfo );
-      UpdateSize( wordLayoutInfo.mSize, characterLayoutInfo.mSize );
-      wordLayoutInfo.mAscender = std::max( wordLayoutInfo.mAscender, characterLayoutInfo.mAscender );
-      wordLayoutInfo.mType = GetTextSeparatorType( character );
-    } // end of each character in the group of characters.
+    // Updates the word size and ascender.
+    UpdateSize( wordLayoutInfo.mSize, characterLayoutInfo.mSize );
+    wordLayoutInfo.mAscender = std::max( wordLayoutInfo.mAscender, characterLayoutInfo.mAscender );
   } // end of characters in the word.
   DALI_LOG_INFO( gTextViewProcessorLogFilter, Debug::General, "<--TextViewProcessor::CreateWordTextInfo\n" );
 }
 
+void UpdateLayoutInfo( WordLayoutInfo& wordLayout )
+{
+  // Initialize layout info for the whole word.
+  wordLayout.mSize = Size::ZERO;
+  wordLayout.mAscender = 0.f;
+
+  // Traverse the character layout info to update the word layout.
+  for( CharacterLayoutInfoContainer::iterator layoutIt = wordLayout.mCharactersLayoutInfo.begin(), layoutEndIt = wordLayout.mCharactersLayoutInfo.end();
+       layoutIt != layoutEndIt;
+       ++layoutIt )
+  {
+    // Layout info for the current character.
+    CharacterLayoutInfo& layoutInfo( *layoutIt );
+
+    // Update layout info for the current word.
+    UpdateSize( wordLayout.mSize, layoutInfo.mSize );
+    wordLayout.mAscender = std::max( wordLayout.mAscender, layoutInfo.mAscender );
+  }
+}
+
 void RemoveCharactersFromWordInfo( TextView::RelayoutData& relayoutData,
                                    const std::size_t numberOfCharacters,
                                    bool& mergeWords,
index 7b2845c..82f36f0 100644 (file)
@@ -36,13 +36,25 @@ namespace TextViewProcessor
 /**
  * Creates a data structure with info to layout the word, and data structures with useful info to modify the layout data structure if characters are added or removed.
  *
- * @param[in] word The styled word.
+ * @param[in] paragraphText The paragraph's text.
+ * @param[in] textStyles The styles for each character of the paragraph.
  * @param[out] wordLayoutInfo Layout info for all characters of the word.
  */
-void CreateWordTextInfo( const MarkupProcessor::StyledTextArray& word,
+void CreateWordTextInfo( const Text& paragraphText,
+                         Vector<TextStyle*>& textStyles,
                          WordLayoutInfo& wordLayoutInfo );
 
 /**
+ * Updates the word size and ascender.
+ *
+ * It's called after deleting some characters, split a word in two,
+ * or when a new word is created when right to left text is reordered.
+ *
+ * @param[in] wordLayout The word layout info.
+ */
+void UpdateLayoutInfo( WordLayoutInfo& wordLayout );
+
+/**
  * Removes a given number of characters from the given word.
  *
  * It calls the RemoveCharactersFromWord() function to remove characters from the word.
diff --git a/base/dali-toolkit/internal/factory/localized-control-factory-impl.cpp b/base/dali-toolkit/internal/factory/localized-control-factory-impl.cpp
deleted file mode 100644 (file)
index da07f2f..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2014 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.
- *
- */
-
-// CLASS HEADER
-#include "localized-control-factory-impl.h"
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/control-impl.h>
-#include <dali/integration-api/debug.h>
-
-// EXTERNAL INCLUDES
-#include <libintl.h>
-
-using std::string;
-using namespace Dali;
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace // unnamed namespace
-{
-
-
-}
-
-LocalizedControlFactory::LocalizedControlFactory()
-: mObjectEntries(),
-  mSignalsConnected( false )
-{
-}
-
-LocalizedControlFactory::~LocalizedControlFactory()
-{
-}
-
-Dali::Toolkit::TextView LocalizedControlFactory::CreateLocalizedTextView( const std::string& textID, const std::string& textDomain, const std::string& textViewTheme )
-{
-  if( !mSignalsConnected )
-  {
-    Stage::GetCurrent().GetObjectRegistry().ObjectDestroyedSignal().Connect( this, &LocalizedControlFactory::OnObjectDestruction );
-    Adaptor::Get().LanguageChangedSignal().Connect( this, &LocalizedControlFactory::OnLanguageChanged );
-    mSignalsConnected = true;
-  }
-
-  const string& localizedText = dgettext(textDomain.c_str(), textID.c_str());
-  Dali::Toolkit::TextView textView = Dali::Toolkit::TextView::New();
-  textView.SetText(localizedText);
-
-  LocalisedStringInfo info(textID, textDomain, textViewTheme);
-
-  mObjectEntries[textView.GetObjectPtr()] = info;
-
-  return textView;
-}
-
-void LocalizedControlFactory::OnObjectDestruction( const Dali::RefObject* objectPointer )
-{
-  if(!mObjectEntries.empty())
-  {
-    //Needs optimization. All the destructed objects are currently checked for existence in entries.
-    mObjectEntries.erase(objectPointer);
-  }
-}
-
-void LocalizedControlFactory::OnLanguageChanged( Dali::Adaptor& adaptor)
-{
-  if(!mObjectEntries.empty())
-  {
-    ObjectEntriesIterator iter = mObjectEntries.begin();
-    ObjectEntriesIterator iterEnd = mObjectEntries.end();
-    while(iter != iterEnd)
-    {
-      RefObject* refObjectPtr = const_cast<RefObject*> (iter->first);
-      BaseHandle handle(static_cast<BaseObject*>(refObjectPtr));
-      LocalisedStringInfo info = iter->second;
-
-      const string& localizedText = dgettext(info.textDomain.c_str(), info.textID.c_str());
-
-      Toolkit::TextView textView =  Dali::Toolkit::TextView::DownCast( handle );
-
-      if(textView)
-      {
-        textView.SetText( localizedText );
-      }
-      else
-      {
-        DALI_ASSERT_ALWAYS(false && "Corrupt TextView internal pointer in entries!");
-      }
-
-      ++iter;
-    }
-  }
-}
-
-
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
diff --git a/base/dali-toolkit/internal/factory/localized-control-factory-impl.h b/base/dali-toolkit/internal/factory/localized-control-factory-impl.h
deleted file mode 100644 (file)
index ac49226..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-#ifndef __DALI_TOOLKIT_INTERNAL_LOCALIZED_CONTROL_FACTORY_H__
-#define __DALI_TOOLKIT_INTERNAL_LOCALIZED_CONTROL_FACTORY_H__
-
-/*
- * Copyright (c) 2014 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 <string>
-#include <set>
-
-// INTERNAL INCLUDES
-#include <dali/dali.h>
-#include <dali-toolkit/public-api/factory/localized-control-factory.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-/**
- * @copydoc Toolkit::LocalizedControlFactory
- */
-class LocalizedControlFactory : public Dali::BaseObject, public ConnectionTracker
-{
-public:
-
-  /**
-   * Structure used to store/retrieve localisation info.
-   */
-  struct LocalisedStringInfo
-  {
-    LocalisedStringInfo()
-    {
-    }
-
-    LocalisedStringInfo(std::string id, std::string domain, std::string theme)
-    : textID(id),
-      textDomain(domain),
-      textViewTheme(theme)
-    {
-
-    }
-
-    std::string textID;
-    std::string textDomain;
-    std::string textViewTheme;
-  };
-
-  typedef std::map< const Dali::RefObject*, LocalisedStringInfo > ObjectEntriesContainer;
-  typedef ObjectEntriesContainer::iterator ObjectEntriesIterator;
-  typedef ObjectEntriesContainer::const_iterator ObjectEntriesConstIterator;
-
-  /**
-   * Construct a new LocalizedControlFactory.
-   */
-  LocalizedControlFactory();
-
-  /**
-   * @copydoc Toolkit::LocalizedControlFactory::CreateLocalizedTextView
-   */
-  Dali::Toolkit::TextView CreateLocalizedTextView( const std::string& textID, const std::string& textDomain, const std::string& textViewTheme );
-
-protected:
-
-  /**
-   * Destructor
-   */
-  virtual ~LocalizedControlFactory();
-
-private:
-
-  /**
-   * Callback for Object destructed signal.
-   * @param objectPointer Pointer to a RefObject
-   */
-  void OnObjectDestruction( const Dali::RefObject* objectPointer );
-
-  /**
-   * Callback for language changed signal.
-   * @param adaptor Reference to a Dali::Adaptor instance
-   */
-  void OnLanguageChanged( Dali::Adaptor& adaptor);
-
-private:
-
-  // Undefined
-  LocalizedControlFactory(const LocalizedControlFactory&);
-  LocalizedControlFactory& operator=(const LocalizedControlFactory& rhs);
-
-private:
-
-  ObjectEntriesContainer mObjectEntries;
-  bool mSignalsConnected:1;
-
-};
-
-} // namespace Internal
-
-inline Internal::LocalizedControlFactory& GetImpl(Dali::Toolkit::LocalizedControlFactory& obj)
-{
-  DALI_ASSERT_ALWAYS(obj);
-
-  Dali::BaseObject& handle = obj.GetBaseObject();
-
-  return static_cast<Internal::LocalizedControlFactory&>(handle);
-}
-
-inline const Internal::LocalizedControlFactory& GetImpl(const Dali::Toolkit::LocalizedControlFactory& obj)
-{
-  DALI_ASSERT_ALWAYS(obj);
-
-  const Dali::BaseObject& handle = obj.GetBaseObject();
-
-  return static_cast<const Internal::LocalizedControlFactory&>(handle);
-}
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_LOCALIZED_CONTROL_FACTORY_H__
index 4fa6bf8..5e8af9c 100644 (file)
@@ -47,6 +47,7 @@ toolkit_base_src_files = \
    $(toolkit_base_src_dir)/controls/text-view/split-by-char-policies.cpp   \
    $(toolkit_base_src_dir)/controls/text-view/text-actor-cache.cpp   \
    $(toolkit_base_src_dir)/controls/text-view/text-processor.cpp   \
+   $(toolkit_base_src_dir)/controls/text-view/text-processor-bidirectional-info.cpp  \
    $(toolkit_base_src_dir)/controls/text-view/text-view-impl.cpp   \
    $(toolkit_base_src_dir)/controls/text-view/text-view-character-processor.cpp  \
    $(toolkit_base_src_dir)/controls/text-view/text-view-paragraph-processor.cpp  \
@@ -54,7 +55,6 @@ toolkit_base_src_files = \
    $(toolkit_base_src_dir)/controls/text-view/text-view-processor-dbg.cpp  \
    $(toolkit_base_src_dir)/controls/text-view/text-view-processor-helper-functions.cpp  \
    $(toolkit_base_src_dir)/controls/text-view/text-view-word-processor.cpp  \
-   $(toolkit_base_src_dir)/factory/localized-control-factory-impl.cpp \
    $(toolkit_base_src_dir)/focus-manager/focus-manager-impl.cpp \
    $(toolkit_base_src_dir)/focus-manager/keyboard-focus-manager-impl.cpp \
    $(toolkit_base_src_dir)/focus-manager/keyinput-focus-manager-impl.cpp \
index 57be231..acf1ced 100644 (file)
@@ -116,9 +116,10 @@ StyleManager::StyleManager()
 
   RequestDefaultTheme();
 
-  if( Adaptor::IsAvailable() )
+  StyleMonitor styleMonitor( StyleMonitor::Get() );
+  if( styleMonitor )
   {
-    StyleMonitor::Get().StyleChangeSignal().Connect( this, &StyleManager::StyleMonitorChange );
+    styleMonitor.StyleChangeSignal().Connect( this, &StyleManager::StyleMonitorChange );
   }
 }
 
index e45436f..74720d0 100644 (file)
@@ -206,6 +206,7 @@ void SetupBackgroundActor( Actor actor, Property::Index constrainingIndex, const
 {
   actor.SetColor( color );
   actor.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
+  actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
   actor.SetZ( BACKGROUND_ACTOR_Z_POSITION );
 
   Constraint constraint = Constraint::New<Vector3>( constrainingIndex,
index 951c2b6..b72f20f 100644 (file)
@@ -324,6 +324,8 @@ public:
    * @brief Sets the background color of the control.
    *
    * @param[in] color The required background color of the control
+   *
+   * @note The background color fully blends with the actor color.
    */
   void SetBackgroundColor( const Vector4& color );
 
diff --git a/base/dali-toolkit/public-api/factory/localized-control-factory.cpp b/base/dali-toolkit/public-api/factory/localized-control-factory.cpp
deleted file mode 100644 (file)
index d8999c1..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2014 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.
- *
- */
-
-// CLASS HEADER
-
-#include <dali-toolkit/public-api/factory/localized-control-factory.h>
-
-// EXTERNAL INCLUDES
-
-// INTERNAL INCLUDES
-
-#include <dali-toolkit/internal/factory/localized-control-factory-impl.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-Dali::Toolkit::TextView LocalizedControlFactory::CreateLocalizedTextView( const std::string& textID, const std::string& textDomain, const std::string& textViewTheme )
-{
-  LocalizedControlFactory factory = Get();
-  return GetImpl(factory).CreateLocalizedTextView(textID, textDomain, textViewTheme);
-}
-
-LocalizedControlFactory::LocalizedControlFactory()
-{
-}
-
-LocalizedControlFactory::~LocalizedControlFactory()
-{
-}
-
-LocalizedControlFactory LocalizedControlFactory::Get()
-{
-  LocalizedControlFactory factory;
-
-  // Check whether the focus factory is already created
-  SingletonService singletonService( SingletonService::Get() );
-  if ( singletonService )
-  {
-    Dali::BaseHandle handle = singletonService.GetSingleton(typeid(LocalizedControlFactory));
-    if(handle)
-    {
-      // If so, downcast the handle of singleton to focus factory
-      factory = LocalizedControlFactory(dynamic_cast<Internal::LocalizedControlFactory*>(handle.GetObjectPtr()));
-    }
-
-    if(!factory)
-    {
-      // If not, create the focus factory and register it as a singleton
-      factory = LocalizedControlFactory(new Internal::LocalizedControlFactory());
-      singletonService.Register(typeid(factory), factory);
-    }
-  }
-
-  return factory;
-}
-
-LocalizedControlFactory::LocalizedControlFactory(Internal::LocalizedControlFactory *impl)
-  : BaseHandle(impl)
-{
-}
-
-} // namespace Toolkit
-
-} // namespace Dali
diff --git a/base/dali-toolkit/public-api/factory/localized-control-factory.h b/base/dali-toolkit/public-api/factory/localized-control-factory.h
deleted file mode 100644 (file)
index 6276550..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-#ifndef __DALI_TOOLKIT_LOCALIZED_CONTROL_FACTORY_H__
-#define __DALI_TOOLKIT_LOCALIZED_CONTROL_FACTORY_H__
-
-/*
- * Copyright (c) 2014 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.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/text-view/text-view.h>
-
-namespace Dali DALI_IMPORT_API
-{
-
-namespace Toolkit
-{
-
-namespace Internal DALI_INTERNAL
-{
-class LocalizedControlFactory;
-}
-
-/**
- * @brief This class provides functionality for creating controls which have localized text.
- *
- * This class keeps track of objects created using its factory methods, and updates them
- * when the system language changes.
- *
- * Warning: If the developer calls SetText on the object to overwrite the managed TextView,
- * then it leads to an inconsistent state where the object will be overwritten with the
- * localized text when language/locale changes.
- */
-
-class LocalizedControlFactory : public BaseHandle
-{
-public:
-
-  /**
-   * @brief Creates a localized TextView, which is automatically updated when the locale or language changes.
-   *
-   * @pre The LocalizedControlFactory has been initialized.
-   *
-   * @param textID The id of the localized text with which a platform request (gettext) for localized text can be made.
-   * @param textDomain The text domain for the localized text. Eg "sys_string"
-   * @param textViewTheme A string containing style info about various properties of TextView for different
-   *        locale/language.
-   * @return handle to a new localized TextView
-   */
-  static Dali::Toolkit::TextView CreateLocalizedTextView( const std::string& textID, const std::string& textDomain = "sys_string", const std::string& textViewTheme = "{}" );
-
-
-private:
-
-  /**
-   * @brief Create a LocalizedControlFactory handle; this can be initialised with LocalizedControlFactory::New().
-   *
-   * Calling member functions with an uninitialised handle is not allowed.
-   */
-  LocalizedControlFactory();
-
-  /**
-   * @brief Destructor
-   *
-   * This is non-virtual since derived Handle types must not contain data or virtual methods.
-   */
-  ~LocalizedControlFactory();
-
-  /**
-   * @brief Get the singleton of LocalizedControlFactory object.
-   *
-   * @return A handle to the LocalizedControlFactory control.
-   */
-  static LocalizedControlFactory Get();
-
-  /**
-   * @brief Allows the creation of this Control from an Internal::LocalizedControlFactory pointer.
-   *
-   * @param[in]  impl  A pointer to the internal LocalizedControlFactory.
-   */
-  LocalizedControlFactory(Internal::LocalizedControlFactory *impl);
-}; // class LocalizedControlFactory
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_LOCALIZED_CONTROL_FACTORY_H__
index e46991d..d497cea 100755 (executable)
@@ -43,7 +43,6 @@ public_api_base_src_files = \
   $(public_api_base_src_dir)/controls/table-view/table-view.cpp \
   $(public_api_base_src_dir)/controls/text-input/text-input.cpp \
   $(public_api_base_src_dir)/controls/text-view/text-view.cpp \
-  $(public_api_base_src_dir)/factory/localized-control-factory.cpp \
   $(public_api_base_src_dir)/focus-manager/focus-manager.cpp \
   $(public_api_base_src_dir)/focus-manager/keyboard-focus-manager.cpp \
   $(public_api_base_src_dir)/focus-manager/keyinput-focus-manager.cpp \
@@ -126,9 +125,6 @@ public_api_base_text_input_header_files = \
 public_api_base_text_view_header_files = \
   $(public_api_base_src_dir)/controls/text-view/text-view.h
 
-public_api_base_factory_header_files = \
-  $(public_api_base_src_dir)/factory/localized-control-factory.h
-
 public_api_base_focus_manager_header_files = \
   $(public_api_base_src_dir)/focus-manager/keyinput-focus-manager.h \
   $(public_api_base_src_dir)/focus-manager/focus-manager.h \
index 3168719..86111b2 100644 (file)
@@ -137,7 +137,6 @@ publicapibasescrollview_HEADERS = $(public_api_base_scroll_view_header_files)
 publicapibasetableview_HEADERS = $(public_api_base_table_view_header_files)
 publicapibasetextview_HEADERS = $(public_api_base_text_view_header_files)
 publicapibasetextinput_HEADERS = $(public_api_base_text_input_header_files)
-publicapibasefactory_HEADERS = $(public_api_base_factory_header_files)
 publicapibasefocusmanager_HEADERS = $(public_api_base_focus_manager_header_files)
 publicapibasemarkupprocessor_HEADERS = $(public_api_base_markup_processor_header_files)
 publicapibaseshadereffects_HEADERS = $(public_api_base_shader_effects_header_files)
diff --git a/docs/content/images/texture-atlas/atlas-size.jpg b/docs/content/images/texture-atlas/atlas-size.jpg
new file mode 100644 (file)
index 0000000..084278d
Binary files /dev/null and b/docs/content/images/texture-atlas/atlas-size.jpg differ
diff --git a/docs/content/images/texture-atlas/atlas.jpg b/docs/content/images/texture-atlas/atlas.jpg
new file mode 100644 (file)
index 0000000..d2e03b2
Binary files /dev/null and b/docs/content/images/texture-atlas/atlas.jpg differ
diff --git a/docs/content/images/texture-atlas/compression-example.jpg b/docs/content/images/texture-atlas/compression-example.jpg
new file mode 100644 (file)
index 0000000..474c572
Binary files /dev/null and b/docs/content/images/texture-atlas/compression-example.jpg differ
diff --git a/docs/content/images/texture-atlas/compression-options.jpg b/docs/content/images/texture-atlas/compression-options.jpg
new file mode 100644 (file)
index 0000000..1540315
Binary files /dev/null and b/docs/content/images/texture-atlas/compression-options.jpg differ
diff --git a/docs/content/images/texture-atlas/example-code.jpg b/docs/content/images/texture-atlas/example-code.jpg
new file mode 100644 (file)
index 0000000..4e2b576
Binary files /dev/null and b/docs/content/images/texture-atlas/example-code.jpg differ
diff --git a/docs/content/images/texture-atlas/image-wall.jpg b/docs/content/images/texture-atlas/image-wall.jpg
new file mode 100644 (file)
index 0000000..f06d258
Binary files /dev/null and b/docs/content/images/texture-atlas/image-wall.jpg differ
diff --git a/docs/content/images/texture-atlas/texture-packer-add-sprites.jpg b/docs/content/images/texture-atlas/texture-packer-add-sprites.jpg
new file mode 100644 (file)
index 0000000..67b65e7
Binary files /dev/null and b/docs/content/images/texture-atlas/texture-packer-add-sprites.jpg differ
diff --git a/docs/content/images/texture-atlas/texture-packer-preferences.jpg b/docs/content/images/texture-atlas/texture-packer-preferences.jpg
new file mode 100644 (file)
index 0000000..fa0b067
Binary files /dev/null and b/docs/content/images/texture-atlas/texture-packer-preferences.jpg differ
diff --git a/docs/content/images/texture-atlas/texture-packer-publish.jpg b/docs/content/images/texture-atlas/texture-packer-publish.jpg
new file mode 100644 (file)
index 0000000..e1564b0
Binary files /dev/null and b/docs/content/images/texture-atlas/texture-packer-publish.jpg differ
diff --git a/docs/content/images/texture-atlas/texture-packer-startup.jpg b/docs/content/images/texture-atlas/texture-packer-startup.jpg
new file mode 100644 (file)
index 0000000..5ed29b5
Binary files /dev/null and b/docs/content/images/texture-atlas/texture-packer-startup.jpg differ
index 53851e3..61619dd 100644 (file)
  * - \link resource-tracking Resource Tracking \endlink
  * - \link performance-profiling Performance Profiling \endlink
  *
-*/
+ * \section Performance
+ * - \link performance-tips Performance Tips \endlink
+ * - \link texture-atlases Texture Atlases  \endlink
+ * - \link Texture_Compression Compressing Textures \endlink
+ *
+ */
 
 /*! \page scene-graph
  *
index d95a60d..c4a1d98 100644 (file)
  * <h2 class="pg">Background</h2>
  * The Dali rendering pipeline has 2 stages.
  * Each stage is typically run once per frame.
- *
- * <ul>
- * <li> 1. Update
+ * <h3> 1. Update </h3>
  * <ul>
- * <li> Run animations
- * <li> Run constraints
- * <li> Run physics
- * <li> Update the scene-graph
+ * <li> Run animations</li>
+ * <li> Run constraints</li>
+ * <li> Run physics</li>
+ * <li> Update the scene-graph</li>
  * </ul>
- * <li> 2. Render
+ * <h3> 2. Render </h3>
  * <ul>
- * <li> Upload 3D data using OpenGL ( textures, vertex buffers etc).
- * <li> Draw the scene using OpenGL
- * </ul>
+ * <li> Upload 3D data using OpenGL ( textures, vertex buffers etc).</li>
+ * <li> Draw the scene using OpenGL</li>
  * </ul>
  *
+ *
  * To run at 60 FPS (16 milliseconds per frame), it is recommended to stay below the following times:
  * <ul>
- * <li> Update: 4 milliseconds
- * <li> Render: 4 milliseconds
+ * <li> Update: 4 milliseconds</li>
+ * <li> Render: 4 milliseconds</li>
  * </ul>
  *
  * This will leave enough time for the output to be composited (if the system uses a compositor) and to avoid using
  * If nothing is animating Dali will enter a paused state to save power. At this
  * point nothing will be logged.
  *
- * <h2 class="pg">Performance advice </h2>
- *
- *
- * <h3> Tips to reduce update times: </h3>
- * <ul>
- * <li> Keep the actor count as small as possible.
- * <ul>
- * <li> Less actors == less processing
- * <li> Try to keep invisible or un-used actors off the stage. Don't have hidden views on the stage.
- * </ul>
- * <li> Ensure constraints are kept as simple as possible
- * </ul>
- *
- * <h3> Tips to reduce render times: </h3>
- *
- * <ul>
- * <li> Keep the visible actor count as small as possible == less draw calls
- * <li> If using a fixed set of images, try pre-generating a texture-atlas.
- * <ul>
- * <li> For each image within the Atlas, use ImageActor.SetPixelArea()  to use it.
- * <li> This reduces texture state changes when rendering.
- * </ul>
- * <li> Try to use 9-patch when you need to stretch an image while maintaining the border size.
- * <ul>
- * <li> See ImageActor::STYLE_NINE_PATCH
- * </ul>
- * <li> When using layers try to disable the depth test to avoid the depth buffer being cleared.
- * <li> If writing custom shaders, try to keep them as simple as possible.
- * <li> Try to keep texture sizes as small as possible.
- * </ul>
  *
  *  <h2 class="pg">Application profiling</h2>
  *
  * <li> DALI_RENDER_END. Dali render task has finished
  * </ul>
  *
- * <h3> Checking ftrace is working on Tizen</h3>
+ * <h3> Checking ftrace is working on Linux</h3>
  *
  * Documentation for ftrace:
  * Follow these instructions to ensure the debugfs has been mounted, and the kernel you are using
diff --git a/docs/content/programming-guide/performance-tips.h b/docs/content/programming-guide/performance-tips.h
new file mode 100644 (file)
index 0000000..969054a
--- /dev/null
@@ -0,0 +1,39 @@
+/*! \page performance-tips Performance Tips
+
+
+<table>
+  <tr>
+    <th>High CPU occupancy <br></th>
+  </tr>
+  <tr>
+  <td>
+       - Try to reduce actor count ( less actors == less processing) <br>
+       - Delete any actors that are not visible, or move them off stage <br>
+       - Use TextureAtlases ( greatly reduces OpenGL driver calls to glBindTexture <br>
+       - Optimise / reduce any constraints used
+       </td>
+       </tr>
+</table>
+<br><br>
+<table>
+  <tr>
+    <th>High GPU occupancy <br></th>
+  </tr>
+  <tr>
+  <td>
+       - Reduce visible actor count ( == less draw calls) <br>
+       - For 2D UI graphics which require no z sorting use @code Actor::SetDrawMode( DrawMode::OVERLAY );
+// In this mode depth testing is turned off and order is determined by the hierachy (depth-first search order).
+        @endcode
+       - Use TextureAtlases ( reduces state changes in the GPU) <br>
+       - Use compressed textures
+       - Use lower quality textures, e.g. smaller, lower number of bits per pixel
+       - Use Dali::NinePatchImage  where possible.
+       - Avoid using too many textures which contain alpha and require blending
+       - Avoid using too many Dali::Layer with depth testing enabled. Otherwise the layer has to clear the depth buffer.
+       - Optimise any shaders used. Pixel shaders should be kept as lean as possible.
+       </td>
+       </tr>
+</table>
+
+ */
diff --git a/docs/content/programming-guide/texture-atlases.h b/docs/content/programming-guide/texture-atlases.h
new file mode 100644 (file)
index 0000000..b664d3e
--- /dev/null
@@ -0,0 +1,261 @@
+/*! \page texture-atlases Texture Atlases
+ *
+ * <h2 class="pg">Using Texture Atlases in DALi </h2>
+ *
+ *
+ * <h3> Example demo application </h3>
+
+  \image html image-wall.jpg
+
+
+<h3> Application above is running slow as there are many small individual images displayed (50)</h3>
+
+<table>
+  <tr>
+    <td> Launch Time </td>
+    <td> Slow </td>
+    <td> Has to perform: <br>- 50 file open requests and multiple reads for each image</td>
+  </tr>
+  <tr>
+    <td> Memory Usage </td>
+    <td> High </td>
+    <td> Has to create:
+      <br>- 50 Dali::Image objects
+      <br>- 50 OpenGL Textures
+    </td>
+  </tr>
+  <tr>
+    <td>Rendering Performance </td>
+    <td> Slow </td>
+    <td> Has to perform:
+      <br>- 50 glBindTexture calls per frame ( each OpenGL calls takes time)
+      <br>- 50 a frame = 3000 calls per second @60 FPS.
+      <br>- Texture switching is a major state change in the GPU
+    </td>
+  </tr>
+</table>
+<br><br>
+
+
+* <h3> Solutions to problem: Use a Texture Atlas</h3>
+
+A texture atlas is simply one larger image that contains smaller images. A texture atlas is sometimes called a
+sprite sheet, bitmap sheet or texture pack.
+
+ \image html atlas.jpg
+
+<br>
+Dali::ImageActor has the ability to display a portion of an image using ImageActor::PixelArea setting.
+For example to display the first 3 image in the atlas
+
+  \image html example-code.jpg
+
+<h3> Result of using an Atlas</h3>
+<table>
+  <tr>
+    <td> Launch Time </td>
+    <td> Fast </td>
+    <td> Has to perform: <br>- 1 file open request </td>
+  </tr>
+  <tr>
+    <td> Memory Usage </td>
+    <td> Better </td>
+    <td> Has to create:
+      <br>- 1 Dali::Image objects
+      <br>- 1 OpenGL Textures
+    </td>
+  </tr>
+  <tr>
+    <td>Rendering Performance </td>
+    <td> Fast </td>
+    <td> Has to perform:
+      <br>- 1 glBindTexture calls per frame ( each OpenGL calls takes time)
+      <br>- 1 a frame = 6- calls per second @60 FPS.
+    </td>
+  </tr>
+</table>
+<br>
+<h2> Atlas creation guide </h2>
+
+Many tools exist for creating texture atlases.<br>
+In the following example we are using a tool called TexturePacker as DALi has an exporter script for it.
+The exporter automatically generates a source file that has the ImageActor::PixelArea pre-defined.
+<br>
+<ul>
+  <li> Download http://www.codeandweb.com/texturepacker </li>
+  <li> Launch TexturePacker </li>
+  <li> Go to the menu File -> Preferences</li>
+  <li> Set the "Exporter directory" to be the location of dali-toolkit/texture-atlas-exporter  <br></li>
+  \image html texture-packer-preferences.jpg
+  <br>
+  <li> <b> Restart the application! </b></li>
+  <li> Select DALi 3D framework for new project</li>
+  <br>
+  \image html texture-packer-startup.jpg
+  <br>
+  <li><h3> Create the atlas </h3> <br></li>
+  \image html texture-packer-add-sprites.jpg <br><br>
+  <li><h3> Click publish to produce the files </h3></li><br><br>
+  \image html texture-packer-publish.jpg  <br><br>
+</ul>
+<h2> Using the generated cpp file </h2>
+
+The generated cpp file contains 3 different ways of describing the atlas. <br>
+Copy and paste the section that best suits your application.
+<ul><li> Lookup table. Includes code for storing the table in a std::map for fast lookup.</li>
+<li> constants.  </li>
+<li> JavaScript property map ( see the Dali JavaScript programming guide on how to use it).
+</ul>
+<h3> Using the lookup table </h3>
+
+Cut and paste the lookup table code into your application.
+
+\code
+
+\\ The following code is automatically generated.
+\\
+const char* ATLAS_FILE_NAME( "my_first_atlas.png" );  ///< Atlas image filename
+
+/**
+ * Structure to hold image name and position within the atlas.
+ *
+ */
+struct ImageInfo
+{
+  const char* name;
+  unsigned int x,y,w,h;
+  Dali::BlendingMode::Type blendMode;  // only enable blending if image has alpha
+};
+
+/**
+ * lookup table
+ */
+const ImageInfo ImageAtlas[]=
+{
+ { "blocks-ball", 2, 198, 51, 51, BlendingMode::ON },
+ { "bubble-ball", 288, 74, 32, 32, BlendingMode::ON },
+ { "gallery-small-52", 2, 2, 128, 128, BlendingMode::OFF },
+ { "icon-change", 219, 2, 37, 34, BlendingMode::ON },
+ { "icon-cluster-carousel", 180, 2, 37, 34, BlendingMode::ON }
+};
+
+const ImageInfo* GetImageInfo(const char* name)
+{
+  typedef std::map< const char*, const ImageInfo* > LookupMap;
+  static LookupMap lookup;
+  if( lookup.empty() )
+  {
+    for( unsigned int i = 0; i < ATLAS_IMAGE_COUNT; ++i)
+    {
+      lookup[ ImageAtlas[i].name ] =  &ImageAtlas[i];
+    }
+  }
+  LookupMap::const_iterator iter = lookup.find(name);
+  if( iter != lookup.end() )
+  {
+   return (*iter).second;
+  }
+  DALI_ASSERT_ALWAYS(0 && "image name not found in atlas");
+  return NULL;
+}
+
+\endcode
+
+To use the lookup table you can do something like this:
+\code
+
+// Example function on how to get an image info from the table
+
+std::string fileName = std::string( DALI_IMAGE_DIR ) + ATLAS_FILE_NAME;
+Image imageImage = Image::New( fileName );
+
+const ImageInfo* info(NULL);
+
+info = GetImageInfo("blocks-ball");
+if( info)
+{
+  ImageActor ballActor = ImageActor::New( imageAtlas, ImageActor::PixelArea( info->x, info->y, info->w, info->h) );
+  ballActor->SetBlendMode( info->blendMode );
+}
+info = GetImageInfo("bubble-ball");
+if( info)
+{
+  ImageActor bubbleActor = ImageActor::New( imageAtlas, ImageActor::PixelArea( info->x, info->y, info->w, info->h) );
+  bubbleActor->SetBlendMode( info->blendMode );
+}
+
+\endcode
+<h3> Using the constant definitions </h3>
+
+1. Cut and paste the constant definition code into your application.
+
+You'll notice the code below won't compile because C++ variables can't have a dash character.<br>
+E.g. BLOCKS-BALL, BUBBLE-BALL will cause errors. Do a search and replace for - and replace with underscores.
+This is one reason why using lookup table which holds the filename as a string maybe easier to use.
+
+\code
+\\ The following code is automatically generated.
+\\
+const char* ATLAS_FILE_NAME( "my_first_atlas.png" );
+
+/**
+ * Structure to hold position / blend mode within the atlas.
+ *
+ */
+struct ImageInfo
+{
+  ImageInfo(unsigned int x,unsigned int y,unsigned int w,unsigned int h,  Dali::BlendingMode::Type mode)
+  :pixelArea(x,y,w,h),blendMode(mode)
+  {}
+  ImageActor::PixelArea pixelArea;
+  Dali::BlendingMode::Type blendMode;  // only enable blending if image has alpha
+};
+
+
+const ImageInfo BLOCKS-BALL( 2, 198, 51, 51 ,BlendingMode::ON );
+const ImageInfo BUBBLE-BALL( 288, 74, 32, 32 ,BlendingMode::ON );
+const ImageInfo GALLERY-SMALL-52( 2, 2, 128, 128 ,BlendingMode::OFF );
+\endcode
+
+2. To use it, you can copy example code from the generated cpp file which looks
+like this
+\code
+void LoadAtlasImages()
+{
+  std::string fileName = std::string(DALI_IMAGE_DIR) + ATLAS_FILE_NAME;
+  Image atlasImage = Image::New( fileName );
+  ImageActor Blocksball = ImageActor::New( atlasImage,  BLOCKS_BALL.pixelArea);
+  Blocksball.SetBlendMode( BLOCKS_BALL.blendMode );
+
+  ImageActor Bubbleball = ImageActor::New( atlasImage,  BUBBLE_BALL.pixelArea);
+  Bubbleball.SetBlendMode( BUBBLE_BALL.blendMode );
+  ...
+ \endcode
+
+
+
+<br><br>
+<h2> Atlas creation tips </h2>
+
+<ul>
+  <li> Compress the atlas  - \link Texture_Compression Compressing Textures \endlink <br></li>
+  <li> Avoid adding large images to the Atlas.<br>
+    E.g. don't add background images to it. Medium to large images should
+    be kept seperate. <br><br>
+    \image html atlas-size.jpg
+    <br><br>
+  </li>
+  <li> Try to ensure the atlas contains only images that are frequently used. <br>
+    There's no point in having images taking up GPU texture memory if they're not displayed.<br>
+  </li>
+  <li> Avoid very large atlases <br>
+    Try to create multiple atlases based on how they are used within your application.<br>
+    <br>
+    Alternatively Texture packer has the option to split atlases ( search help for Multipack)
+  </li>
+</ul>
+
+
+
+ */
+
diff --git a/docs/content/programming-guide/texture-compression.h b/docs/content/programming-guide/texture-compression.h
new file mode 100644 (file)
index 0000000..62f4577
--- /dev/null
@@ -0,0 +1,64 @@
+
+/*! \page Texture_Compression Texture Compression
+
+
+Using compressing the textures will:
+<ul>
+<li> Speed up rendering in time the GPU == less power used due to less texture data being transferred.
+<li> Reduce texture memory usage.
+<li> Speed up load times. Smaller files mean quicker load times.
+</ul>
+<br><br>
+DALi supports the KTX file format.
+You just load the compressed texture like you would any other image.
+\code
+Image::New("my_compressed_file.ktx");
+\endcode
+<br>
+ARMS texture compression tool<br>
+http://malideveloper.arm.com/develop-for-mali/tools/asset-creation/mali-gpu-texture-compression-tool/  <br>
+
+Here is an example of using the ARM compression tool.
+\image html compression-options.jpg
+
+<br><br>
+
+\image html compression-example.jpg
+<br>
+<br>
+As shown above the ETC-1 compression format does not support alpha.<br> As a work around the tool will export
+the alpha as a seperate compressed image.<br>
+In order to combine both the images you need to use a custom shader.<br>
+Here is an example shader:<br>
+\code
+  const char* const COMPRESSED_RGB_PLUS_SEPARATE_ALPHA_FRAGMENT_SOURCE =
+    "\n"
+    "void main()\n"
+    "{\n"
+    "    vec4 v4Color  = (texture2D(sTexture, vTexCoord) * uColor);\n"
+    "    v4Color.a =  texture2D(sEffect, vTexCoord ).r;\n"
+    "   gl_FragColor = v4Color;"
+    "}\n";
+
+
+  mShaderEffect = ShaderEffect::New( "", COMPRESSED_RGB_PLUS_SEPARATE_ALPHA_FRAGMENT_SOURCE);
+
+  mAtlasImageRGB = Image::New( ATLAS_RGB_FILENAME.KTX);
+
+  mAtlasImageAlpha = Image::New( ATLAS_ALPHA_FILENAME.KTX );
+
+  mShaderEffect.SetEffectImage( mAtlasImageAlpha );
+
+
+
+  // to create Image Actor
+  ImageActor  imageActor = ImageActor::New( mAtlasImageRGB, GetImagePosition( info) );
+
+  imageActor.SetShaderEffect( mShaderEffect );
+
+  imageActor.SetBlendMode(BlendingMode::ON);
+
+\endcode
+
+
+ */
index 2c838cd..45d1566 100644 (file)
@@ -46,7 +46,6 @@
 #include <dali-toolkit/public-api/controls/text-input/text-input.h>
 #include <dali-toolkit/public-api/controls/text-view/text-view.h>
 #include <dali-toolkit/public-api/enums.h>
-#include <dali-toolkit/public-api/factory/localized-control-factory.h>
 #include <dali-toolkit/public-api/focus-manager/focus-manager.h>
 #include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
 #include <dali-toolkit/public-api/markup-processor/markup-processor.h>
index b9b9946..14ff051 100644 (file)
@@ -292,11 +292,6 @@ unsigned int genRandom(unsigned int& seed, unsigned int offset)
   return seed;
 }
 
-float genRandomFloat(unsigned int& seed, unsigned int offset)
-{
-  return static_cast<float>(genRandom(seed, offset)) / 0xffffffff;
-}
-
 float genRandomFloat(unsigned int& seed, unsigned int offset, float min, float max)
 {
   const float f = static_cast<float>(genRandom(seed, offset)) / 0xffffffff;
index 9783240..3e23a8a 100644 (file)
@@ -115,22 +115,6 @@ struct RenderTaskViewportSizeConstraint
   }
 };
 
-/**
- * Returns relative border (0.0f...1.0f x 0.0f...1.0f)
- * from an absolute pixel specified border.
- * @param[in] absolute A border using absolute pixel coordinates
- * @param[in] width The width of the texture
- * @param[in] height The height of the texture.
- * @return A border relative to the size of the Image texture dimensions.
- */
-Vector4 GetRelativeBorder(Vector4 absolute, float width, float height)
-{
-  return Vector4( absolute.x / width,
-                  absolute.y / height,
-                  absolute.z / width,
-                  absolute.w / height);
-}
-
 }
 
 namespace Dali
index 61060bf..10125c7 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 0;
-const unsigned int TOOLKIT_MICRO_VERSION = 9;
+const unsigned int TOOLKIT_MICRO_VERSION = 10;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index d20e41c..aa12918 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    The OpenGLES Canvas Core Library Toolkit
-Version:    1.0.9
+Version:    1.0.10
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0
diff --git a/texture-atlas-exporter/dali-exporter/dali3d_exporter.cpp b/texture-atlas-exporter/dali-exporter/dali3d_exporter.cpp
new file mode 100755 (executable)
index 0000000..ac505ef
--- /dev/null
@@ -0,0 +1,131 @@
+// Created with TexturePacker (http://www.codeandweb.com/texturepacker)
+// DALi Exporter: nick.holland@partner.samsung.com
+//
+// {{smartUpdateKey}}
+
+// For your application cut and paste either:
+//
+// 1. Lookup table.
+// 2. Constants.
+// 3. JavaScript property map for using with DALi JS.
+
+// Note: If you use one option, then delete code for the other two
+
+
+
+
+//
+// 1.  ------  lookup table method  ------
+//
+// Handy if you want to get image with a postfix, e.g. image_1, image_2, image_3
+// Or if some of the image names contain special characters which are not allowed
+// in constant definitions ( e.g. spaces and full stops).
+
+
+const char* ATLAS_FILE_NAME( "{{texture.fullName}}" );  ///< Atlas image filename
+
+
+/**
+ * Structure to hold image name and position within the atlas.
+ *
+ */
+struct ImageInfo
+{
+  const char* name;
+  unsigned int x,y,w,h;
+  Dali::BlendingMode::Type blendMode;  // only enable blending if image has alpha
+};
+
+/**
+ * lookup table
+ */
+const ImageInfo ImageAtlas[]=
+{
+{% for sprite in allSprites %} { "{{sprite.trimmedName}}", {{sprite.frameRect.x}}, {{sprite.frameRect.y}}, {{sprite.frameRect.width}}, {{sprite.frameRect.height}}, {%if sprite.isSolid %}BlendingMode::OFF{% else%}BlendingMode::ON{% endif %} }{% if not forloop.last %},{% endif %}
+{% endfor %}
+};
+
+const unsigned int ATLAS_IMAGE_COUNT = sizeof(ImageAtlas)/sizeof(ImageAtlas[0]);
+
+// Example function on how to get an image info from the table
+//
+// std::string fileName = std::string( DALI_IMAGE_DIR ) + ATLAS_FILE_NAME;
+// Image imageAtlas = Image::New( fileName );
+//
+//
+//  const ImageInfo* info = GetImageInfo("left_icon");
+//
+//  if( info)
+//  {
+//     ImageActor myActor = ImageActor::New( imageAtlas, ImageActor::PixelArea( info->x, info->y, info->w, info->h) );
+//     myActor->SetBlendMode( info->blendMode );
+//
+//
+
+const ImageInfo* GetImageInfo(const char* name)
+{
+  typedef std::map< const char*, const ImageInfo* > LookupMap;
+  static LookupMap lookup;
+  if( lookup.empty() )
+  {
+    for( unsigned int i = 0; i < ATLAS_IMAGE_COUNT; ++i)
+    {
+      lookup[ ImageAtlas[i].name ] =  &ImageAtlas[i];
+    }
+  }
+  LookupMap::const_iterator iter = lookup.find(name);
+  if( iter != lookup.end() )
+  {
+   return (*iter).second;
+  }
+  DALI_ASSERT_ALWAYS(0 && "image name not found in atlas");
+  return NULL;
+}
+
+//
+//
+// 2. ------ constants code ------
+//
+//
+
+const char* ATLAS_FILE_NAME( "{{texture.fullName}}" );
+
+/**
+ * Structure to hold position / blend mode within the atlas.
+ *
+ */
+struct ImageInfo
+{
+  ImageInfo(unsigned int x,unsigned int y,unsigned int w,unsigned int h,  Dali::BlendingMode::Type mode)
+  :pixelArea(x,y,w,h),blendMode(mode)
+  {}
+  ImageActor::PixelArea pixelArea;
+  Dali::BlendingMode::Type blendMode;  // only enable blending if image had alpha
+};
+
+{% for sprite in allSprites %}const ImageInfo {{ sprite.trimmedName|upper}}( {{sprite.frameRect.x}}, {{sprite.frameRect.y}}, {{sprite.frameRect.width}}, {{sprite.frameRect.height}} ,{%if sprite.isSolid %}BlendingMode::OFF{% else%}BlendingMode::ON{% endif %} );
+{% endfor %}
+
+
+// Example on using the Atlas, please delete this code.
+void LoadAtlasImages()
+{
+  std::string fileName = std::string(DALI_IMAGE_DIR) + ATLAS_FILE_NAME;
+  Image atlasImage = Image::New( fileName );
+  {% for sprite in allSprites %}ImageActor {{sprite.trimmedName|capfirst}} = ImageActor::New( atlasImage,  {{sprite.trimmedName|upper}}.pixelArea);
+  {{sprite.trimmedName|capfirst}}.SetBlendMode( {{sprite.trimmedName|upper}}.blendMode );
+
+  {% endfor %}
+}
+
+//
+//
+// 3.  ------  JavaScript key/value lookup table   ------
+//
+//
+//
+
+ATLAS_IMAGE_LIST : [
+{% for sprite in allSprites %} { name: "{{sprite.trimmedName}}", x: {{sprite.frameRect.x}}, y:{{sprite.frameRect.y}}, w:{{sprite.frameRect.width}}, h:{{sprite.frameRect.height}}, {%if sprite.isSolid %}dali.BLENDING_OFF{% else%}dali.BLENDING_ON{% endif %}  }{% if not forloop.last %},{% endif %}
+{% endfor %}
+]
\ No newline at end of file
diff --git a/texture-atlas-exporter/dali-exporter/exporter.xml b/texture-atlas-exporter/dali-exporter/exporter.xml
new file mode 100755 (executable)
index 0000000..bb9cbcd
--- /dev/null
@@ -0,0 +1,45 @@
+<exporter version="1.0">
+  <!-- identifier of the exporter -->
+  <name>dali_exporter</name>
+
+  <!-- display name of the exporter for the combo box -->
+  <displayName>DALi 3D</displayName>
+
+  <!-- description of the exporter -->
+  <description>DALi 3D exporter for TexturePacker</description>
+
+  <!-- exporter version -->
+  <version>1.0</version>
+
+  <!-- currently only one file allowed - more to come soon -->
+  <files>
+      <file>
+          <!-- name of this file variable -->
+          <name>maintext</name>
+
+          <!-- human readable name (for GUI) -->
+          <displayName>.cpp file</displayName>
+
+          <!-- file extension for the file -->
+          <fileExtension>cpp</fileExtension>
+
+          <!-- name of the template file -->
+          <template>dali3d_exporter.cpp</template>
+      </file>
+  </files>
+
+  <!-- target framework supports trimming -->
+  <supportsTrimming>no</supportsTrimming>
+
+  <!-- target framework supports rotated sprites -->
+  <supportsRotation>no</supportsRotation>
+
+  <!-- supports npot sizes -->
+  <supportsNPOT>yes</supportsNPOT>
+
+  <!-- supports file name stripping (remove .png etc.) -->
+  <supportsTrimSpriteNames>yes</supportsTrimSpriteNames>
+
+  <!-- supports texture subpath -->
+  <supportsTextureSubPath>yes</supportsTextureSubPath>
+</exporter>
\ No newline at end of file