Merge "Fix grid layout defaults" into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Tue, 28 Aug 2018 11:12:12 +0000 (11:12 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Tue, 28 Aug 2018 11:12:12 +0000 (11:12 +0000)
18 files changed:
automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-utils.cpp
automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-utils.h
automated-tests/src/dali-toolkit-internal/utc-Dali-BidirectionalSupport.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-LogicalModel.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Cursor.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Layout.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Shaping.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-VisualModel.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp
dali-toolkit/devel-api/controls/text-controls/text-label-devel.h
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/text/layouts/layout-engine.cpp
dali-toolkit/internal/text/layouts/layout-parameters.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/internal/text/text-model.cpp
dali-toolkit/internal/text/text-model.h
dali-toolkit/styles/1920x1080/dali-toolkit-default-theme.json

index b977ec3..08f2c63 100755 (executable)
@@ -31,6 +31,7 @@
 #include <dali-toolkit/internal/text/segmentation.h>
 #include <dali-toolkit/internal/text/shaper.h>
 #include <dali-toolkit/internal/text/text-controller-impl.h>
+#include <dali-toolkit/internal/text/markup-processor.h>
 
 namespace Dali
 {
@@ -100,31 +101,52 @@ void CreateTextModel( const std::string& text,
                       Size& layoutSize,
                       LogicalModelPtr& logicalModel,
                       VisualModelPtr& visualModel,
-                      MetricsPtr& metrics )
+                      MetricsPtr& metrics,
+                      bool markupProcessorEnabled )
 {
   logicalModel = LogicalModel::New();
   visualModel = VisualModel::New();
 
+  MarkupProcessData markupProcessData( logicalModel->mColorRuns,
+                                       logicalModel->mFontDescriptionRuns );
+
+  Length textSize = 0u;
+  const uint8_t* utf8 = NULL;
+  if( markupProcessorEnabled )
+  {
+    ProcessMarkupString( text, markupProcessData );
+    textSize = markupProcessData.markupProcessedText.size();
+
+    // This is a bit horrible but std::string returns a (signed) char*
+    utf8 = reinterpret_cast<const uint8_t*>( markupProcessData.markupProcessedText.c_str() );
+  }
+  else
+  {
+    textSize = text.size();
+
+    // This is a bit horrible but std::string returns a (signed) char*
+    utf8 = reinterpret_cast<const uint8_t*>( text.c_str() );
+  }
+
   // 1) Convert to utf32
   Vector<Character>& utf32Characters = logicalModel->mText;
-  utf32Characters.Resize( text.size() );
+  utf32Characters.Resize( textSize );
 
-  const uint32_t numberOfCharacters = ( text.size() == 0) ? 0 :
-    Utf8ToUtf32( reinterpret_cast<const uint8_t* const>( text.c_str() ),
-                                                   text.size(),
-                                                   &utf32Characters[0u] );
-  utf32Characters.Resize( numberOfCharacters );
+  // Transform a text array encoded in utf8 into an array encoded in utf32.
+  // It returns the actual number of characters.
+  Length characterCount = Utf8ToUtf32( utf8, textSize, utf32Characters.Begin() );
+  utf32Characters.Resize( characterCount );
 
   // 2) Set the break and paragraph info.
   Vector<LineBreakInfo>& lineBreakInfo = logicalModel->mLineBreakInfo;
-  lineBreakInfo.Resize( numberOfCharacters );
+  lineBreakInfo.Resize( characterCount );
 
   SetLineBreakInfo( utf32Characters,
                     0u,
-                    numberOfCharacters,
+                    characterCount,
                     lineBreakInfo );
 
-  if( 0u == numberOfCharacters )
+  if( 0u == characterCount )
   {
     // Nothing else to do if the number of characters is zero.
     return;
@@ -132,11 +154,11 @@ void CreateTextModel( const std::string& text,
 
   // Retrieves the word break info. The word break info is used to layout the text (where to wrap the text in lines).
   Vector<WordBreakInfo>& wordBreakInfo = logicalModel->mWordBreakInfo;
-  wordBreakInfo.Resize( numberOfCharacters );
+  wordBreakInfo.Resize( characterCount );
 
   SetWordBreakInfo( utf32Characters,
                     0u,
-                    numberOfCharacters,
+                    characterCount,
                     wordBreakInfo );
 
   // 3) Set the script info.
@@ -145,7 +167,7 @@ void CreateTextModel( const std::string& text,
   Vector<ScriptRun>& scripts = logicalModel->mScriptRuns;
   multilanguageSupport.SetScripts( utf32Characters,
                                    0u,
-                                   numberOfCharacters,
+                                   characterCount,
                                    scripts );
 
   // 4) Set the font info
@@ -167,7 +189,7 @@ void CreateTextModel( const std::string& text,
                                       fontDescription,
                                       TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
                                       0u,
-                                      numberOfCharacters,
+                                      characterCount,
                                       validFonts );
 
   // 5) Set the bidirectional info per paragraph.
@@ -182,12 +204,12 @@ void CreateTextModel( const std::string& text,
                         scripts,
                         lineBreakInfo,
                         0u,
-                        numberOfCharacters,
+                        characterCount,
                         bidirectionalInfo );
 
   // Create the paragraph info.
   logicalModel->CreateParagraphInfo( 0u,
-                                     numberOfCharacters );
+                                     characterCount );
 
   // 6) Set character directions.
   Vector<CharacterDirection>& characterDirections = logicalModel->mCharacterDirections;
@@ -195,9 +217,9 @@ void CreateTextModel( const std::string& text,
   {
     // Only set the character directions if there is right to left characters.
     GetCharactersDirection( bidirectionalInfo,
-                            numberOfCharacters,
+                            characterCount,
                             0u,
-                            numberOfCharacters,
+                            characterCount,
                             characterDirections );
 
 
@@ -206,7 +228,7 @@ void CreateTextModel( const std::string& text,
                                     characterDirections,
                                     bidirectionalInfo,
                                     0u,
-                                    numberOfCharacters,
+                                    characterCount,
                                     mirroredUtf32Characters );
   }
   else
@@ -230,15 +252,15 @@ void CreateTextModel( const std::string& text,
              validFonts,
              0u,
              0u,
-             numberOfCharacters,
+             characterCount,
              glyphs,
              glyphsToCharactersMap,
              charactersPerGlyph,
              newParagraphGlyphs );
 
   // Create the 'number of glyphs' per character and the glyph to character conversion tables.
-  visualModel->CreateGlyphsPerCharacterTable( 0u, 0u, numberOfCharacters );
-  visualModel->CreateCharacterToGlyphTable( 0u, 0u, numberOfCharacters );
+  visualModel->CreateGlyphsPerCharacterTable( 0u, 0u, characterCount );
+  visualModel->CreateCharacterToGlyphTable( 0u, 0u, characterCount );
 
   const Length numberOfGlyphs = glyphs.Count();
 
@@ -284,14 +306,15 @@ void CreateTextModel( const std::string& text,
                                        numberOfGlyphs,
                                        Text::HorizontalAlignment::BEGIN,
                                        Text::LineWrap::WORD,
-                                       outlineWidth );
+                                       outlineWidth,
+                                       true );
 
   Vector<LineRun>& lines = visualModel->mLines;
 
   Vector<Vector2>& glyphPositions = visualModel->mGlyphPositions;
   glyphPositions.Resize( numberOfGlyphs );
 
-  layoutParameters.isLastNewParagraph = TextAbstraction::IsNewParagraph( *( utf32Characters.Begin() + ( numberOfCharacters - 1u ) ) );
+  layoutParameters.isLastNewParagraph = TextAbstraction::IsNewParagraph( *( utf32Characters.Begin() + ( characterCount - 1u ) ) );
 
   // The initial glyph and the number of glyphs to layout.
   layoutParameters.startGlyphIndex = 0u;
@@ -317,7 +340,7 @@ void CreateTextModel( const std::string& text,
     bidirectionalLineInfo.Reserve( numberOfLines ); // Reserve because is not known yet how many lines have right to left characters.
     ReorderLines( bidirectionalInfo,
                   0u,
-                  numberOfCharacters,
+                  characterCount,
                   lines,
                   bidirectionalLineInfo );
 
@@ -330,7 +353,7 @@ void CreateTextModel( const std::string& text,
       // Re-layout the text. Reorder those lines with right to left characters.
       layoutEngine.ReLayoutRightToLeftLines( layoutParameters,
                                              0u,
-                                             numberOfCharacters,
+                                             characterCount,
                                              glyphPositions );
     }
   }
@@ -340,7 +363,7 @@ void CreateTextModel( const std::string& text,
     float alignmentOffset = 0.f;
     layoutEngine.Align( textArea,
                         0u,
-                        numberOfCharacters,
+                        characterCount,
                         Text::HorizontalAlignment::BEGIN,
                         lines,
                         alignmentOffset );
index 2391cb1..8ba7306 100644 (file)
@@ -59,6 +59,7 @@ struct LayoutOptions
  * @param[out] logicalModel Pointer to a logical text model instance.
  * @param[out] visualModel Pointer to a visual text model instance.
  * @param[out] metrics Pointer to a wrapper around FontClient used to get metrics.
+ * @param[in] markupProcessorEnabled Enable markup processor to use markup text.
  */
 void CreateTextModel( const std::string& text,
                       const Size& textArea,
@@ -67,7 +68,8 @@ void CreateTextModel( const std::string& text,
                       Size& layoutSize,
                       LogicalModelPtr& logicalModel,
                       VisualModelPtr& visualModel,
-                      MetricsPtr& metrics );
+                      MetricsPtr& metrics,
+                      bool markupProcessorEnabled );
 
 /**
  * @brief Configures the text @p controller similarly to the one configured by the text-label.
index cb33f00..191ead1 100644 (file)
@@ -101,11 +101,12 @@ struct GetMirroredTextData
 
 struct GetCharactersDirectionData
 {
-  std::string  description;         ///< Description of the test.
-  std::string  text;                ///< Input text.
-  unsigned int startIndex;          ///< The index from where the model is updated.
-  unsigned int numberOfCharacters;  ///< The number of characters.
-  bool*        directions;          ///< The expected directions.
+  std::string  description;            ///< Description of the test.
+  std::string  text;                   ///< Input text.
+  unsigned int startIndex;             ///< The index from where the model is updated.
+  unsigned int numberOfCharacters;     ///< The number of characters.
+  bool*        directions;             ///< The expected directions.
+  bool         markupProcessorEnabled; ///< Enable markup processor to use markup text.
 };
 
 bool SetBidirectionalInfoTest( const SetBidirectionalInfoData& data )
@@ -127,7 +128,8 @@ bool SetBidirectionalInfoTest( const SetBidirectionalInfoData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   // 2) Clear the bidirectional paragraph info data.
   Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = logicalModel->mBidirectionalParagraphInfo;
@@ -233,7 +235,8 @@ bool ReorderLinesTest( const ReorderLinesData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   // 2) Clear the bidirectional line info data.
   uint32_t startRemoveIndex = logicalModel->mBidirectionalLineInfo.Count();
@@ -358,7 +361,8 @@ bool GetMirroredTextTest( const GetMirroredTextData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   // 2) Call the GetMirroredText() function for the whole text
   Vector<Character> mirroredText;
@@ -432,7 +436,8 @@ bool GetCharactersDirectionTest( const GetCharactersDirectionData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   data.markupProcessorEnabled );
 
   Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = logicalModel->mBidirectionalParagraphInfo;
 
@@ -930,6 +935,11 @@ int UtcDaliGetCharactersDirection(void)
     true,  true,  true,  true,  true,  true,  true,  true,  true,  true,
     true,  true,  false, false, false, false, false };
 
+    bool directions06[] = {
+    true,  true,  true,  true,  true,  true,  true,  true,  true, true,
+    false, false, false, false, false, false, false, false, false, false,
+    false, false, false, false, false, false };
+
   struct GetCharactersDirectionData data[] =
   {
     {
@@ -937,28 +947,32 @@ int UtcDaliGetCharactersDirection(void)
       "",
       0u,
       0u,
-      directions01
+      directions01,
+      false
     },
     {
       "Left to right characters only",
       "Hello world\nhello world demo",
       0u,
       28u,
-      directions02
+      directions02,
+      false
     },
     {
       "Right to left characters only",
       "שלום עולם\nשלום עולם",
       0u,
       19u,
-      directions03
+      directions03,
+      false
     },
     {
       "Mix of bidirectional text",
       "Hello world\nhello world שלום עולם\nשלום עולם hello world",
       0u,
       55u,
-      directions04
+      directions04,
+      false
     },
     {
       "Mix of bidirectional text. With more paragraphs.",
@@ -966,7 +980,8 @@ int UtcDaliGetCharactersDirection(void)
       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום hello world demo עולם\nשלום مرحبا بالعالم עולם hello",
       0u,
       227u,
-      directions05
+      directions05,
+      false
     },
     {
       "Mix of bidirectional text. With more paragraphs. Update first paragraph.",
@@ -974,7 +989,8 @@ int UtcDaliGetCharactersDirection(void)
       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום hello world demo עולם\nשלום مرحبا بالعالم עולם hello",
       0u,
       17u,
-      directions05
+      directions05,
+      false
     },
     {
       "Mix of bidirectional text. With more paragraphs. Update from character 29",
@@ -982,7 +998,8 @@ int UtcDaliGetCharactersDirection(void)
       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום hello world demo עולם\nשלום مرحبا بالعالم עולם hello",
       29u,
       134u,
-      directions05
+      directions05,
+      false
     },
     {
       "Mix of bidirectional text. With more paragraphs. Update from character 163",
@@ -990,10 +1007,19 @@ int UtcDaliGetCharactersDirection(void)
       " مرحبا بالعالم שלום עולם hello world hello world\nبالعالم שלום hello world demo עולם\nשלום مرحبا بالعالم עולם hello",
       163u,
       35u,
-      directions05
+      directions05,
+      false
+    },
+    {
+      "Mix of bidirectional text. With brackets and LRM",
+      "שלום עולם &lrm;(hello)[world]&lrm;",
+      0u,
+      26u,
+      directions06,
+      true
     }
   };
-  const unsigned int numberOfTests = 8u;
+  const unsigned int numberOfTests = 9u;
 
   for( unsigned int index = 0u; index < numberOfTests; ++index )
   {
index f8df615..d43e3e5 100644 (file)
@@ -115,7 +115,8 @@ bool CreateParagraphTest( const CreateParagraphData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   // 2) Clear the paragraphs.
   Vector<ParagraphRun>& paragraphs = logicalModel->mParagraphInfo;
@@ -175,7 +176,8 @@ bool FindParagraphTest( const FindParagraphData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   // 2) Find the paragraphs.
   Vector<ParagraphRunIndex> paragraphs;
@@ -224,7 +226,8 @@ bool FetchBidirectionalLineInfoTest( const FetchBidirectionalLineInfoData& data
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   for( unsigned int index = 0; index < data.numberOfTests; ++index )
   {
@@ -268,7 +271,8 @@ bool GetLogicalCharacterIndexTest( const GetLogicalCharacterIndexData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   for( unsigned int index = 0u; index < data.numberOfIndices; ++index )
   {
@@ -310,7 +314,8 @@ bool GetLogicalCursorIndexTest( const GetLogicalCursorIndexData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   for( unsigned int index = 0u; index < data.numberOfIndices; ++index )
   {
index 2a5ae46..cba35a3 100644 (file)
@@ -112,7 +112,8 @@ bool GetClosestLineTest( const GetClosestLineData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   for( unsigned int index = 0; index < data.numberOfTests; ++index )
   {
@@ -156,7 +157,8 @@ bool GetClosestCursorIndexTest( const GetClosestCursorIndexData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   for( unsigned int index = 0; index < data.numberOfTests; ++index )
   {
@@ -204,7 +206,8 @@ bool GetCursorPositionTest( const GetCursorPositionData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   GetCursorPositionParameters parameters;
   parameters.visualModel = visualModel;
@@ -255,7 +258,8 @@ bool FindSelectionIndicesTest( const FindSelectionIndicesData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   for( unsigned int index = 0; index < data.numberOfTests; ++index )
   {
index 86edead..ab15b46 100644 (file)
@@ -109,7 +109,8 @@ bool LayoutTextTest( const LayoutTextData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   // 2) Clear the layout.
   Vector<LineRun>& lines = visualModel->mLines;
@@ -172,7 +173,8 @@ bool LayoutTextTest( const LayoutTextData& data )
                                        totalNumberOfGlyphs,
                                        Text::HorizontalAlignment::BEGIN,
                                        Text::LineWrap::WORD,
-                                       outlineWidth );
+                                       outlineWidth,
+                                       true );
 
   layoutParameters.isLastNewParagraph = isLastNewParagraph;
 
@@ -370,7 +372,8 @@ bool ReLayoutRightToLeftLinesTest( const ReLayoutRightToLeftLinesData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   // 2) Call the ReLayoutRightToLeftLines() method.
   Layout::Engine engine;
@@ -390,7 +393,8 @@ bool ReLayoutRightToLeftLinesTest( const ReLayoutRightToLeftLinesData& data )
                                        visualModel->mGlyphs.Count(),
                                        Text::HorizontalAlignment::BEGIN,
                                        Text::LineWrap::WORD,
-                                       outlineWidth );
+                                       outlineWidth,
+                                       true );
 
   layoutParameters.numberOfBidirectionalInfoRuns = logicalModel->mBidirectionalLineInfo.Count();
   layoutParameters.lineBidirectionalInfoRunsBuffer = logicalModel->mBidirectionalLineInfo.Begin();
@@ -482,7 +486,8 @@ bool AlignTest( const AlignData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   // Call the Align method.
   Layout::Engine engine;
index 0b7ca02..b5bf653 100644 (file)
@@ -138,7 +138,8 @@ bool ShapeInfoTest( const ShapeInfoData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   // 2) Clear the model.
 
index a13b4d8..c36fed6 100644 (file)
@@ -80,7 +80,8 @@ bool SetGlyphsPerCharacterTest( const SetGlyphsPerCharacterData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   Vector<GlyphIndex>& charactersToGlyph = visualModel->mCharactersToGlyph;
   Vector<Length>& glyphsPerCharacter = visualModel->mGlyphsPerCharacter;
@@ -162,7 +163,8 @@ bool SetCharacterToGlyphTest( const SetCharacterToGlyphData& data )
                    layoutSize,
                    logicalModel,
                    visualModel,
-                   metrics );
+                   metrics,
+                   false );
 
   Vector<GlyphIndex>& charactersToGlyph = visualModel->mCharactersToGlyph;
   Vector<Length>& glyphsPerCharacter = visualModel->mGlyphsPerCharacter;
index b134179..f19cb12 100644 (file)
@@ -1047,6 +1047,21 @@ int UtcDaliToolkitTextlabelEllipsis(void)
     tet_result(TET_FAIL);
   }
 
+  label.SetProperty( TextLabel::Property::TEXT, "Hello world                                        " );
+  label.SetProperty( DevelTextLabel::Property::IGNORE_SPACES_AFTER_TEXT, false );
+  label.SetSize( 400.0f, 10.f );
+
+  try
+  {
+    // Render the text.
+    application.SendNotification();
+    application.Render();
+  }
+  catch( ... )
+  {
+    tet_result(TET_FAIL);
+  }
+
   END_TEST;
 }
 
index 939c08d..0b16273 100644 (file)
@@ -94,6 +94,13 @@ namespace Property
      * | color                | VECTOR4  | No       | The color of the background (the default value is Color::CYAN)                                                     |
      */
     BACKGROUND,
+
+    /**
+     * @brief Ignore spaces after text.
+     * @details Name "ignoreSpacesAfterText", type (Property::BOLEAN), Read/Write
+     * @note The default value is true
+     */
+    IGNORE_SPACES_AFTER_TEXT,
   };
 
 } // namespace Property
index 7c6ef25..bb40d00 100644 (file)
@@ -131,6 +131,7 @@ DALI_PROPERTY_REGISTRATION( Toolkit,           TextLabel, "lineWrapMode",
 DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY( Toolkit, TextLabel, "textDirection",       INTEGER, TEXT_DIRECTION             )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit,     TextLabel, "verticalLineAlignment",     INTEGER, VERTICAL_LINE_ALIGNMENT    )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit,     TextLabel, "textBackground",            MAP,     BACKGROUND                 )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit,     TextLabel, "ignoreSpacesAfterText",     BOOLEAN, IGNORE_SPACES_AFTER_TEXT   )
 DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT( Toolkit, TextLabel, "textColor",      Color::BLACK,     TEXT_COLOR     )
 DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit,    TextLabel, "textColorRed",   TEXT_COLOR_RED,   TEXT_COLOR, 0  )
 DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit,    TextLabel, "textColorGreen", TEXT_COLOR_GREEN, TEXT_COLOR, 1  )
