support match align for system language direciton 60/189860/21
authorJoogab Yun <joogab.yun@samsung.com>
Thu, 20 Sep 2018 10:22:19 +0000 (19:22 +0900)
committerjoogab yun <joogab.yun@samsung.com>
Sun, 7 Oct 2018 23:52:02 +0000 (23:52 +0000)
if matchSystemLanguageDirection property set true,
text align direction follow system language direction.

Change-Id: Idc1a45057cdc69d310e4c2817960e7c13cf4e48f

20 files changed:
automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-utils.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Layout.cpp [changed mode: 0644->0755]
automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp [changed mode: 0644->0755]
dali-toolkit/devel-api/controls/text-controls/text-label-devel.h [changed mode: 0644->0755]
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp [changed mode: 0644->0755]
dali-toolkit/internal/text/layouts/layout-engine.cpp [changed mode: 0644->0755]
dali-toolkit/internal/text/layouts/layout-engine.h [changed mode: 0644->0755]
dali-toolkit/internal/text/layouts/layout-parameters.h [changed mode: 0644->0755]
dali-toolkit/internal/text/text-controller-impl.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/internal/visuals/text/text-visual.cpp
dali-toolkit/styles/1920x1080/dali-toolkit-default-theme.json
docs/content/images/text-controls/HelloWorld-Default-END.png [new file with mode: 0755]
docs/content/images/text-controls/HelloWorld-System-END.png [new file with mode: 0755]
docs/content/shared-javascript-and-cpp-documentation/text-label.md [changed mode: 0644->0755]

index 08f2c63..ccd24b5 100755 (executable)
@@ -307,7 +307,8 @@ void CreateTextModel( const std::string& text,
                                        Text::HorizontalAlignment::BEGIN,
                                        Text::LineWrap::WORD,
                                        outlineWidth,
-                                       true );
+                                       true,
+                                       false );
 
   Vector<LineRun>& lines = visualModel->mLines;
 
@@ -366,7 +367,9 @@ void CreateTextModel( const std::string& text,
                         characterCount,
                         Text::HorizontalAlignment::BEGIN,
                         lines,
-                        alignmentOffset );
+                        alignmentOffset,
+                        Dali::LayoutDirection::LEFT_TO_RIGHT,
+                        false );
   }
 }
 
old mode 100644 (file)
new mode 100755 (executable)
index ab15b46..bc9d08b
@@ -174,7 +174,8 @@ bool LayoutTextTest( const LayoutTextData& data )
                                        Text::HorizontalAlignment::BEGIN,
                                        Text::LineWrap::WORD,
                                        outlineWidth,
-                                       true );
+                                       true,
+                                       false );
 
   layoutParameters.isLastNewParagraph = isLastNewParagraph;
 
@@ -394,7 +395,8 @@ bool ReLayoutRightToLeftLinesTest( const ReLayoutRightToLeftLinesData& data )
                                        Text::HorizontalAlignment::BEGIN,
                                        Text::LineWrap::WORD,
                                        outlineWidth,
-                                       true );
+                                       true,
+                                       false );
 
   layoutParameters.numberOfBidirectionalInfoRuns = logicalModel->mBidirectionalLineInfo.Count();
   layoutParameters.lineBidirectionalInfoRunsBuffer = logicalModel->mBidirectionalLineInfo.Begin();
@@ -447,6 +449,8 @@ struct AlignData
   unsigned int                      numberOfCharacters;
   unsigned int                      numberOfLines;
   float*                            lineOffsets;
+  Dali::LayoutDirection::Type       layoutDirection;
+  bool                              matchSystemLanguageDirection;
 };
 
 bool AlignTest( const AlignData& data )
@@ -499,7 +503,9 @@ bool AlignTest( const AlignData& data )
                 data.numberOfCharacters,
                 data.horizontalAlignment,
                 visualModel->mLines,
-                alignmentOffset );
+                alignmentOffset,
+                data.layoutDirection,
+                data.matchSystemLanguageDirection );
 
   // Compare results.
   if( data.numberOfLines != visualModel->mLines.Count() )
