Merge "Fixed Control and Magnifier API" into tizen
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / shaper.cpp
index e70750c..c236d28 100644 (file)
 #include <dali-toolkit/internal/text/shaper.h>
 
 // EXTERNAL INCLUDES
-#include <dali/public-api/text-abstraction/shaping.h>
+#include <dali/devel-api/text-abstraction/script.h>
+#include <dali/devel-api/text-abstraction/shaping.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/font-run.h>
-#include <dali-toolkit/internal/text/logical-model.h>
-#include <dali-toolkit/internal/text/script.h>
+#include <dali-toolkit/internal/text/logical-model-impl.h>
 #include <dali-toolkit/internal/text/script-run.h>
-#include <dali-toolkit/internal/text/visual-model.h>
+#include <dali-toolkit/internal/text/visual-model-impl.h>
 
 namespace Dali
 {
@@ -48,7 +48,7 @@ void ShapeText( const Vector<Character>& text,
                 const Vector<ScriptRun>& scripts,
                 const Vector<FontRun>& fonts,
                 Vector<GlyphInfo>& glyphs,
-                Vector<CharacterIndex>& characterIndices,
+                Vector<CharacterIndex>& glyphToCharacterMap,
                 Vector<Length>& charactersPerGlyph )
 {
   const Length numberOfCharacters = text.Count();
@@ -95,7 +95,7 @@ void ShapeText( const Vector<Character>& text,
 
   Length numberOfGlyphsReserved = static_cast<Length>( numberOfCharacters * 1.3f );
   glyphs.Resize( numberOfGlyphsReserved );
-  charactersPerGlyph.Resize( numberOfGlyphsReserved );
+  glyphToCharacterMap.Resize( numberOfGlyphsReserved );
 
   // The actual number of glyphs.
   Length totalNumberOfGlyphs = 0u;
@@ -103,7 +103,7 @@ void ShapeText( const Vector<Character>& text,
   const Character* textBuffer = text.Begin();
   const LineBreakInfo* lineBreakInfoBuffer = lineBreakInfo.Begin();
   GlyphInfo* glyphsBuffer = glyphs.Begin();
-  Length* charactersPerGlyphBuffer = charactersPerGlyph.Begin();
+  CharacterIndex* glyphToCharacterMapBuffer = glyphToCharacterMap.Begin();
 
   // Traverse the characters and shape the text.
   for( previousIndex = 0; previousIndex < numberOfCharacters; )
@@ -131,11 +131,17 @@ void ShapeText( const Vector<Character>& text,
       }
     }
 
-    // Check if the current index is a white space. Do not want to shape a \n.
+    // Check if the current index is a new paragraph character.
+    // A \n is going to be shaped in order to not to mess the conversion tables.
+    // After the \n character is shaped, the glyph is going to be reset to its
+    // default in order to not to get any metric or font index for it.
+    const bool isNewParagraph = TextAbstraction::IsNewParagraph( *( textBuffer + currentIndex ) );
+
     // The last character is always a must-break even if it's not a \n.
     Length numberOfCharactersToShape = currentIndex - previousIndex;
-    if( mustBreak && !IsWhiteSpace( *( textBuffer + currentIndex ) ) )
+    if( mustBreak )
     {
+      // Add one more character to shape.
       ++numberOfCharactersToShape;
     }
 
@@ -153,16 +159,38 @@ void ShapeText( const Vector<Character>& text,
       // Resize the vectors to get enough space.
       numberOfGlyphsReserved = static_cast<Length>( totalNumberOfGlyphs * 1.3f );
       glyphs.Resize( numberOfGlyphsReserved );
-      charactersPerGlyph.Resize( numberOfGlyphsReserved );
+      glyphToCharacterMap.Resize( numberOfGlyphsReserved );
 
       // Iterators are not valid anymore, set them again.
       glyphsBuffer = glyphs.Begin();
-      charactersPerGlyphBuffer = charactersPerGlyph.Begin();
+      glyphToCharacterMapBuffer = glyphToCharacterMap.Begin();
     }
 
     // Retrieve the glyphs and the glyph to character conversion map.
     shaping.GetGlyphs( glyphsBuffer + glyphIndex,
-                       charactersPerGlyphBuffer + glyphIndex );
+                       glyphToCharacterMapBuffer + glyphIndex );
+
+    if( isNewParagraph )
+    {
+      // TODO : This is a work around to avoid drawing a square in the
+      //        place of a new line character.
+
+      // If the last character is a \n, it resets the glyph to the default
+      // to avoid getting any metric for it.
+      GlyphInfo& glyph = *( glyphsBuffer + glyphIndex + ( numberOfGlyphs - 1u ) );
+
+      glyph = GlyphInfo();
+    }
+
+    // Update indices.
+    if( 0u != glyphIndex )
+    {
+      for( Length index = glyphIndex; index < glyphIndex + numberOfGlyphs; ++index )
+      {
+        CharacterIndex& characterIndex = *( glyphToCharacterMapBuffer + index );
+        characterIndex += previousIndex;
+      }
+    }
 
     // Update the iterators to get the next font or script run.
     if( currentIndex == fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters )
@@ -178,19 +206,23 @@ void ShapeText( const Vector<Character>& text,
     previousIndex = mustBreak ? currentIndex + 1u : currentIndex;
   }
 
-  characterIndices.Reserve( totalNumberOfGlyphs );
-  CharacterIndex characterIndex = 0u;
-  characterIndices.PushBack( characterIndex );
-  for( Length index = 0u, length = totalNumberOfGlyphs - 1u; index < length; ++index )
+  // Add the number of characters per glyph.
+  charactersPerGlyph.Reserve( totalNumberOfGlyphs );
+  previousIndex = 0u;
+  for( Length index = 1u; index < totalNumberOfGlyphs; ++index )
   {
-    characterIndex += *( charactersPerGlyphBuffer + index );
-    characterIndices.PushBack( characterIndex );
+    const CharacterIndex characterIndex = *( glyphToCharacterMapBuffer + index );
+
+    charactersPerGlyph.PushBack( characterIndex - previousIndex );
+
+    previousIndex = characterIndex;
   }
 
+  charactersPerGlyph.PushBack( numberOfCharacters - previousIndex );
+
   // Resize the vectors to set the right number of items.
   glyphs.Resize( totalNumberOfGlyphs );
-  // characterIndices.Resize( totalNumberOfGlyphs );
-  charactersPerGlyph.Resize( totalNumberOfGlyphs );
+  glyphToCharacterMap.Resize( totalNumberOfGlyphs );
 }
 
 void ShapeText( const LogicalModel& logicalModel,