@@ -533,6 +534,11 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
         }
         break;
       }
+      case Toolkit::DevelTextLabel::Property::IGNORE_SPACES_AFTER_TEXT:
+      {
+        impl.mController->SetIgnoreSpacesAfterText(value.Get< bool >());
+        break;
+      }
     }
 
     // Request relayout when text update is needed. It's necessary to call it
@@ -831,6 +837,11 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
         GetBackgroundProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
         break;
       }
+      case Toolkit::DevelTextLabel::Property::IGNORE_SPACES_AFTER_TEXT:
+      {
+        value = impl.mController->IsIgnoreSpacesAfterText();
+        break;
+      }
     }
   }
 
index af257ff..061707a 100644 (file)
@@ -281,9 +281,6 @@ struct Engine::Impl
       // Get the line break info for the current character.
       const LineBreakInfo lineBreakInfo = hasCharacters ? *( parameters.lineBreakInfoBuffer + characterLastIndex ) : TextAbstraction::LINE_NO_BREAK;
 
-      // Get the word break info for the current character.
-      const WordBreakInfo wordBreakInfo = *( parameters.wordBreakInfoBuffer + characterLastIndex );
-
       // Increase the number of characters.
       tmpLineLayout.numberOfCharacters += charactersPerGlyph;
 