@@ -519,7 +525,6 @@ bool AlignTest( const AlignData& data )
       return false;
     }
   }
-
   return true;
 }
 
@@ -4237,7 +4242,9 @@ int UtcDaliTextAlign01(void)
     0u,
     22u,
     6u,
-    positions
+    positions,
+    Dali::LayoutDirection::LEFT_TO_RIGHT,
+    false
   };
 
   if( !AlignTest( data ) )
@@ -4356,7 +4363,9 @@ int UtcDaliTextAlign02(void)
     22u,
     26u,
     6u,
-    positions
+    positions,
+    Dali::LayoutDirection::LEFT_TO_RIGHT,
+    false
   };
 
   if( !AlignTest( data ) )
@@ -4475,7 +4484,9 @@ int UtcDaliTextAlign03(void)
     48u,
     26u,
     6u,
-    positions
+    positions,
+    Dali::LayoutDirection::LEFT_TO_RIGHT,
+    false
   };
 
   if( !AlignTest( data ) )
@@ -4594,7 +4605,9 @@ int UtcDaliTextAlign04(void)
     0u,
     22u,
     6u,
-    positions
+    positions,
+    Dali::LayoutDirection::LEFT_TO_RIGHT,
+    false
   };
 
   if( !AlignTest( data ) )
@@ -4713,7 +4726,9 @@ int UtcDaliTextAlign05(void)
     22u,
     26u,
     6u,
-    positions
+    positions,
+    Dali::LayoutDirection::LEFT_TO_RIGHT,
+    false
   };
 
   if( !AlignTest( data ) )
@@ -4832,7 +4847,9 @@ int UtcDaliTextAlign06(void)
     48u,
     26u,
     6u,
-    positions
+    positions,
+    Dali::LayoutDirection::LEFT_TO_RIGHT,
+    false
   };
 
   if( !AlignTest( data ) )
@@ -4951,7 +4968,9 @@ int UtcDaliTextAlign07(void)
     0u,
     22u,
     6u,
-    positions
+    positions,
+    Dali::LayoutDirection::LEFT_TO_RIGHT,
+    false
   };
 
   if( !AlignTest( data ) )
@@ -5070,7 +5089,9 @@ int UtcDaliTextAlign08(void)
     22u,
     26u,
     6u,
-    positions
+    positions,
+    Dali::LayoutDirection::LEFT_TO_RIGHT,
+    false
   };
 
   if( !AlignTest( data ) )
@@ -5189,7 +5210,130 @@ int UtcDaliTextAlign09(void)
     48u,
     26u,
     6u,
