Add the alignment offset to the glyph lines. 11/40811/10
authorVictor Cebollada <v.cebollada@samsung.com>
Tue, 9 Jun 2015 08:47:25 +0000 (09:47 +0100)
committerVictor Cebollada <v.cebollada@samsung.com>
Thu, 11 Jun 2015 09:54:37 +0000 (10:54 +0100)
When the lines are horizontally aligned, we don't
want to modify the original layout. Subsequent calls
to Layout::Align() will always use the original layout
and modify only the alignment offset of each line.
The TextView is the responsible of adding the offset
to get the final layout.

Change-Id: Id8c1fea9a75e77b597b6744f226ef566408e6e8c
Signed-off-by: Victor Cebollada <v.cebollada@samsung.com>
dali-toolkit/internal/text/layouts/layout-engine.cpp
dali-toolkit/internal/text/layouts/layout-engine.h
dali-toolkit/internal/text/line-run.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-view.cpp
dali-toolkit/internal/text/visual-model-impl.cpp
dali-toolkit/internal/text/visual-model-impl.h

index d1c38e2..b018ed1 100644 (file)
@@ -508,6 +508,7 @@ struct LayoutEngine::Impl
     }
 
     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--LayoutText\n\n" );
     }
 
     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--LayoutText\n\n" );
+
     return true;
   }
 
     return true;
   }
 
@@ -556,76 +557,36 @@ struct LayoutEngine::Impl
     }
   }
 
     }
   }
 
-  void Align( const LayoutParameters& layoutParameters,
-              const Size& layoutSize,
-              const Vector<LineRun>& lines,
-              Vector<Vector2>& glyphPositions )
+  void Align( const Size& layoutSize,
+              Vector<LineRun>& lines )
   {
   {
-    Vector2* glyphPositionsBuffer = glyphPositions.Begin();
-
     // Traverse all lines and align the glyphs.
     // Traverse all lines and align the glyphs.
-    // LayoutParameters contains bidirectional info for those lines with
-    // right to left text, this info includes the paragraph's direction.
 
 
-    LineIndex bidiLineIndex = 0u;
-    for( Vector<LineRun>::ConstIterator it = lines.Begin(), endIt = lines.End();
+    for( Vector<LineRun>::Iterator it = lines.Begin(), endIt = lines.End();
          it != endIt;
          ++it )
     {
          it != endIt;
          ++it )
     {
-      const LineRun& line = *it;
-
-      // 1) Get the paragrap's direction.
-      bool paragraphDirection = false;
-
-      // Check if there is any right to left line.
-      if( ( NULL != layoutParameters.lineBidirectionalInfoRunsBuffer ) &&
-          ( bidiLineIndex < layoutParameters.numberOfBidirectionalInfoRuns ) )
-      {
-        const BidirectionalLineInfoRun* bidiLine = layoutParameters.lineBidirectionalInfoRunsBuffer + bidiLineIndex;
-
-        // Get the right to left line that match with current line.
-        while( ( line.characterRun.characterIndex > bidiLine->characterRun.characterIndex ) &&
-               ( bidiLineIndex < layoutParameters.numberOfBidirectionalInfoRuns ) )
-        {
-          ++bidiLineIndex;
-          bidiLine = layoutParameters.lineBidirectionalInfoRunsBuffer + bidiLineIndex;
-        }
-
-        if( line.characterRun.characterIndex == bidiLine->characterRun.characterIndex )
-        {
-          paragraphDirection = bidiLine->direction;
-        }
-      }
-
-      // 2) Calculate the alignment offset accordingly with the align option,
-      //    the box width, line length, and the paragraphs direction.
-      float alignOffset = CalculateHorizontalAlignment( layoutSize.width,
-                                                        line.width,
-                                                        line.extraLength,
-                                                        paragraphDirection );
-
-      // 3) Traverse all glyphs and update the 'x' position.
-      for( GlyphIndex index = line.glyphIndex,
-             endIndex = line.glyphIndex + line.numberOfGlyphs;
-           index < endIndex;
-           ++index )
-      {
-        Vector2& position = *( glyphPositionsBuffer + index );
-
-        position.x += alignOffset;
-      }
+      LineRun& line = *it;
+      const bool isLastLine = lines.End() == it + 1u;
+
+      // Calculate the alignment offset accordingly with the align option,
+      // the box width, line length, and the paragraphs direction.
+      CalculateHorizontalAlignment( layoutSize.width,
+                                    line,
+                                    isLastLine );
     }
   }
 
     }
   }
 
