Lines added to the model. 32/36532/6
authorVictor Cebollada <v.cebollada@samsung.com>
Thu, 26 Feb 2015 10:40:01 +0000 (10:40 +0000)
committerVictor Cebollada <v.cebollada@samsung.com>
Tue, 10 Mar 2015 08:15:18 +0000 (08:15 +0000)
Change-Id: Ie80d79ad0ab7b050d4871a9f95d633f0fbdbc970
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-controller.h
dali-toolkit/internal/text/visual-model.cpp
dali-toolkit/internal/text/visual-model.h

index b5c3b16..9544a66 100644 (file)
@@ -86,14 +86,6 @@ struct LayoutEngine::Impl
       // because there are glyphs formed by more than one character but their break info is
       // given only for the last character.
       const Length charactersPerGlyph = *( parameters.charactersPerGlyphBuffer + glyphIndex );
-      const CharacterIndex characterFirstIndex = *( parameters.glyphsToCharactersBuffer + glyphIndex );
-      const CharacterIndex characterLastIndex = characterFirstIndex + ( ( 1u > charactersPerGlyph ) ? 0u : charactersPerGlyph - 1u );
-
-      // Get the line break info for the current character.
-      const LineBreakInfo lineBreakInfo = *( parameters.lineBreakInfoBuffer + characterLastIndex );
-
-      // Get the word break info for the current character.
-      const WordBreakInfo wordBreakInfo = *( parameters.wordBreakInfoBuffer + characterLastIndex );
 
       // Increase the number of characters.
       lineLayout.numberOfCharacters += charactersPerGlyph;
@@ -104,13 +96,6 @@ struct LayoutEngine::Impl
       // Increase the accumulated length.
       lineLayout.length += ( glyphIndex == lastGlyphIndex ) ? glyphInfo.width : glyphInfo.advance;
 