-    positions
+    positions,
+    Dali::LayoutDirection::LEFT_TO_RIGHT,
+    false
+  };
+
+  if( !AlignTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextAlign10(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextAlign10");
+
+  // Calculate text alignment.
+
+  const std::string fontLatin( "TizenSans" );
+  const std::string fontHebrew( "TizenSansHebrew" );
+  const std::string fontArabic( "TizenSansArabic" );
+
+  // Set a known font description
+  FontDescriptionRun fontDescriptionRun01;
+  fontDescriptionRun01.characterRun.characterIndex = 0u;
+  fontDescriptionRun01.characterRun.numberOfCharacters = 12u;
+  fontDescriptionRun01.familyLength = fontLatin.size();
+  fontDescriptionRun01.familyName = new char[fontDescriptionRun01.familyLength];
+  memcpy( fontDescriptionRun01.familyName, fontLatin.c_str(), fontDescriptionRun01.familyLength );
+  fontDescriptionRun01.familyDefined = true;
+  fontDescriptionRun01.weightDefined = false;
+  fontDescriptionRun01.widthDefined = false;
+  fontDescriptionRun01.slantDefined = false;
+  fontDescriptionRun01.sizeDefined = false;
+
+  FontDescriptionRun fontDescriptionRun02;
+  fontDescriptionRun02.characterRun.characterIndex = 12u;
+  fontDescriptionRun02.characterRun.numberOfCharacters = 10u;
+  fontDescriptionRun02.familyLength = fontHebrew.size();
+  fontDescriptionRun02.familyName = new char[fontDescriptionRun02.familyLength];
+  memcpy( fontDescriptionRun02.familyName, fontHebrew.c_str(), fontDescriptionRun02.familyLength );
+  fontDescriptionRun02.familyDefined = true;
+  fontDescriptionRun02.weightDefined = false;
+  fontDescriptionRun02.widthDefined = false;
+  fontDescriptionRun02.slantDefined = false;
+  fontDescriptionRun02.sizeDefined = false;
+
+  FontDescriptionRun fontDescriptionRun03;
+  fontDescriptionRun03.characterRun.characterIndex = 22u;
+  fontDescriptionRun03.characterRun.numberOfCharacters = 14u;
+  fontDescriptionRun03.familyLength = fontArabic.size();
+  fontDescriptionRun03.familyName = new char[fontDescriptionRun03.familyLength];
+  memcpy( fontDescriptionRun03.familyName, fontArabic.c_str(), fontDescriptionRun03.familyLength );
+  fontDescriptionRun03.familyDefined = true;
+  fontDescriptionRun03.weightDefined = false;
+  fontDescriptionRun03.widthDefined = false;
+  fontDescriptionRun03.slantDefined = false;
+  fontDescriptionRun03.sizeDefined = false;
+
+  FontDescriptionRun fontDescriptionRun04;
+  fontDescriptionRun04.characterRun.characterIndex = 36u;
+  fontDescriptionRun04.characterRun.numberOfCharacters = 12u;
+  fontDescriptionRun04.familyLength = fontLatin.size();
+  fontDescriptionRun04.familyName = new char[fontDescriptionRun04.familyLength];
+  memcpy( fontDescriptionRun04.familyName, fontLatin.c_str(), fontDescriptionRun04.familyLength );
+  fontDescriptionRun04.familyDefined = true;
+  fontDescriptionRun04.weightDefined = false;
+  fontDescriptionRun04.widthDefined = false;
+  fontDescriptionRun04.slantDefined = false;
+  fontDescriptionRun04.sizeDefined = false;
+
+  FontDescriptionRun fontDescriptionRun05;
+  fontDescriptionRun05.characterRun.characterIndex = 48u;
+  fontDescriptionRun05.characterRun.numberOfCharacters = 12u;
+  fontDescriptionRun05.familyLength = fontLatin.size();
+  fontDescriptionRun05.familyName = new char[fontDescriptionRun05.familyLength];
+  memcpy( fontDescriptionRun05.familyName, fontLatin.c_str(), fontDescriptionRun05.familyLength );
+  fontDescriptionRun05.familyDefined = true;
+  fontDescriptionRun05.weightDefined = false;
+  fontDescriptionRun05.widthDefined = false;
+  fontDescriptionRun05.slantDefined = false;
+  fontDescriptionRun05.sizeDefined = false;
+
+  FontDescriptionRun fontDescriptionRun06;
+  fontDescriptionRun06.characterRun.characterIndex = 60u;
+  fontDescriptionRun06.characterRun.numberOfCharacters = 14u;
+  fontDescriptionRun06.familyLength = fontArabic.size();
+  fontDescriptionRun06.familyName = new char[fontDescriptionRun06.familyLength];
+  memcpy( fontDescriptionRun06.familyName, fontArabic.c_str(), fontDescriptionRun06.familyLength );
+  fontDescriptionRun06.familyDefined = true;
+  fontDescriptionRun06.weightDefined = false;
+  fontDescriptionRun06.widthDefined = false;
+  fontDescriptionRun06.slantDefined = false;
+  fontDescriptionRun06.sizeDefined = false;
+
+  Vector<FontDescriptionRun> fontDescriptionRuns;
+  fontDescriptionRuns.PushBack( fontDescriptionRun01 );
+  fontDescriptionRuns.PushBack( fontDescriptionRun02 );
+  fontDescriptionRuns.PushBack( fontDescriptionRun03 );
+  fontDescriptionRuns.PushBack( fontDescriptionRun04 );
+  fontDescriptionRuns.PushBack( fontDescriptionRun05 );
+  fontDescriptionRuns.PushBack( fontDescriptionRun06 );
+
+  float positions[] = { -4.f, 0.f, 0.f, 0.f, 0.f, 0.f };
+
+  Size textArea( 100.f, 300.f );
+  AlignData data =
+  {
+    "Begin alignment for the first paragraph.",
+    "Hello world שלום עולם\nمرحبا بالعالم Hello world\nHello world مرحبا بالعالم.",
+    textArea,
+    6u,
+    fontDescriptionRuns.Begin(),
+    Text::HorizontalAlignment::END,
+    Text::VerticalAlignment::TOP,
+    0u,
+    22u,
+    6u,
+    positions,
+    Dali::LayoutDirection::RIGHT_TO_LEFT,
+    true
   };
 
   if( !AlignTest( data ) )
old mode 100644 (file)
new mode 100755 (executable)
index f19cb12..ffa0a61
@@ -1062,6 +1062,22 @@ int UtcDaliToolkitTextlabelEllipsis(void)
     tet_result(TET_FAIL);
   }
 
+
+  label.SetProperty( TextLabel::Property::TEXT, "Hello world" );
+  label.SetProperty( DevelTextLabel::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION, true );
+  label.SetSize( 400.0f, 10.f );
+
+  try
+  {
+    // Render the text.
+    application.SendNotification();
+    application.Render();
+  }
+  catch( ... )
+  {
+    tet_result(TET_FAIL);
+  }
+
   END_TEST;
 }
 