@@ -397,11 +394,19 @@ struct Engine::Impl
         tmpLineLayout.wsLengthEndOfLine = 0.f;
       }
 
+      // If calculation is end but wsLengthEndOfLine is exist, it means end of text is space.
+      // Merge remained length.
+      if ( !parameters.ignoreSpaceAfterText && glyphIndex == lastGlyphOfParagraphPlusOne-1 && tmpLineLayout.wsLengthEndOfLine > 0 )
+      {
+        tmpLineLayout.length += tmpLineLayout.wsLengthEndOfLine;
+        tmpLineLayout.wsLengthEndOfLine = 0u;
+      }
+
       // Save the current extra width to compare with the next one
       mPreviousCharacterExtraWidth = tmpExtraWidth;
 
       // Check if the accumulated length fits in the width of the box.
-      if( ( completelyFill || isMultiline ) && !isWhiteSpace &&
+      if( ( completelyFill || isMultiline )  && !(parameters.ignoreSpaceAfterText && isWhiteSpace) &&
           ( tmpExtraBearing + lineLayout.length + lineLayout.wsLengthEndOfLine + tmpLineLayout.length + tmpExtraWidth > parameters.boundingBox.width ) )
       {
         // Current word does not fit in the box's width.
@@ -458,7 +463,7 @@ struct Engine::Impl
       }
 
       if( isMultiline &&
-          ( TextAbstraction::WORD_BREAK == wordBreakInfo ) )
+          ( TextAbstraction::LINE_ALLOW_BREAK == lineBreakInfo ) )
       {
         oneWordLaidOut = isWordLaidOut;
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  One word laid-out\n" );
index 7f3e169..5a77d86 100644 (file)
@@ -74,7 +74,8 @@ struct Parameters
               Length totalNumberOfGlyphs,
               Text::HorizontalAlignment::Type horizontalAlignment,
               Text::LineWrap::Mode lineWrapMode,
-              float outlineWidth )
+              float outlineWidth,
+              bool ignoreSpaceAfterText )
   : boundingBox( boundingBox ),
     textBuffer( textBuffer ),
     lineBreakInfoBuffer( lineBreakInfoBuffer ),
