Fix for right to left glyphs reordering. 01/37401/1
authorVictor Cebollada <v.cebollada@samsung.com>
Wed, 25 Mar 2015 07:28:45 +0000 (07:28 +0000)
committerVictor Cebollada <v.cebollada@samsung.com>
Wed, 25 Mar 2015 14:59:31 +0000 (14:59 +0000)
  - The character to glyph conversion table was not filled correctly.
    It caused reordering issues when there is a mix of some right to
    left characters generating more than one glyph and some right to
    left glyphs which are formed by more than one character.

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

index ebbf65b..9bde93f 100644 (file)
@@ -355,14 +355,16 @@ struct LayoutEngine::Impl
   void ReLayoutRightToLeftLines( const LayoutParameters& layoutParameters,
                                  Vector<Vector2>& glyphPositions )
   {
+    // Traverses the paragraphs with right to left characters.
     for( LineIndex lineIndex = 0u; lineIndex < layoutParameters.numberOfBidirectionalInfoRuns; ++lineIndex )
     {
-      const BidirectionalLineInfoRun& bidiLine = *( layoutParameters.lineBidirectionalInfoRunsBuffer +lineIndex  );
+      const BidirectionalLineInfoRun& bidiLine = *( layoutParameters.lineBidirectionalInfoRunsBuffer + lineIndex );
 
       float penX = 0.f;
 
       Vector2* glyphPositionsBuffer = glyphPositions.Begin();
 
+      // Traverses the characters of the right to left paragraph.
       for( CharacterIndex characterLogicalIndex = 0u;
            characterLogicalIndex < bidiLine.characterRun.numberOfCharacters;
            ++characterLogicalIndex )
@@ -376,7 +378,9 @@ struct LayoutEngine::Impl
         for( GlyphIndex index = 0u; index < numberOfGlyphs; ++index )
         {
           // Convert the character in the visual order into the glyph in the visual order.
-          GlyphIndex glyphIndex = 1u + *( layoutParameters.charactersToGlyphsBuffer + characterVisualIndex + index ) - numberOfGlyphs;
+          const GlyphIndex glyphIndex = *( layoutParameters.charactersToGlyphsBuffer + characterVisualIndex ) + index;
+
+          DALI_ASSERT_DEBUG( 0u <= glyphIndex && glyphIndex < layoutParameters.totalNumberOfGlyphs );
 
           const GlyphInfo& glyph = *( layoutParameters.glyphsBuffer + glyphIndex );
           Vector2& position = *( glyphPositionsBuffer + glyphIndex );
index 1a39d16..7643e4d 100644 (file)
@@ -1366,6 +1366,10 @@ void Controller::UpdateModel( OperationsMask operationsRequired )
                glyphs,
                glyphsToCharactersMap,
                charactersPerGlyph );
+
+    // Create the 'number of glyphs' per character and the glyph to character conversion tables.
+    mImpl->mVisualModel->CreateGlyphsPerCharacterTable( numberOfCharacters );
+    mImpl->mVisualModel->CreateCharacterToGlyphTable( numberOfCharacters );
   }
 
   const Length numberOfGlyphs = glyphs.Count();
@@ -1374,13 +1378,6 @@ void Controller::UpdateModel( OperationsMask operationsRequired )
   {
     mImpl->mFontClient.GetGlyphMetrics( glyphs.Begin(), numberOfGlyphs );
   }
-
-  if( 0u != numberOfGlyphs )
-  {
-    // Create the glyph to character conversion table and the 'number of glyphs' per character.
-    mImpl->mVisualModel->CreateCharacterToGlyphTable(numberOfCharacters );
-    mImpl->mVisualModel->CreateGlyphsPerCharacterTable( numberOfCharacters );
-  }
 }
 
 bool Controller::DoRelayout( const Size& size,
index 5822469..74291b4 100644 (file)
@@ -68,11 +68,11 @@ void VisualModel::SetGlyphs( const GlyphInfo* glyphs,
       mCharactersPerGlyph.Resize( numberOfGlyphs );
       memcpy( mCharactersPerGlyph.Begin(), charactersPerGlyph, numberOfGlyphs * sizeof( Length ) );
 
-      // Build the characters to glyph conversion table.
-      CreateCharacterToGlyphTable();
-
       // Build the glyphs per character table.
       CreateGlyphsPerCharacterTable();
+
+      // Build the characters to glyph conversion table.
+      CreateCharacterToGlyphTable();
     }
   }
 }
@@ -87,22 +87,31 @@ void VisualModel::CreateCharacterToGlyphTable( Length numberOfCharacters )
   }
   mCharactersToGlyph.Reserve( numberOfCharacters );
 
+  DALI_ASSERT_DEBUG( mGlyphsPerCharacter.Count() != 0u ||
+                     ( 0u == numberOfCharacters ) );
+
+  const Length* const glyphsPerCharacterBuffer = mGlyphsPerCharacter.Begin();
+
   // 2) Traverse the glyphs and set the glyph indices per character.
 
   // Index to the glyph.
   GlyphIndex glyphIndex = 0u;
+  CharacterIndex characterIndex = 0u;
   for( Vector<Length>::ConstIterator it = mCharactersPerGlyph.Begin(),
          endIt = mCharactersPerGlyph.End();
        it != endIt;
-       ++it, ++glyphIndex )
+       ++it )
   {
     const Length numberOfCharactersPerGlyph = *it;
 
+    Length numberOfGlyphs = 0u;
     // Set the glyph indices.
-    for( Length index = 0u; index < numberOfCharactersPerGlyph; ++index )
+    for( Length index = 0u; index < numberOfCharactersPerGlyph; ++index, ++characterIndex )
     {
       mCharactersToGlyph.PushBack( glyphIndex );
+      numberOfGlyphs += *( glyphsPerCharacterBuffer + characterIndex );
     }
+    glyphIndex += numberOfGlyphs;
   }
 }
 
@@ -114,7 +123,7 @@ void VisualModel::CreateGlyphsPerCharacterTable( Length numberOfCharacters )
     // If no number of characters is given, just set something sensible to avoid reallocations.
     numberOfCharacters = static_cast<Length> ( static_cast<float>( mGlyphs.Count() ) * 1.3f );
   }
-  mCharactersToGlyph.Reserve( numberOfCharacters );
+  mGlyphsPerCharacter.Reserve( numberOfCharacters );
 
   // 2) Traverse the glyphs and set the number of glyphs per character.
 
index 415b4a0..e5af4c3 100644 (file)
@@ -80,6 +80,8 @@ public:
   /**
    * @brief Creates the character to glyph conversion table.
    *
+   * @pre The glyphs per character table needs to be created first.
+   *
    * @param[in] numberOfCharacters The number of characters.
    */
   void CreateCharacterToGlyphTable( Length numberOfCharacters = 0u );