@@ -1334,4 +1350,4 @@ int UtcDaliToolkitTextlabelVerticalLineAlignment(void)
   DALI_TEST_EQUALS( label.GetProperty< int >( DevelTextLabel::Property::VERTICAL_LINE_ALIGNMENT ), static_cast< int >( Toolkit::DevelText::VerticalLineAlignment::BOTTOM ), TEST_LOCATION );
 
   END_TEST;
-}
\ No newline at end of file
+}
old mode 100644 (file)
new mode 100755 (executable)
index 0b16273..ec6b935
@@ -101,6 +101,27 @@ namespace Property
      * @note The default value is true
      */
     IGNORE_SPACES_AFTER_TEXT,
+
+    /**
+     * @brief Modifies the default text alignment to match the direction of the system language.
+     * @details Name "matchSystemLanguageDirection", type (Property::BOLEAN), Read/Write
+     * @note The default value is false
+     *
+     * If MATCH_SYSTEM_LANGUAGE_DIRECTION property set true, the default text alignment to match the direction of the system language.
+     *
+     * ex) Current system language direction LTR.
+     *     TextLabel::New("Hello world \n  ﻡﺮﺤﺑﺍ. ");
+     *     TextLabel::Property::HORIZONTAL_ALIGNMENT, "END"
+     *
+     * | TextLabel::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION                 |
+     * |-----------------------------------------------------------------------
+     * |        false (default)            |                true              |
+     * |-----------------------------------|----------------------------------|
+     * |                     Hello world   |                  Hello world     |
+     * |   ﻡﺮﺤﺑﺍ.                          |                      ﻡﺮﺤﺑﺍ.      |
+     *
+     */
+    MATCH_SYSTEM_LANGUAGE_DIRECTION,
   };
 
 } // namespace Property
index 94d0f20..af57128 100755 (executable)
@@ -1351,7 +1351,7 @@ void TextEditor::OnRelayout( const Vector2& size, RelayoutContainer& container )
     mActiveLayer.SetPosition( padding.start, padding.top );
   }
 
-  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize );
+  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize, layoutDirection );
 
   if( ( Text::Controller::NONE_UPDATED != updateTextType ) ||
       !mRenderer )
index 95e4765..d4485ba 100755 (executable)
@@ -1397,7 +1397,7 @@ void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
     mActiveLayer.SetPosition( padding.start, padding.top );
   }
 