-  float CalculateHorizontalAlignment( float boxWidth,
-                                      float lineLength,
-                                      float extraLength,
-                                      bool paragraphDirection )
+  void CalculateHorizontalAlignment( float boxWidth,
+                                     LineRun& line,
+                                     bool isLastLine )
   {
   {
-    float offset = 0.f;
+    line.alignmentOffset = 0.f;
+    const bool isRTL = RTL == line.direction;
+    float lineLength = line.width;
 
     HorizontalAlignment alignment = mHorizontalAlignment;
 
     HorizontalAlignment alignment = mHorizontalAlignment;
-    if( paragraphDirection &&
+    if( isRTL &&
         ( HORIZONTAL_ALIGN_CENTER != alignment ) )
     {
       if( HORIZONTAL_ALIGN_BEGIN == alignment )
         ( HORIZONTAL_ALIGN_CENTER != alignment ) )
     {
       if( HORIZONTAL_ALIGN_BEGIN == alignment )
@@ -642,29 +603,25 @@ struct LayoutEngine::Impl
     {
       case HORIZONTAL_ALIGN_BEGIN:
       {
     {
       case HORIZONTAL_ALIGN_BEGIN:
       {
-        offset = 0.f;
+        line.alignmentOffset = 0.f;
         break;
       }
       case HORIZONTAL_ALIGN_CENTER:
       {
         break;
       }
       case HORIZONTAL_ALIGN_CENTER:
       {
-        offset = 0.5f * ( boxWidth - lineLength );
-        const int intOffset = static_cast<int>( offset ); // try to avoid pixel alignment.
-        offset = static_cast<float>( intOffset );
+        line.alignmentOffset = floorf( 0.5f * ( boxWidth - lineLength ) ); // try to avoid pixel alignment.
         break;
       }
       case HORIZONTAL_ALIGN_END:
       {
         break;
       }
       case HORIZONTAL_ALIGN_END:
       {
-        offset = boxWidth - lineLength;
+        line.alignmentOffset = boxWidth - lineLength;
         break;
       }
     }
 
         break;
       }
     }
 
-    if( paragraphDirection )
+    if( isRTL )
     {
     {
-      offset -= extraLength;
+      line.alignmentOffset -= line.extraLength;
     }
     }
-
-    return offset;
   }
 
   LayoutEngine::Layout mLayout;
   }
 
   LayoutEngine::Layout mLayout;
@@ -745,15 +702,11 @@ void LayoutEngine::ReLayoutRightToLeftLines( const LayoutParameters& layoutParam
                                    glyphPositions );
 }
 
                                    glyphPositions );
 }
 
-void LayoutEngine::Align( const LayoutParameters& layoutParameters,
-                          const Size& layoutSize,
-                          const Vector<LineRun>& lines,
-                          Vector<Vector2>& glyphPositions )
+void LayoutEngine::Align( const Size& layoutSize,
+                          Vector<LineRun>& lines )
 {
 {
-  mImpl->Align( layoutParameters,
-                layoutSize,
-                lines,
-                glyphPositions );
+  mImpl->Align( layoutSize,
+                lines );
 }
 
 } // namespace Text
 }
 
 } // namespace Text
index 42ff1aa..e48de90 100644 (file)
@@ -158,15 +158,11 @@ public:
   /**
    * @brief Aligns the laid out lines.
    *
   /**
    * @brief Aligns the laid out lines.
    *
-   * @param[in] layoutParameters The parameters needed to layout the text.
    * @param[in] layoutSize The size of the laid out the text.
    * @param[in] layoutSize The size of the laid out the text.
-   * @param[in] lines The laid-out lines.
-   * @param[in,out] glyphPositions The positions of all the glyphs.
+   * @param[in,out] lines The laid-out lines.
    */
    */
-  void Align( const LayoutParameters& layoutParameters,
-              const Size& layoutSize,
-              const Vector<LineRun>& lines,
-              Vector<Vector2>& glyphPositions );
+  void Align( const Size& layoutSize,
+              Vector<LineRun>& lines );
 
 private:
 
 
 private:
 