@@ -94,8 +95,9 @@ struct Parameters
     startLineIndex( 0u ),
     estimatedNumberOfLines( 0u ),
     lineWrapMode( lineWrapMode ),
+    outlineWidth( outlineWidth ),
     isLastNewParagraph( false ),
-    outlineWidth( outlineWidth )
+    ignoreSpaceAfterText( ignoreSpaceAfterText )
   {}
 
   Vector2                         boundingBox;                     ///< The size of the box containing the text.
@@ -117,8 +119,9 @@ struct Parameters
   LineIndex                       startLineIndex;                  ///< The line index where to insert the new lines.
   Length                          estimatedNumberOfLines;          ///< The estimated number of lines.
   Text::LineWrap::Mode            lineWrapMode;                    ///< The line wrap mode for moving to next line.
-  bool                            isLastNewParagraph;              ///< Whether the last character is a new paragraph character.
   float                           outlineWidth;                    ///< The outline width.
+  bool                            isLastNewParagraph:1;            ///< Whether the last character is a new paragraph character.
+  bool                            ignoreSpaceAfterText:1;          ///< Whether ignoring spaces after text or not. Default is true.
 };
 
 } // namespace Layout
index 4ce4b5a..227760f 100755 (executable)
@@ -407,6 +407,16 @@ VerticalAlignment::Type Controller::GetVerticalAlignment() const
   return mImpl->mModel->mVerticalAlignment;
 }
 