-  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize );
+  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize, layoutDirection );
 
   if( ( Text::Controller::NONE_UPDATED != updateTextType ) ||
       !mRenderer )
old mode 100644 (file)
new mode 100755 (executable)
index bb40d00..7a8c283
@@ -132,6 +132,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY( Toolkit, TextLabel, "textDirection",
 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_DEVEL_PROPERTY_REGISTRATION( Toolkit,     TextLabel, "matchSystemLanguageDirection", BOOLEAN, MATCH_SYSTEM_LANGUAGE_DIRECTION )
 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  )
@@ -539,6 +540,11 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
         impl.mController->SetIgnoreSpacesAfterText(value.Get< bool >());
         break;
       }
+      case Toolkit::DevelTextLabel::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
+      {
+        impl.mController->SetMatchSystemLanguageDirection(value.Get< bool >());
+        break;
+      }
     }
 
     // Request relayout when text update is needed. It's necessary to call it
@@ -842,6 +848,11 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
         value = impl.mController->IsIgnoreSpacesAfterText();
         break;
       }
+      case Toolkit::DevelTextLabel::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
+      {
+        value = impl.mController->IsMatchSystemLanguageDirection();
+        break;
+      }
     }
   }
 
@@ -962,7 +973,10 @@ void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container )
 
   Vector2 contentSize( size.x - ( padding.start + padding.end ), size.y - ( padding.top + padding.bottom ) );
 
-  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize );
+  // Support Right-To-Left
+  Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>( Self().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
+
+  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize, layoutDirection );
 
   if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) )
      || mTextUpdateNeeded )
@@ -973,7 +987,6 @@ void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container )
     TextVisual::EnableRendererUpdate( mVisual );
 
     // Support Right-To-Left of padding
-    Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>( Self().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
     if( Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection )
     {
       std::swap( padding.start, padding.end );
old mode 100644 (file)
new mode 100755 (executable)
index 061707a..0c3d9df
@@ -1104,7 +1104,9 @@ struct Engine::Impl
               Length numberOfCharacters,
               Text::HorizontalAlignment::Type horizontalAlignment,
               Vector<LineRun>& lines,
-              float& alignmentOffset )
+              float& alignmentOffset,
+              Dali::LayoutDirection::Type layoutDirection,
+              bool matchSystemLanguageDirection )
   {
     const CharacterIndex lastCharacterPlusOne = startIndex + numberOfCharacters;
 
@@ -1132,7 +1134,9 @@ struct Engine::Impl
       // the box width, line length, and the paragraph's direction.
       CalculateHorizontalAlignment( size.width,
                                     horizontalAlignment,
-                                    line );
+                                    line,
+                                    layoutDirection,
+                                    matchSystemLanguageDirection );
 
       // Updates the alignment offset.
       alignmentOffset = std::min( alignmentOffset, line.alignmentOffset );
@@ -1141,16 +1145,24 @@ struct Engine::Impl
 
   void CalculateHorizontalAlignment( float boxWidth,
                                      HorizontalAlignment::Type horizontalAlignment,
-                                     LineRun& line )
+                                     LineRun& line,
+                                     Dali::LayoutDirection::Type layoutDirection,
+                                     bool matchSystemLanguageDirection )
   {
     line.alignmentOffset = 0.f;
-    const bool isRTL = RTL == line.direction;
+    bool isRTL = RTL == line.direction;
     float lineLength = line.width;
-
     HorizontalAlignment::Type alignment = horizontalAlignment;
+
+    // match align for system language direction
+    if( matchSystemLanguageDirection )
+    {
+      isRTL = layoutDirection == LayoutDirection::RIGHT_TO_LEFT;
+    }
+
+    // Swap the alignment type if the line is right to left.
     if( isRTL )
     {
-      // Swap the alignment type if the line is right to left.
       switch( alignment )
       {
         case HorizontalAlignment::BEGIN:
@@ -1169,6 +1181,7 @@ struct Engine::Impl
           break;
         }
       }
+
     }
 
     // Calculate the horizontal line offset.
