[dali_1.1.9] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / layouts / layout-engine.cpp
index e75009d..ad513a8 100644 (file)
@@ -20,9 +20,8 @@
 
 // EXTERNAL INCLUDES
 #include <limits>
-#include <dali/public-api/math/vector2.h>
-#include <dali/devel-api/text-abstraction/font-client.h>
 #include <dali/integration-api/debug.h>
+#include <dali/devel-api/text-abstraction/font-client.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/layouts/layout-parameters.h>
@@ -46,6 +45,7 @@ namespace
 
 const float MAX_FLOAT = std::numeric_limits<float>::max();
 const bool RTL = true;
+const float CURSOR_WIDTH = 1.f;
 
 } //namespace
 
@@ -102,9 +102,9 @@ struct LayoutEngine::Impl
   : mLayout( LayoutEngine::SINGLE_LINE_BOX ),
     mHorizontalAlignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN ),
     mVerticalAlignment( LayoutEngine::VERTICAL_ALIGN_TOP ),
+    mCursorWidth( CURSOR_WIDTH ),
     mEllipsisEnabled( false )
   {
-    mFontClient = TextAbstraction::FontClient::Get();
   }
 
   /**
@@ -116,7 +116,7 @@ struct LayoutEngine::Impl
   void UpdateLineHeight( FontId fontId, LineLayout& lineLayout )
   {
     Text::FontMetrics fontMetrics;
-    mFontClient.GetFontMetrics( fontId, fontMetrics );
+    mMetrics->GetFontMetrics( fontId, fontMetrics );
 
     // Sets the maximum ascender.
     if( fontMetrics.ascender > lineLayout.ascender )
@@ -211,7 +211,7 @@ struct LayoutEngine::Impl
 
     float tmpExtraBearing = ( 0.f > glyphInfo.xBearing ) ? -glyphInfo.xBearing : 0.f;
 
-    tmpLineLayout.length += 1.f; // Added one unit to give some space to the cursor.
+    tmpLineLayout.length += mCursorWidth; // Added to give some space to the cursor.
 
     // Calculate the line height if there is no characters.
     FontId lastFontId = glyphInfo.fontId;
@@ -229,6 +229,14 @@ struct LayoutEngine::Impl
       // Get the glyph info.
       const GlyphInfo& glyphInfo = *( parameters.glyphsBuffer + glyphIndex );
 
+      // Check if the font of the current glyph is the same of the previous one.
+      // If it's different the ascender and descender need to be updated.
+      if( lastFontId != glyphInfo.fontId )
+      {
+        UpdateLineHeight( glyphInfo.fontId, tmpLineLayout );
+        lastFontId = glyphInfo.fontId;
+      }
+
       // Get the character indices for the current glyph. The last character index is needed
       // because there are glyphs formed by more than one character but their break info is
       // given only for the last character.
@@ -421,14 +429,6 @@ struct LayoutEngine::Impl
         tmpLineLayout.Clear();
       }
 
-      // Check if the font of the current glyph is the same of the previous one.
-      // If it's different the ascender and descender need to be updated.
-      if( lastFontId != glyphInfo.fontId )
-      {
-        UpdateLineHeight( glyphInfo.fontId, tmpLineLayout );
-        lastFontId = glyphInfo.fontId;
-      }
-
       previousCharacterDirection = characterDirection;
     }
 
@@ -451,7 +451,6 @@ struct LayoutEngine::Impl
 
     const GlyphInfo& glyph = *glyphsBuffer;
     float penX = ( 0.f > glyph.xBearing ) ? -glyph.xBearing : 0.f;
-    penX += 1.f; // Added one unit to give some space to the cursor.
 
     for( GlyphIndex i = 0u; i < numberOfGlyphs; ++i )
     {
@@ -528,11 +527,11 @@ struct LayoutEngine::Impl
 
           penY -= layout.ascender - lineRun.descender;
 
-          ellipsisLayout.glyphIndex = lineRun.glyphIndex;
+          ellipsisLayout.glyphIndex = lineRun.glyphRun.glyphIndex;
         }
         else
         {
-          lineRun.glyphIndex = 0u;
+          lineRun.glyphRun.glyphIndex = 0u;
           ellipsisLayout.glyphIndex = 0u;
         }
 
@@ -541,22 +540,23 @@ struct LayoutEngine::Impl
                              currentParagraphDirection,
                              true );
 
-        lineRun.numberOfGlyphs = ellipsisLayout.numberOfGlyphs;
+        lineRun.glyphRun.numberOfGlyphs = ellipsisLayout.numberOfGlyphs;
         lineRun.characterRun.characterIndex = ellipsisLayout.characterIndex;
         lineRun.characterRun.numberOfCharacters = ellipsisLayout.numberOfCharacters;
         lineRun.width = ellipsisLayout.length;
         lineRun.extraLength =  ( ellipsisLayout.wsLengthEndOfLine > 0.f ) ? ellipsisLayout.wsLengthEndOfLine - ellipsisLayout.extraWidth : 0.f;
         lineRun.ascender = ellipsisLayout.ascender;
         lineRun.descender = ellipsisLayout.descender;
+        lineRun.direction = !RTL;
         lineRun.ellipsis = true;
 
         actualSize.width = layoutParameters.boundingBox.width;
         actualSize.height += ( lineRun.ascender + -lineRun.descender );
 
-        SetGlyphPositions( layoutParameters.glyphsBuffer + lineRun.glyphIndex,
+        SetGlyphPositions( layoutParameters.glyphsBuffer + lineRun.glyphRun.glyphIndex,
                            ellipsisLayout.numberOfGlyphs,
                            penY,
-                           glyphPositions.Begin() + lineRun.glyphIndex );
+                           glyphPositions.Begin() + lineRun.glyphRun.glyphIndex );
 
         if( 0u != numberOfLines )
         {
@@ -576,11 +576,11 @@ struct LayoutEngine::Impl
         const bool isLastLine = index + layout.numberOfGlyphs == layoutParameters.totalNumberOfGlyphs;
 
         LineRun lineRun;
-        lineRun.glyphIndex = index;
-        lineRun.numberOfGlyphs = layout.numberOfGlyphs;
+        lineRun.glyphRun.glyphIndex = index;
+        lineRun.glyphRun.numberOfGlyphs = layout.numberOfGlyphs;
         lineRun.characterRun.characterIndex = layout.characterIndex;
         lineRun.characterRun.numberOfCharacters = layout.numberOfCharacters;
-        if( isLastLine )
+        if( isLastLine && !layoutParameters.isLastNewParagraph )
         {
           const float width = layout.extraBearing + layout.length + layout.extraWidth + layout.wsLengthEndOfLine;
           if( MULTI_LINE_BOX == mLayout )
@@ -601,7 +601,7 @@ struct LayoutEngine::Impl
         }
         lineRun.ascender = layout.ascender;
         lineRun.descender = layout.descender;
-        lineRun.direction = false;
+        lineRun.direction = !RTL;
         lineRun.ellipsis = false;
 
         lines.PushBack( lineRun );
@@ -623,8 +623,36 @@ struct LayoutEngine::Impl
 
         // Increase the glyph index.
         index += layout.numberOfGlyphs;
+
+        if( isLastLine &&
+            layoutParameters.isLastNewParagraph &&
+            ( mLayout == MULTI_LINE_BOX ) )
+        {
+          // Need to add a new line with no characters but with height to increase the actualSize.height
+          const GlyphInfo& glyphInfo = *( layoutParameters.glyphsBuffer + layoutParameters.totalNumberOfGlyphs - 1u );
+
+          Text::FontMetrics fontMetrics;
+          mMetrics->GetFontMetrics( glyphInfo.fontId, fontMetrics );
+
+          LineRun lineRun;
+          lineRun.glyphRun.glyphIndex = 0u;
+          lineRun.glyphRun.numberOfGlyphs = 0u;
+          lineRun.characterRun.characterIndex = 0u;
+          lineRun.characterRun.numberOfCharacters = 0u;
+          lineRun.width = 0.f;
+          lineRun.ascender = fontMetrics.ascender;
+          lineRun.descender = fontMetrics.descender;
+          lineRun.extraLength = 0.f;
+          lineRun.alignmentOffset = 0.f;
+          lineRun.direction = !RTL;
+          lineRun.ellipsis = false;
+
+          actualSize.height += ( lineRun.ascender + -lineRun.descender );
+
+          lines.PushBack( lineRun );
+        }
       }
-    }
+    } // end for() traversing glyphs.
 
     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--LayoutText\n\n" );
 
@@ -643,7 +671,6 @@ struct LayoutEngine::Impl
       const GlyphInfo& glyph = *( layoutParameters.glyphsBuffer + *( layoutParameters.charactersToGlyphsBuffer + characterVisualIndex ) );
 
       float penX = ( 0.f > glyph.xBearing ) ? -glyph.xBearing : 0.f;
-      penX += 1.f; // Added one unit to give some space to the cursor.
 
       Vector2* glyphPositionsBuffer = glyphPositions.Begin();
 
@@ -739,10 +766,12 @@ struct LayoutEngine::Impl
       {
         if( isLastLine && !isRTL )
         {
+          // Add the length of the white saces at the end of the line.
           lineLength += line.extraLength;
           if( lineLength > boxWidth )
           {
-            lineLength = boxWidth;
+            // The line's length is longer than the box's width.
+            // Set the line's offset to 0 and nothing else to do.
             line.alignmentOffset = 0.f;
             break;
           }
@@ -789,8 +818,9 @@ struct LayoutEngine::Impl
   LayoutEngine::Layout mLayout;
   LayoutEngine::HorizontalAlignment mHorizontalAlignment;
   LayoutEngine::VerticalAlignment mVerticalAlignment;
+  float mCursorWidth;
 
-  TextAbstraction::FontClient mFontClient;
+  IntrusivePtr<Metrics> mMetrics;
 
   bool mEllipsisEnabled:1;
 };
@@ -806,6 +836,11 @@ LayoutEngine::~LayoutEngine()
   delete mImpl;
 }
 
+void LayoutEngine::SetMetrics( MetricsPtr& metrics )
+{
+  mImpl->mMetrics = metrics;
+}
+
 void LayoutEngine::SetLayout( Layout layout )
 {
   mImpl->mLayout = layout;
@@ -846,6 +881,16 @@ LayoutEngine::VerticalAlignment LayoutEngine::GetVerticalAlignment() const
   return mImpl->mVerticalAlignment;
 }
 
+void LayoutEngine::SetCursorWidth( int width )
+{
+  mImpl->mCursorWidth = static_cast<float>( width );
+}
+
+int LayoutEngine::GetCursorWidth() const
+{
+  return static_cast<int>( mImpl->mCursorWidth );
+}
+
 bool LayoutEngine::LayoutText( const LayoutParameters& layoutParameters,
                                Vector<Vector2>& glyphPositions,
                                Vector<LineRun>& lines,