+bool Controller::IsIgnoreSpacesAfterText() const
+{
+  return mImpl->mModel->mIgnoreSpacesAfterText;
+}
+
+void Controller::SetIgnoreSpacesAfterText( bool ignore )
+{
+  mImpl->mModel->mIgnoreSpacesAfterText = ignore;
+}
+
 void Controller::SetLineWrapMode( Text::LineWrap::Mode lineWrapMode )
 {
   if( lineWrapMode != mImpl->mModel->mLineWrapMode )
@@ -3533,7 +3543,8 @@ bool Controller::DoRelayout( const Size& size,
                                          totalNumberOfGlyphs,
                                          mImpl->mModel->mHorizontalAlignment,
                                          mImpl->mModel->mLineWrapMode,
-                                         outlineWidth );
+                                         outlineWidth,
+                                         mImpl->mModel->mIgnoreSpacesAfterText );
 
     // Resize the vector of positions to have the same size than the vector of glyphs.
     Vector<Vector2>& glyphPositions = mImpl->mModel->mVisualModel->mGlyphPositions;
index 92677f2..25bb13b 100755 (executable)
@@ -1231,6 +1231,18 @@ public: // Queries & retrieves.
    */
   void SetVerticalLineAlignment( Toolkit::DevelText::VerticalLineAlignment::Type alignment );
 