@@ -1300,14 +1313,18 @@ void Engine::Align( const Size& size,
                     Length numberOfCharacters,
                     Text::HorizontalAlignment::Type horizontalAlignment,
                     Vector<LineRun>& lines,
-                    float& alignmentOffset )
+                    float& alignmentOffset,
+                    Dali::LayoutDirection::Type layoutDirection,
+                    bool matchSystemLanguageDirection )
 {
   mImpl->Align( size,
                 startIndex,
                 numberOfCharacters,
                 horizontalAlignment,
                 lines,
-                alignmentOffset );
+                alignmentOffset,
+                layoutDirection,
+                matchSystemLanguageDirection );
 }
 
 void Engine::SetDefaultLineSpacing( float lineSpacing )
old mode 100644 (file)
new mode 100755 (executable)
index 66525d1..5e80d8c
@@ -21,6 +21,7 @@
 // EXTERNAL INCLUDE
 #include <dali/public-api/common/dali-vector.h>
 #include <dali/public-api/math/vector2.h>
+#include <dali/public-api/actors/actor-enumerations.h>
 
 // INTERNAL INCLUDE
 #include <dali-toolkit/public-api/text/text-enumerations.h>
@@ -140,13 +141,17 @@ public:
    * @param[in] horizontalAlignment The horizontal alignment.
    * @param[in,out] lines The laid-out lines.
    * @param[out] alignmentOffset The alignment offset.
+   * @param[in] layoutDirection The direction of the system language.
+   * @param[in] matchSystemLanguageDirection Whether match align for system language direction or not.
    */
   void Align( const Size& size,
               CharacterIndex startIndex,
               Length numberOfCharacters,
               Text::HorizontalAlignment::Type horizontalAlignment,
               Vector<LineRun>& lines,
-              float& alignmentOffset );
+              float& alignmentOffset,
+              Dali::LayoutDirection::Type layoutDirection,
+              bool matchSystemLanguageDirection );
 
   /**
    * @brief Sets the default line spacing.
old mode 100644 (file)
new mode 100755 (executable)
index 5a77d86..ecd1f6b
@@ -60,6 +60,9 @@ struct Parameters
    * @param[in] totalNumberOfGlyphs The number of glyphs.
    * @param[in] horizontalAlignment The horizontal alignment.
    * @param[in] lineWrapMode The text wrap mode.
+   * @param[in] outlineWidth The outline width.
+   * @param[in] ignoreSpaceAfterText Whether ignoring spaces after text or not.
+   * @param[in] matchSystemLanguageDirection Whether match align for system language direction or not..
    */
   Parameters( const Vector2& boundingBox,
               const Character* const textBuffer,
@@ -75,7 +78,8 @@ struct Parameters
               Text::HorizontalAlignment::Type horizontalAlignment,
               Text::LineWrap::Mode lineWrapMode,
               float outlineWidth,
-              bool ignoreSpaceAfterText )
+              bool ignoreSpaceAfterText,
+              bool matchSystemLanguageDirection )
   : boundingBox( boundingBox ),
     textBuffer( textBuffer ),
     lineBreakInfoBuffer( lineBreakInfoBuffer ),
@@ -97,7 +101,8 @@ struct Parameters
     lineWrapMode( lineWrapMode ),
     outlineWidth( outlineWidth ),
     isLastNewParagraph( false ),
-    ignoreSpaceAfterText( ignoreSpaceAfterText )
+    ignoreSpaceAfterText( ignoreSpaceAfterText ),
+    matchSystemLanguageDirection ( matchSystemLanguageDirection )
   {}
 
   Vector2                         boundingBox;                     ///< The size of the box containing the text.
@@ -122,6 +127,7 @@ struct Parameters
   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.
+  bool                            matchSystemLanguageDirection:1;  ///< Whether match align for system language direction or not. Default is false.
 };
 
 } // namespace Layout
index 34601f5..3e50faf 100755 (executable)
@@ -329,7 +329,8 @@ struct Controller::Impl
     mShadowSetByString( false ),
     mOutlineSetByString( false ),
     mFontStyleSetByString( false ),
