bug fixed : Characters are truncated when HorizontalAlignment.End in 86/192086/9
authorJoogab Yun <joogab.yun@samsung.com>
Tue, 30 Oct 2018 05:18:14 +0000 (14:18 +0900)
committerJoogab Yun <joogab.yun@samsung.com>
Tue, 6 Nov 2018 04:22:02 +0000 (13:22 +0900)
Multi line text on RTL environment.

Recalculate the alignmentOffset only if the line is RTL.

We need to distinguish the RTL variable for alignment and the RTL variable for the text line for position offset.
So the RTL check of the text line is called isLineRTL.

ex)
When running the sample app below, the characters are truncated.

 Stage stage = Stage::GetCurrent();
 stage.SetBackgroundColor( Color::WHITE );

 TextLabel label = TextLabel::New( "Music, Film & TV, Funny, News,
Sports... Access millions of user generaed content and professional
videos from DAILYMOTION website on your SAMSUNG TV.Search, browse and
watch, get a direct access to your own or favorite accounts, watch a
selection of best" );
 label.SetSize( 1250, 600 );
 label.SetParentOrigin(ParentOrigin::TOP_LEFT);
 label.SetAnchorPoint(AnchorPoint::TOP_LEFT);
 label.SetPosition( 100.f, 700.f);
 label.SetProperty( TextLabel::Property::MULTI_LINE, true );
 label.SetProperty(TextLabel::Property::POINT_SIZE, 30);
 label.SetProperty(TextLabel::Property::HORIZONTAL_ALIGNMENT,
"END");
 label.SetProperty(Toolkit::DevelTextLabel::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION,
true );
 label.SetProperty( Actor::Property::LAYOUT_DIRECTION,
LayoutDirection::RIGHT_TO_LEFT );

 stage.Add( label );

Change-Id: I0c1161330de073cef466d8e7119a56a9be606034

automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Layout.cpp
dali-toolkit/internal/text/layouts/layout-engine.cpp

index bc9d08b8fe2faf0a5b629c1a8527490d3e1717bf..b9278e3882fc8e97d476a3bc167d55e55906adea 100755 (executable)
@@ -5316,7 +5316,7 @@ int UtcDaliTextAlign10(void)
   fontDescriptionRuns.PushBack( fontDescriptionRun05 );
   fontDescriptionRuns.PushBack( fontDescriptionRun06 );
 
-  float positions[] = { -4.f, 0.f, 0.f, 0.f, 0.f, 0.f };
+  float positions[] = { 0.f, 0.f, 0.f, 0.f, 0.f, 0.f };
 
   Size textArea( 100.f, 300.f );
   AlignData data =
@@ -5345,6 +5345,248 @@ int UtcDaliTextAlign10(void)
   END_TEST;
 }
 
+int UtcDaliTextAlign11(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextAlign11");
+
+  // 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[] = { 20.f, 33.f, 2.f, 0.f, 0.f, 0.f };
+
+  Size textArea( 100.f, 300.f );
+  AlignData data =
+  {
+    "End alignment for the last paragraph.",
+    "Hello world שלום עולם\nمرحبا بالعالم Hello world\nHello world مرحبا بالعالم.",
+    textArea,
+    6u,
+    fontDescriptionRuns.Begin(),
+    Text::HorizontalAlignment::END,
+    Text::VerticalAlignment::TOP,
+    0u,
+    26u,
+    6u,
+    positions,
+    Dali::LayoutDirection::LEFT_TO_RIGHT,
+    true
+  };
+
+  if( !AlignTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextAlign12(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextAlign12");
+
+  // 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[] = { 0.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::BEGIN,
+    Text::VerticalAlignment::TOP,
+    48u,
+    26u,
+    6u,
+    positions,
+    Dali::LayoutDirection::LEFT_TO_RIGHT,
+    true
+  };
+
+  if( !AlignTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
 int UtcDaliTextLayoutSetGetDefaultLineSpacing(void)
 {
   ToolkitTestApplication application;
index 0c3d9df9d02bf945a8dfafe39eb1dc9f09ef7ca0..4f9876c8cc45fd0d4a6e3c3c7a20720e4fe78c4d 100755 (executable)
@@ -1150,51 +1150,41 @@ struct Engine::Impl
                                      bool matchSystemLanguageDirection )
   {
     line.alignmentOffset = 0.f;
-    bool isRTL = RTL == line.direction;
+    const bool isLineRTL = RTL == line.direction;
+    // Whether to swap the alignment.
+    // Swap if the line is RTL and is not required to match the direction of the system's language or if it's required to match the direction of the system's language and it's RTL.
+    bool isLayoutRTL = isLineRTL;
     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.
+      isLayoutRTL = layoutDirection == LayoutDirection::RIGHT_TO_LEFT;
     }
-
-    // Swap the alignment type if the line is right to left.
-    if( isRTL )
-    {
-      switch( alignment )
-      {
-        case HorizontalAlignment::BEGIN:
-        {
-          alignment = HorizontalAlignment::END;
-          break;
-        }
-        case HorizontalAlignment::CENTER:
-        {
-          // Nothing to do.
-          break;
-        }
-        case HorizontalAlignment::END:
-        {
-          alignment = HorizontalAlignment::BEGIN;
-          break;
-        }
-      }
-
-    }
-
     // Calculate the horizontal line offset.
-    switch( alignment )
+    switch( horizontalAlignment )
     {
       case HorizontalAlignment::BEGIN:
       {
-        line.alignmentOffset = 0.f;
+        if( isLayoutRTL )
+        {
+          if( isLineRTL )
+          {
+            lineLength += line.extraLength;
+          }
 
-        if( isRTL )
+          line.alignmentOffset = boxWidth - lineLength;
+        }
+        else
         {
-          // 'Remove' the white spaces at the end of the line (which are at the beginning in visual order)
-          line.alignmentOffset -= line.extraLength;
+          line.alignmentOffset = 0.f;
+
+          if( isLineRTL )
+          {
+            // 'Remove' the white spaces at the end of the line (which are at the beginning in visual order)
+            line.alignmentOffset -= line.extraLength;
+          }
         }
         break;
       }
@@ -1202,7 +1192,7 @@ struct Engine::Impl
       {
         line.alignmentOffset = 0.5f * ( boxWidth - lineLength );
 
-        if( isRTL )
+        if( isLineRTL )
         {
           line.alignmentOffset -= line.extraLength;
         }
@@ -1212,12 +1202,25 @@ struct Engine::Impl
       }
       case HorizontalAlignment::END:
       {
-        if( isRTL )
+        if( isLayoutRTL )
         {
-          lineLength += line.extraLength;
+          line.alignmentOffset = 0.f;
+
+          if( isLineRTL )
+          {
+            // 'Remove' the white spaces at the end of the line (which are at the beginning in visual order)
+            line.alignmentOffset -= line.extraLength;
+          }
         }
+        else
+        {
+          if( isLineRTL )
+          {
+            lineLength += line.extraLength;
+          }
 
-        line.alignmentOffset = boxWidth - lineLength;
+          line.alignmentOffset = boxWidth - lineLength;
+        }
         break;
       }
     }