index 5668669..584d758 100644 (file)
@@ -38,15 +38,16 @@ namespace Text
  */
 struct LineRun
 {
  */
 struct LineRun
 {
-  GlyphIndex         glyphIndex;     ///< The initial glyph index.
-  Length             numberOfGlyphs; ///< The number of glyphs of the run.
-  CharacterRun       characterRun;   ///< The initial character and the number of characters.
-  float              width;          ///< The line's width.
-  float              ascender;       ///< The line's ascender.
-  float              descender;      ///< The line's descender.
-  float              extraLength;    ///< The length of the white spaces at the end of the line.
-  CharacterDirection direction : 1;  ///< Direction of the first character of the paragraph.
-  bool               ellipsis  : 1;  ///< Wheter ellipsis is added to the line.
+  GlyphIndex         glyphIndex;      ///< The initial glyph index.
+  Length             numberOfGlyphs;  ///< The number of glyphs of the run.
+  CharacterRun       characterRun;    ///< The initial character and the number of characters.
+  float              width;           ///< The line's width.
+  float              ascender;        ///< The line's ascender.
+  float              descender;       ///< The line's descender.
+  float              extraLength;     ///< The length of the white spaces at the end of the line.
+  float              alignmentOffset; ///< The horizontal alignment offset.
+  CharacterDirection direction : 1;   ///< Direction of the first character of the paragraph.
+  bool               ellipsis  : 1;   ///< Wheter ellipsis is added to the line.
 };
 
 } // namespace Text
 };
 
 } // namespace Text
index 36b566b..d584c73 100644 (file)
@@ -893,17 +893,6 @@ bool Controller::DoRelayout( const Size& size,
         }
       } // REORDER
 
         }
       } // REORDER
 
-      // TODO: I'm working on a patch that changes the LayoutEngine::Align() method.
-      //       The layoutParameters is not needed and this call can be moved outside the if().
-      //       Then there is no need to do the layout again to change the alignment.
-      if( ALIGN & operations )
-      {
-        mImpl->mLayoutEngine.Align( layoutParameters,
-                                    layoutSize,
-                                    lines,
-                                    glyphPositions );
-      }
-
       // Sets the actual size.
       if( UPDATE_ACTUAL_SIZE & operations )
       {
       // Sets the actual size.
       if( UPDATE_ACTUAL_SIZE & operations )
       {
@@ -916,6 +905,17 @@ bool Controller::DoRelayout( const Size& size,
     layoutSize = mImpl->mVisualModel->GetActualSize();
   }
 
     layoutSize = mImpl->mVisualModel->GetActualSize();
   }
 
+  if( ALIGN & operations )
+  {
+    // The laid-out lines.
+    Vector<LineRun>& lines = mImpl->mVisualModel->mLines;
+
+    mImpl->mLayoutEngine.Align( layoutSize,
+                                lines );
+
+    viewUpdated = true;
+  }
+
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::DoRelayout, view updated %s\n", ( viewUpdated ? "true" : "false" ) );
   return viewUpdated;
 }
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::DoRelayout, view updated %s\n", ( viewUpdated ? "true" : "false" ) );
   return viewUpdated;
 }
@@ -954,15 +954,7 @@ void Controller::SetHorizontalAlignment( LayoutEngine::HorizontalAlignment align
     mImpl->mLayoutEngine.SetHorizontalAlignment( alignment );
 
     // Set the flag to redo the alignment operation.
     mImpl->mLayoutEngine.SetHorizontalAlignment( alignment );
 
     // Set the flag to redo the alignment operation.
-    // TODO : Is not needed re-layout and reorder again but with the current implementation it is.
-    //        Im working on a different patch to fix an issue with the alignment. When that patch
-    //        is in, this issue can be fixed.
-    const OperationsMask layoutOperations =  static_cast<OperationsMask>( LAYOUT             |
-                                                                          UPDATE_ACTUAL_SIZE |
-                                                                          ALIGN              |
-                                                                          REORDER );
-
-    mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending | layoutOperations );
+    mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending | ALIGN );
 
     mImpl->RequestRelayout();
   }
 
     mImpl->RequestRelayout();
   }
index 47a2028..414fffa 100644 (file)
@@ -92,6 +92,48 @@ Length View::GetGlyphs( GlyphInfo* glyphs,
                                               glyphIndex,
                                               numberOfLaidOutGlyphs );
 
                                               glyphIndex,
                                               numberOfLaidOutGlyphs );
 