-    mShouldClearFocusOnEscape( true )
+    mShouldClearFocusOnEscape( true ),
+    mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT )
   {
     mModel = Model::New();
 
@@ -765,6 +766,7 @@ public:
   bool mOutlineSetByString:1;              ///< Set when outline is set by string (legacy) instead of map
   bool mFontStyleSetByString:1;            ///< Set when font style is set by string (legacy) instead of map
   bool mShouldClearFocusOnEscape:1;        ///< Whether text control should clear key input focus
+  LayoutDirection::Type mLayoutDirection;  ///< Current system language direction
 };
 
 } // namespace Text
index 033433b..f0b496f 100755 (executable)
@@ -417,6 +417,17 @@ void Controller::SetIgnoreSpacesAfterText( bool ignore )
   mImpl->mModel->mIgnoreSpacesAfterText = ignore;
 }
 
+bool Controller::IsMatchSystemLanguageDirection() const
+{
+  return mImpl->mModel->mMatchSystemLanguageDirection;
+}
+
+void Controller::SetMatchSystemLanguageDirection( bool match )
+{
+  mImpl->mModel->mMatchSystemLanguageDirection = match;
+}
+
+
 void Controller::SetLineWrapMode( Text::LineWrap::Mode lineWrapMode )
 {
   if( lineWrapMode != mImpl->mModel->mLineWrapMode )
@@ -2228,12 +2239,13 @@ void Controller::SetVerticalLineAlignment( Toolkit::DevelText::VerticalLineAlign
 
 // public : Relayout.
 
-Controller::UpdateTextType Controller::Relayout( const Size& size )
+Controller::UpdateTextType Controller::Relayout( const Size& size, Dali::LayoutDirection::Type layoutDirection )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->Controller::Relayout %p size %f,%f, autoScroll[%s]\n", this, size.width, size.height, mImpl->mIsAutoScrollEnabled ?"true":"false"  );
 
   UpdateTextType updateTextType = NONE_UPDATED;
 
+  mImpl->mLayoutDirection = layoutDirection;
   if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
   {
     if( 0u != mImpl->mModel->mVisualModel->mGlyphPositions.Count() )
@@ -3543,7 +3555,8 @@ bool Controller::DoRelayout( const Size& size,
                                          mImpl->mModel->mHorizontalAlignment,
                                          mImpl->mModel->mLineWrapMode,
                                          outlineWidth,
-                                         mImpl->mModel->mIgnoreSpacesAfterText );
+                                         mImpl->mModel->mIgnoreSpacesAfterText,
+                                         mImpl->mModel->mMatchSystemLanguageDirection );
 
     // Resize the vector of positions to have the same size than the vector of glyphs.
     Vector<Vector2>& glyphPositions = mImpl->mModel->mVisualModel->mGlyphPositions;
@@ -3661,7 +3674,9 @@ bool Controller::DoRelayout( const Size& size,
                                 requestedNumberOfCharacters,
                                 mImpl->mModel->mHorizontalAlignment,
                                 lines,
-                                mImpl->mModel->mAlignmentOffset );
+                                mImpl->mModel->mAlignmentOffset,
+                                mImpl->mLayoutDirection,
+                                mImpl->mModel->mMatchSystemLanguageDirection );
 
     viewUpdated = true;
   }
index 25bb13b..f92a69d 100755 (executable)
@@ -1243,6 +1243,18 @@ public: // Queries & retrieves.
    */
   void SetIgnoreSpacesAfterText( bool ignore );
 
+  /**
+   * @brief Retrieves matchSystemLanguageDirection value from model
+   * @return The value of matchSystemLanguageDirection
+   */
+  bool IsMatchSystemLanguageDirection() const;
+
+  /**
+   * @brief Sets matchSystemLanguageDirection value to model
+   * @param[in] match The value of matchSystemLanguageDirection for the text
+   */
+  void SetMatchSystemLanguageDirection( bool match );
+
 public: // Relayout.
 
   /**
@@ -1250,10 +1262,11 @@ public: // Relayout.
    *
    * @note UI Controls are expected to minimize calls to this method e.g. call once after size negotiation.
    * @param[in] size A the size of a bounding box to layout text within.
+   * @param[in] layoutDirection The direction of the system language.
    *
    * @return Whether the text model or decorations were updated.
    */