-      if( TextAbstraction::LINE_MUST_BREAK == lineBreakInfo )
-      {
-      }
-      if( TextAbstraction::WORD_BREAK == wordBreakInfo )
-      {
-      }
-
       if( lastFontId != glyphInfo.fontId )
       {
         Text::FontMetrics fontMetrics;
@@ -277,6 +262,7 @@ struct LayoutEngine::Impl
 
   bool LayoutText( const LayoutParameters& layoutParameters,
                    Vector<Vector2>& glyphPositions,
+                   Vector<LineRun>& lines,
                    Size& actualSize )
   {
     // TODO Switch between different layouts
@@ -288,6 +274,7 @@ struct LayoutEngine::Impl
       {
         update = SingleLineLayout( layoutParameters,
                                    glyphPositions,
+                                   lines,
                                    actualSize );
         break;
       }
@@ -295,6 +282,7 @@ struct LayoutEngine::Impl
       {
         update = MultiLineLayout( layoutParameters,
                                   glyphPositions,
+                                  lines,
                                   actualSize );
         break;
       }
@@ -308,6 +296,7 @@ struct LayoutEngine::Impl
   // TODO - Rewrite this to handle bidi
   bool SingleLineLayout( const LayoutParameters& layoutParameters,
                          Vector<Vector2>& glyphPositions,
+                         Vector<LineRun>& lines,
                          Size& actualSize )
   {
     LineLayout layout;
@@ -315,11 +304,18 @@ struct LayoutEngine::Impl
     GetLineLayoutForBox( layoutParameters,
                          layout );
 
-    if( 0u == layout.numberOfGlyphs )
-    {
-      // The width is too small and no characters are laid-out.
-      return false;
-    }
+    // Create a line run and add it to the lines.
+    const GlyphIndex lastGlyphIndex = layoutParameters.totalNumberOfGlyphs - 1u;
+
+    LineRun lineRun;
+    lineRun.glyphIndex = 0u;
+    lineRun.numberOfGlyphs = layoutParameters.totalNumberOfGlyphs;
+    lineRun.characterRun.characterIndex = 0u;
+    lineRun.characterRun.numberOfCharacters = *( layoutParameters.glyphsToCharactersBuffer + lastGlyphIndex ) + *( layoutParameters.charactersPerGlyphBuffer + lastGlyphIndex );
+    lineRun.lineSize.width = layout.length;
+    lineRun.lineSize.height = layout.height;
+
+    lines.PushBack( lineRun );
 
     // Update the actual size.
     actualSize.width = layout.length;
@@ -346,6 +342,7 @@ struct LayoutEngine::Impl
   // TODO - Rewrite this to handle bidi
   bool MultiLineLayout( const LayoutParameters& layoutParameters,
                         Vector<Vector2>& glyphPositions,
+                        Vector<LineRun>& lines,
                         Size& actualSize )
   {
     float penY = 0.f;
@@ -365,6 +362,19 @@ struct LayoutEngine::Impl
         return false;
       }
 
+      // Create a line run and add it to the lines.
+      const GlyphIndex lastGlyphIndex = index + layout.numberOfGlyphs - 1u;
+
+      LineRun lineRun;
+      lineRun.glyphIndex = index;
+      lineRun.numberOfGlyphs = layout.numberOfGlyphs;
+      lineRun.characterRun.characterIndex = *( layoutParameters.glyphsToCharactersBuffer + index );
+      lineRun.characterRun.numberOfCharacters = ( *( layoutParameters.glyphsToCharactersBuffer + lastGlyphIndex ) + *( layoutParameters.charactersPerGlyphBuffer + lastGlyphIndex ) ) - lineRun.characterRun.characterIndex;
+      lineRun.lineSize.width = layout.length;
+      lineRun.lineSize.height = layout.height;
+
+      lines.PushBack( lineRun );
+
       // Update the actual size.
       if( layout.length > actualSize.width )
       {
@@ -424,10 +434,12 @@ unsigned int LayoutEngine::GetLayout() const
 
 bool LayoutEngine::LayoutText( const LayoutParameters& layoutParameters,
                                Vector<Vector2>& glyphPositions,
+                               Vector<LineRun>& lines,
                                Size& actualSize )
 {
   return mImpl->LayoutText( layoutParameters,
                             glyphPositions,
+                            lines,
                             actualSize );
 }
 
index febf485..59977c2 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 // INTERNAL INCLUDE
-#include <dali-toolkit/internal/text/text-definitions.h>
+#include <dali-toolkit/internal/text/line-run.h>
 
 // EXTERNAL INCLUDE
 #include <dali/public-api/common/dali-vector.h>
@@ -80,12 +80,14 @@ public:
    *
    * @param[in] layoutParameters The parameters needed to layout the text.
    * @param[out] glyphPositions The positions of all the glyphs.
+   * @param[out] lines The laid-out lines.
    * @param[out] actualSize The size of the text after it has been laid-out.
    *
    * @return \e true if the text has been re-laid-out. \e false means the given width is too small to layout even a single character.
    */
   bool LayoutText( const LayoutParameters& layoutParameters,
                    Vector<Vector2>& glyphPositions,
+                   Vector<LineRun>& lines,
                    Size& actualSize );
 
 private:
index ad25d59..aedd3f7 100644 (file)
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/public-api/math/vector2.h>
+
 // INTERNAL INCLUDES
-#include <dali-toolkit/internal/text/text-definitions.h>
+#include <dali-toolkit/internal/text/character-run.h>
 
 namespace Dali
 {
@@ -35,9 +38,10 @@ namespace Text
  */
 struct LineRun
 {
-  GlyphIndex glyphIndex;     ///< The initial glyph index.
-  Length     numberOfGlyphs; ///< The number of characters of the run.
-  // VCC More info to be added. i.e the size, ...
+  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.
+  Size         lineSize;       ///< The size of the line.
 };
 
 } // namespace Text
index 3433301..b0fb0d1 100644 (file)
@@ -555,6 +555,7 @@ bool Controller::Relayout( const Vector2& size )
                                                              LAYOUT                    |
                                                              UPDATE_ACTUAL_SIZE        |
                                                              UPDATE_POSITIONS          |
+                                                             UPDATE_LINES              |
                                                              REORDER );
 
     mImpl->mControlSize = size;
@@ -710,9 +711,10 @@ bool Controller::DoRelayout( const Vector2& size,
 
   if( LAYOUT & operations )
   {
+    const Length numberOfCharacters = mImpl->mLogicalModel->GetNumberOfCharacters();
+
     if( 0u == numberOfGlyphs )
     {
-      const Length numberOfCharacters = mImpl->mLogicalModel->GetNumberOfCharacters();
       numberOfGlyphs = mImpl->mVisualModel->GetNumberOfGlyphs();
 
       lineBreakInfo.Resize( numberOfCharacters );
@@ -755,22 +757,40 @@ bool Controller::DoRelayout( const Vector2& size,
     Vector<Vector2> glyphPositions;
     glyphPositions.Resize( numberOfGlyphs );
 
-    // Update the visual model
+    // The laid-out lines.
+    // It's not possible to know in how many lines the text is going to be laid-out,
+    // but it can be resized at least with the number of 'paragraphs' to avoid
+    // some re-allocations.
+    Vector<LineRun> lines;
+    lines.Reserve( mImpl->mLogicalModel->GetNumberOfBidirectionalInfoRuns( 0u, numberOfCharacters ) );
+
+    // Update the visual model.
     viewUpdated = mImpl->mLayoutEngine.LayoutText( layoutParameters,
                                                    glyphPositions,
+                                                   lines,
                                                    layoutSize );
 
-    // Sets the positions into the model.
-    if( UPDATE_POSITIONS & operations )
+    if( viewUpdated )
     {
-      mImpl->mVisualModel->SetGlyphPositions( glyphPositions.Begin(),
-                                              numberOfGlyphs );
-    }
+      // Sets the positions into the model.
+      if( UPDATE_POSITIONS & operations )
+      {
+        mImpl->mVisualModel->SetGlyphPositions( glyphPositions.Begin(),
+                                                numberOfGlyphs );
+      }
 
-    // Sets the actual size.
-    if( UPDATE_ACTUAL_SIZE & operations )
-    {
-      mImpl->mVisualModel->SetActualSize( layoutSize );
+      // Sets the lines into the model.
+      if( UPDATE_LINES & operations )
+      {
+        mImpl->mVisualModel->SetLines( lines.Begin(),
+                                       lines.Count() );
+      }
+
+      // Sets the actual size.
+      if( UPDATE_ACTUAL_SIZE & operations )
+      {
+        mImpl->mVisualModel->SetActualSize( layoutSize );
+      }
     }
   }
   else
index 5623a11..b061330 100644 (file)
@@ -75,9 +75,10 @@ private:
     LAYOUT             = 0x0080,
     UPDATE_ACTUAL_SIZE = 0x0100,
     UPDATE_POSITIONS   = 0x0200,
-    REORDER            = 0x0400,
-    ALIGNMENT          = 0x0800,
-    RENDER             = 0x1000,
+    UPDATE_LINES       = 0x0400,
+    REORDER            = 0x0800,
+    ALIGNMENT          = 0x1000,
+    RENDER             = 0x2000,
     ALL_OPERATIONS     = 0xFFFF
   };
 
index ab183e4..73400f0 100644 (file)
@@ -35,6 +35,18 @@ namespace Toolkit
 namespace Text
 {
 
+/**
+ * @brief caches some temporary values of the GetNumberOfLines( glyphIndex, numberOfGlyphs ) operation
+ * as they are going to be used in the GetLinesOfGlyphRange() call.
+ */
+struct GetLineCache
+{
+  GlyphIndex glyphIndex;     ///< The glyph index.
+  Length     numberOfGlyphs; ///< The number of glyphs.
+  Length     firstLine;      ///< Index to the first line.
+  Length     numberOfLines;  ///< The number of lines.
+};
+
 struct VisualModel::Impl
 {
   Vector<GlyphInfo>      mGlyphs;             ///< For each glyph, the font's id, glyph's index within the font and glyph's metrics.
@@ -42,9 +54,12 @@ struct VisualModel::Impl
   Vector<GlyphIndex>     mCharactersToGlyph;  ///< For each character, the index of the first glyph.
   Vector<Length>         mCharactersPerGlyph; ///< For each glyph, the number of characters that form the glyph.
   Vector<Vector2>        mGlyphPositions;     ///< For each glyph, the position.
+  Vector<LineRun>        mLines;              ///< The laid out lines.
+
+  Size                   mNaturalSize;        ///< Size of the text with no line wrapping.
+  Size                   mActualSize;         ///< Size of the laid-out text considering the layout properties set.
 
-  Size                   mNaturalSize;
-  Size                   mActualSize;
+  GetLineCache           mGetLineCache;       ///< Caches the GetNumberOfLines( glyphIndex, numberOfGlyphs ) operation.
 };
 
 VisualModelPtr VisualModel::New()
@@ -101,7 +116,7 @@ void VisualModel::GetGlyphs( GlyphInfo* glyphs,
                              GlyphIndex glyphIndex,
                              Length numberOfGlyphs ) const
 {
-  Vector<GlyphInfo>& modelGlyphs = mImpl->mGlyphs;
+  const Vector<GlyphInfo>& modelGlyphs = mImpl->mGlyphs;
   memcpy( glyphs, modelGlyphs.Begin() + glyphIndex, numberOfGlyphs * sizeof( GlyphInfo ) );
 }
 
@@ -129,7 +144,7 @@ void VisualModel::GetCharacterToGlyphMap( GlyphIndex* characterToGlyphMap,
                                           CharacterIndex characterIndex,
                                           Length numberOfCharacters ) const
 {
-  Vector<GlyphIndex>& modelCharactersToGlyph = mImpl->mCharactersToGlyph;
+  const Vector<GlyphIndex>& modelCharactersToGlyph = mImpl->mCharactersToGlyph;
   memcpy( characterToGlyphMap, modelCharactersToGlyph.Begin() + characterIndex, numberOfCharacters * sizeof( GlyphIndex ) );
 }
 
@@ -137,7 +152,7 @@ void VisualModel::GetCharactersPerGlyphMap( Length* charactersPerGlyph,
                                             GlyphIndex glyphIndex,
                                             Length numberOfGlyphs ) const
 {
-  Vector<Length>& modelCharactersPerGlyph = mImpl->mCharactersPerGlyph;
+  const Vector<Length>& modelCharactersPerGlyph = mImpl->mCharactersPerGlyph;
   memcpy( charactersPerGlyph, modelCharactersPerGlyph.Begin() + glyphIndex, numberOfGlyphs * sizeof( Length ) );
 }
 
@@ -145,7 +160,7 @@ void VisualModel::GetGlyphToCharacterMap( CharacterIndex* glyphToCharacter,
                                           GlyphIndex glyphIndex,
                                           Length numberOfGlyphs ) const
 {
-  Vector<CharacterIndex>& modelGlyphsToCharacters = mImpl->mGlyphsToCharacters;
+  const Vector<CharacterIndex>& modelGlyphsToCharacters = mImpl->mGlyphsToCharacters;
   memcpy( glyphToCharacter, modelGlyphsToCharacters.Begin() + glyphIndex, numberOfGlyphs * sizeof( CharacterIndex ) );
 }
 
@@ -161,7 +176,7 @@ void VisualModel::GetGlyphPositions( Vector2* glyphPositions,
                                      GlyphIndex glyphIndex,
                                      Length numberOfGlyphs ) const
 {
-  Vector<Vector2> modelPositions = mImpl->mGlyphPositions;
+  const Vector<Vector2>& modelPositions = mImpl->mGlyphPositions;
   memcpy( glyphPositions, modelPositions.Begin() + glyphIndex, numberOfGlyphs * sizeof( Vector2 ) );
 }
 
@@ -173,29 +188,107 @@ const Vector2& VisualModel::GetGlyphPosition( GlyphIndex glyphIndex ) const
 void VisualModel::SetLines( const LineRun* const lines,
                             Length numberOfLines )
 {
+  Vector<LineRun>& modelLines = mImpl->mLines;
+  GetLineCache& lineCache = mImpl->mGetLineCache;
+
+  modelLines.Resize( numberOfLines );
+  memcpy( modelLines.Begin(), lines, numberOfLines * sizeof( LineRun ) );
+
+  // Clear the get line cache.
+  lineCache.glyphIndex = 0u;
+  lineCache.numberOfGlyphs = 0u;
+  lineCache.firstLine = 0u;
+  lineCache.numberOfLines = 0u;
 }
 
 Length VisualModel::GetNumberOfLines() const
 {
-  return 0u;
+  return mImpl->mLines.Count();
 }
 
 void VisualModel::GetLines( LineRun* lines,
                             LineIndex lineIndex,
                             Length numberOfLines ) const
 {
+  const Vector<LineRun>& modelLines = mImpl->mLines;
+  memcpy( lines, modelLines.Begin() + lineIndex, numberOfLines * sizeof( LineRun ) );
 }
 
 Length VisualModel::GetNumberOfLines( GlyphIndex glyphIndex,
                                       Length numberOfGlyphs ) const
 {
-  return 0u;
+  // If is likely the user query consecutively for the number of lines with the same
+  // glyph index and number of glyphs, use the cache could be considered.
+  GetLineCache& lineCache = mImpl->mGetLineCache;
+
+  // Cache the glyph index and number of glyphs to be used in the GetLinesOfGlyphRange().
+  lineCache.glyphIndex = glyphIndex;
+  lineCache.numberOfGlyphs = numberOfGlyphs;
+
+  // Check first if the query is for the total number of glyphs.
+  const Length totalNumberOfGlyphs = mImpl->mGlyphs.Count();
+
+  if( ( 0u == glyphIndex ) &&
+      ( totalNumberOfGlyphs == numberOfGlyphs ) )
+  {
+    lineCache.firstLine = 0u;
+    lineCache.numberOfLines = mImpl->mLines.Count();
+
+    return lineCache.numberOfLines;
+  }
+
+  // Initialize the number of lines and the first line.
+  lineCache.numberOfLines = 0u;
+  lineCache.firstLine = 0u;
+  bool firstLineFound = false;
+
+  const Vector<LineRun>& modelLines = mImpl->mLines;
+  const GlyphIndex lastGlyphIndex = glyphIndex + numberOfGlyphs;
+
+  // Traverse the lines and cound those lines within the range of glyphs.
+  for( Vector<LineRun>::ConstIterator it = modelLines.Begin(),
+         endIt = modelLines.End();
+       it != endIt;
+       ++it )
+  {
+    const LineRun& line = *it;
+
+    if( ( line.glyphIndex + line.numberOfGlyphs > glyphIndex ) &&
+        ( lastGlyphIndex > line.glyphIndex ) )
+    {
+      firstLineFound = true;
+      ++lineCache.numberOfLines;
+    }
+    else if( lastGlyphIndex <= line.glyphIndex )
+    {
+      // nothing else to do.
+      break;
+    }
+
+    if( !firstLineFound )
+    {
+      ++lineCache.firstLine;
+    }
+  }
+
+  return lineCache.numberOfLines;
 }
 
 void VisualModel::GetLinesOfGlyphRange( LineRun* lines,
                                         GlyphIndex glyphIndex,
                                         Length numberOfGlyphs ) const
 {
+  const Vector<LineRun>& modelLines = mImpl->mLines;
+  GetLineCache& lineCache = mImpl->mGetLineCache;
+
+  if( ( glyphIndex != lineCache.glyphIndex ) ||
+      ( numberOfGlyphs != lineCache.numberOfGlyphs ) )
+  {
+    GetNumberOfLines( glyphIndex,
+                      numberOfGlyphs );
+  }
+
+  memcpy( lines, modelLines.Begin() + lineCache.firstLine, lineCache.numberOfLines * sizeof( LineRun ) );
 }
 
 void VisualModel::SetNaturalSize( const Vector2& size  )
index ad2a137..ec74764 100644 (file)
@@ -241,8 +241,8 @@ public:
    *
    * @return The number of lines.
    */
-  TextAbstraction::Length GetNumberOfLines( GlyphIndex glyphIndex,
-                                            Length numberOfGlyphs ) const;
+  Length GetNumberOfLines( GlyphIndex glyphIndex,
+                           Length numberOfGlyphs ) const;
   /**
    * Retrieves the lines where the given range of glyphs is laid out.
    *