+  /**
+   * @brief Retrieves ignoreSpaceAfterText value from model
+   * @return The value of ignoreSpaceAfterText
+   */
+  bool IsIgnoreSpacesAfterText() const;
+
+  /**
+   * @brief Sets ignoreSpaceAfterText value to model
+   * @param[in] ignore The value of ignoreSpacesAfterText for the text
+   */
+  void SetIgnoreSpacesAfterText( bool ignore );
+
 public: // Relayout.
 
   /**
index 84b0428..65494e5 100755 (executable)
@@ -187,7 +187,8 @@ Model::Model()
   mVerticalLineAlignment( DevelText::VerticalLineAlignment::TOP ),
   mLineWrapMode( Text::LineWrap::WORD ),
   mAlignmentOffset( 0.0f ),
-  mElideEnabled( false )
+  mElideEnabled( false ),
+  mIgnoreSpacesAfterText( true )
 {
   mLogicalModel = LogicalModel::New();
   mVisualModel = VisualModel::New();
index cb8d77c..1ea725c 100755 (executable)
@@ -230,14 +230,15 @@ public:
    * 0,0 means that the top-left corner of the layout matches the top-left corner of the UI control.
    * Typically this will have a negative value with scrolling occurs.
    */
-  Vector2                                   mScrollPosition;        ///< The text is offset by this position when scrolling.
-  Vector2                                   mScrollPositionLast;    ///< The last offset value of mScrollPosition
-  HorizontalAlignment::Type                 mHorizontalAlignment;   ///< The layout's horizontal alignment.
-  VerticalAlignment::Type                   mVerticalAlignment;     ///< The layout's vertical alignment.
-  DevelText::VerticalLineAlignment::Type    mVerticalLineAlignment; ///< The layout's vertical line alignment.
-  Text::LineWrap::Mode                      mLineWrapMode;          ///< The text wrap mode
-  float                                     mAlignmentOffset;       ///< The alignment offset.
-  bool                                      mElideEnabled:1;        ///< Whether the text's elide is enabled.
+  Vector2                                   mScrollPosition;          ///< The text is offset by this position when scrolling.
+  Vector2                                   mScrollPositionLast;      ///< The last offset value of mScrollPosition
+  HorizontalAlignment::Type                 mHorizontalAlignment;     ///< The layout's horizontal alignment.
+  VerticalAlignment::Type                   mVerticalAlignment;       ///< The layout's vertical alignment.
+  DevelText::VerticalLineAlignment::Type    mVerticalLineAlignment;   ///< The layout's vertical line alignment.
+  Text::LineWrap::Mode                      mLineWrapMode;            ///< The text wrap mode
+  float                                     mAlignmentOffset;         ///< The alignment offset.
+  bool                                      mElideEnabled:1;          ///< Whether the text's elide is enabled.
+  bool                                      mIgnoreSpacesAfterText:1; ///< Whether ignoring spaces after text or not. Default is true.
 };
 
 } // namespace Text
index fa8c6f8..43bd4e5 100644 (file)
@@ -66,7 +66,8 @@
       "enableAutoScroll":false,
       "autoScrollLoopCount":2,
       "autoScrollGap":50,
-      "autoScrollSpeed":80
+      "autoScrollSpeed":80,
+      "ignoreSpacesAfterText":false
     },
 
     "TextLabelFontSize0":