+      // Get the lines for the given range of glyphs.
+      // The lines contain the alignment offset which needs to be added to the glyph's position.
+      LineIndex firstLine = 0u;
+      Length numberOfLines = 0u;
+      mImpl->mVisualModel->GetNumberOfLines( glyphIndex,
+                                             numberOfLaidOutGlyphs,
+                                             firstLine,
+                                             numberOfLines );
+
+      Vector<LineRun> lines;
+      lines.Resize( numberOfLines );
+      LineRun* lineBuffer = lines.Begin();
+
+      mImpl->mVisualModel->GetLinesOfGlyphRange( lineBuffer,
+                                                 glyphIndex,
+                                                 numberOfLaidOutGlyphs );
+
+      // Get the first line for the given glyph range.
+      LineIndex lineIndex = firstLine;
+      LineRun* line = lineBuffer + lineIndex;
+
+      // Index of the last glyph of the line.
+      GlyphIndex lastGlyphIndexOfLine = line->glyphIndex + line->numberOfGlyphs - 1u;
+
+      // Add the alignment offset to the glyph's position.
+      for( Length index = 0u; index < numberOfLaidOutGlyphs; ++index )
+      {
+        ( *( glyphPositions + index ) ).x += line->alignmentOffset;
+
+        if( lastGlyphIndexOfLine == index )
+        {
+          // Get the next line.
+          ++lineIndex;
+
+          if( lineIndex < numberOfLines )
+          {
+            line = lineBuffer + lineIndex;
+            lastGlyphIndexOfLine = line->glyphIndex + line->numberOfGlyphs - 1u;
+          }
+        }
+      }
+
       if( 1u == numberOfLaidOutGlyphs )
       {
         // not a point try to do ellipsis with only one laid out character.
       if( 1u == numberOfLaidOutGlyphs )
       {
         // not a point try to do ellipsis with only one laid out character.
index 5f36226..beeb08b 100644 (file)
@@ -36,9 +36,9 @@ VisualModelPtr VisualModel::New()
   return VisualModelPtr( new VisualModel() );
 }
 
   return VisualModelPtr( new VisualModel() );
 }
 
-void VisualModel::SetGlyphs( const GlyphInfo* glyphs,
-                             const CharacterIndex* characterIndices,
-                             const Length* charactersPerGlyph,
+void VisualModel::SetGlyphs( const GlyphInfo* const glyphs,
+                             const CharacterIndex* const characterIndices,
+                             const Length* const charactersPerGlyph,
                              Length numberOfGlyphs )
 {
   if( 0u == numberOfGlyphs )
                              Length numberOfGlyphs )
 {
   if( 0u == numberOfGlyphs )
@@ -225,7 +225,7 @@ void VisualModel::GetGlyphsPerCharacterMap( Length* glyphsPerCharacter,
   memcpy( glyphsPerCharacter, mGlyphsPerCharacter.Begin() + characterIndex, numberOfCharacters * sizeof( Length ) );
 }
 
   memcpy( glyphsPerCharacter, mGlyphsPerCharacter.Begin() + characterIndex, numberOfCharacters * sizeof( Length ) );
 }
 
-void VisualModel::SetGlyphPositions( const Vector2* glyphPositions,
+void VisualModel::SetGlyphPositions( const Vector2* const glyphPositions,
                                      Length numberOfGlyphs )
 {
   if( 0u == numberOfGlyphs )
                                      Length numberOfGlyphs )
 {
   if( 0u == numberOfGlyphs )
index fb9f7bc..227019f 100644 (file)
@@ -73,9 +73,9 @@ public:
    * @param[in] charactersPerGlyph An array containing the number of characters per glyph.
    * @param[in] numberOfGlyphs The number of glyphs.
    */
    * @param[in] charactersPerGlyph An array containing the number of characters per glyph.
    * @param[in] numberOfGlyphs The number of glyphs.
    */
-  void SetGlyphs( const GlyphInfo* glyphs,
-                  const CharacterIndex* characterIndices,
-                  const Length* charactersPerGlyph,
+  void SetGlyphs( const GlyphInfo* const glyphs,
+                  const CharacterIndex* const characterIndices,
+                  const Length* const charactersPerGlyph,
                   Length numberOfGlyphs );
 
   /**
                   Length numberOfGlyphs );
 
   /**
@@ -228,7 +228,7 @@ public:
    * @param[in] glyphPositions An array of visual positions for each glyph.
    * @param[in] numberOfGlyphs The number of positions.
    */
    * @param[in] glyphPositions An array of visual positions for each glyph.
    * @param[in] numberOfGlyphs The number of positions.
    */
-  void SetGlyphPositions( const Vector2* glyphPositions,
+  void SetGlyphPositions( const Vector2* const glyphPositions,
                           Length numberOfGlyphs );
 
   /**
                           Length numberOfGlyphs );
 
   /**