-  UpdateTextType Relayout( const Size& size );
+  UpdateTextType Relayout( const Size& size, Dali::LayoutDirection::Type layoutDirection = Dali::LayoutDirection::LEFT_TO_RIGHT );
 
   /**
    * @brief Request a relayout using the ControlInterface.
index 65494e5..474b3ae 100755 (executable)
@@ -188,7 +188,8 @@ Model::Model()
   mLineWrapMode( Text::LineWrap::WORD ),
   mAlignmentOffset( 0.0f ),
   mElideEnabled( false ),
-  mIgnoreSpacesAfterText( true )
+  mIgnoreSpacesAfterText( true ),
+  mMatchSystemLanguageDirection( false )
 {
   mLogicalModel = LogicalModel::New();
   mVisualModel = VisualModel::New();
index 1ea725c..688eac4 100755 (executable)
@@ -239,6 +239,7 @@ public:
   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.
+  bool                                      mMatchSystemLanguageDirection:1; ///< Whether match align for system language direction or not. Default is false.
 };
 
 } // namespace Text
index b8edc7a..4b3176c 100755 (executable)
@@ -634,7 +634,9 @@ void TextVisual::UpdateRenderer()
     return;
   }
 
-  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( relayoutSize );
+  Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>( control.GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
+
+  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( relayoutSize, layoutDirection );
 
   if( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType )
    || mRendererUpdateNeeded )
index 43bd4e5..842a568 100644 (file)
@@ -67,7 +67,8 @@
       "autoScrollLoopCount":2,
       "autoScrollGap":50,
       "autoScrollSpeed":80,
-      "ignoreSpacesAfterText":false
+      "ignoreSpacesAfterText":false,
+      "matchSystemLanguageDirection":true
     },
 
     "TextLabelFontSize0":
diff --git a/docs/content/images/text-controls/HelloWorld-Default-END.png b/docs/content/images/text-controls/HelloWorld-Default-END.png
new file mode 100755 (executable)
index 0000000..3302d08
Binary files /dev/null and b/docs/content/images/text-controls/HelloWorld-Default-END.png differ
diff --git a/docs/content/images/text-controls/HelloWorld-System-END.png b/docs/content/images/text-controls/HelloWorld-System-END.png
new file mode 100755 (executable)
index 0000000..2794090
Binary files /dev/null and b/docs/content/images/text-controls/HelloWorld-System-END.png differ
old mode 100644 (file)
new mode 100755 (executable)
index f1c3b77..9b463e4
@@ -89,6 +89,30 @@ label.HorizontalAlignment = "BEGIN"; // "CENTER" or "END"
 | ![ ](../assets/img/text-controls/LatinEnd.png) ![ ](LatinEnd.png) | ![ ](../assets/img/text-controls/ArabicEnd.png) ![ ](ArabicEnd.png) |
 
 
+
+The text's alignment can be modified to match the direction of the system language.
+
+If the MATCH_SYSTEM_LANGUAGE_DIRECTION property is set to true then the direction of the text is ignored, instead the text is aligned as the system default language.
+
+~~~{.cpp}
+// C++
+
+label.SetProperty( TextLabel::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION, true );
+~~~
+
+~~~{.js}
+// JavaScript
+
+label.matchSystemLanguageDirection = true;
+~~~
+
+|  |  |
+|--|--|
+| Current system language direction left-to-right | |
+| END alignment and MATCH_SYSTEM_LANGUAGE_DIRECTION set to TRUE. | END alignment and MATCH_SYSTEM_LANGUAGE_DIRECTION set to FALSE (default). |
+| ![ ](HelloWorld-System-END.png) | ![ ](HelloWorld-Default-END.png) |
+
+
 The examples above assume that the TextLabel size greater than the minimum required.  
 The next section provides details about the other size related options.