Size negotiation patch 3: Scope size negotiation enums
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / layouts / layout-engine.cpp
index ebbf65b..1a97dd4 100644 (file)
@@ -19,6 +19,7 @@
 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
 
 // EXTERNAL INCLUDES
+#include <limits>
 #include <dali/public-api/math/vector2.h>
 #include <dali/public-api/text-abstraction/font-client.h>
 
@@ -35,6 +36,13 @@ namespace Toolkit
 namespace Text
 {
 
+namespace
+{
+
+const float MAX_FLOAT = std::numeric_limits<float>::max();
+
+} //namespace
+
 /**
  * @brief Stores temporary layout info of the line.
  */
@@ -48,14 +56,15 @@ struct LineLayout
   float          widthAdvanceDiff;   ///< The difference between the width and the advance of the last glyph.
   float          wsLengthEndOfLine;  ///< The length of the white spaces at the end of the line.
   float          ascender;           ///< The maximum ascender of all fonts in the line.
-  float          descender;          ///< The maximum descender of all fonts in the line.
+  float          descender;          ///< The minimum descender of all fonts in the line.
 };
 
 struct LayoutEngine::Impl
 {
   Impl()
   : mLayout( LayoutEngine::SINGLE_LINE_BOX ),
-    mAlignment( LayoutEngine::ALIGN_BEGIN )
+    mHorizontalAlignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN ),
+    mVerticalAlignment( LayoutEngine::VERTICAL_ALIGN_TOP )
   {
     mFontClient = TextAbstraction::FontClient::Get();
   }
@@ -72,7 +81,7 @@ struct LayoutEngine::Impl
     lineLayout.length = 0.f;
     lineLayout.wsLengthEndOfLine = 0.f;
     lineLayout.ascender = 0.f;
-    lineLayout.descender = 0.f;
+    lineLayout.descender = MAX_FLOAT;
 
     // Get the last glyph index.
     const GlyphIndex lastGlyphIndex = parameters.totalNumberOfGlyphs - 1u;
@@ -128,8 +137,8 @@ struct LayoutEngine::Impl
           lineLayout.ascender = fontMetrics.ascender;
         }
 
-        // Sets the maximum descender.
-        if( fontMetrics.descender > lineLayout.descender )
+        // Sets the minimum descender.
+        if( fontMetrics.descender < lineLayout.descender )
         {
           lineLayout.descender = fontMetrics.descender;
         }
@@ -152,7 +161,7 @@ struct LayoutEngine::Impl
     lineLayout.widthAdvanceDiff = 0.f;
     lineLayout.wsLengthEndOfLine = 0.f;
     lineLayout.ascender = 0.f;
-    lineLayout.descender = 0.f;
+    lineLayout.descender = MAX_FLOAT;
 
     // Stores temporary line layout which has not been added to the final line layout.
     LineLayout tmpLineLayout;
@@ -162,7 +171,7 @@ struct LayoutEngine::Impl
     tmpLineLayout.widthAdvanceDiff = 0.f;
     tmpLineLayout.wsLengthEndOfLine = 0.f;
     tmpLineLayout.ascender = 0.f;
-    tmpLineLayout.descender = 0.f;
+    tmpLineLayout.descender = MAX_FLOAT;
 
     FontId lastFontId = 0u;
     for( GlyphIndex glyphIndex = lineLayout.glyphIndex;
@@ -243,7 +252,7 @@ struct LayoutEngine::Impl
           lineLayout.ascender = tmpLineLayout.ascender;
         }
 
-        if( tmpLineLayout.descender > lineLayout.descender )
+        if( tmpLineLayout.descender < lineLayout.descender )
         {
           lineLayout.descender = tmpLineLayout.descender;
         }
@@ -254,7 +263,7 @@ struct LayoutEngine::Impl
         tmpLineLayout.widthAdvanceDiff = 0u;
         tmpLineLayout.wsLengthEndOfLine = 0u;
         tmpLineLayout.ascender = 0.f;
-        tmpLineLayout.descender = 0.f;
+        tmpLineLayout.descender = MAX_FLOAT;
         return;
       }
 
@@ -283,7 +292,7 @@ struct LayoutEngine::Impl
           lineLayout.ascender = tmpLineLayout.ascender;
         }
 
-        if( tmpLineLayout.descender > lineLayout.descender )
+        if( tmpLineLayout.descender < lineLayout.descender )
         {
           lineLayout.descender = tmpLineLayout.descender;
         }
@@ -294,7 +303,7 @@ struct LayoutEngine::Impl
         tmpLineLayout.widthAdvanceDiff = 0u;
         tmpLineLayout.wsLengthEndOfLine = 0u;
         tmpLineLayout.ascender = 0.f;
-        tmpLineLayout.descender = 0.f;
+        tmpLineLayout.descender = MAX_FLOAT;
       }
 
       if( lastFontId != glyphInfo.fontId )
@@ -308,10 +317,10 @@ struct LayoutEngine::Impl
           tmpLineLayout.ascender = fontMetrics.ascender;
         }
 
-        // Sets the maximum descender.
-        if( -fontMetrics.descender > tmpLineLayout.descender )
+        // Sets the minimum descender.
+        if( -fontMetrics.descender < tmpLineLayout.descender )
         {
-          tmpLineLayout.descender = -fontMetrics.descender;
+          tmpLineLayout.descender = fontMetrics.descender;
         }
 
         lastFontId = glyphInfo.fontId;
@@ -355,14 +364,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 +387,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 );
@@ -431,10 +444,10 @@ struct LayoutEngine::Impl
 
       // 2) Calculate the alignment offset accordingly with the align option,
       //    the box width, line length, and the paragraphs direction.
-      float alignOffset = CalculateAlignment( layoutSize.width,
-                                              line.lineSize.width,
-                                              line.extraLength,
-                                              paragraphDirection );
+      float alignOffset = CalculateHorizontalAlignment( layoutSize.width,
+                                                        line.width,
+                                                        line.extraLength,
+                                                        paragraphDirection );
 
       // 3) Traverse all glyphs and update the 'x' position.
       for( GlyphIndex index = line.glyphIndex,
@@ -467,15 +480,17 @@ struct LayoutEngine::Impl
     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.ascender + layout.descender;
+    lineRun.width = layout.length;
+    lineRun.ascender = layout.ascender;
+    lineRun.descender = layout.descender;
     lineRun.extraLength = layout.wsLengthEndOfLine;
+    lineRun.direction = false;
 
     lines.PushBack( lineRun );
 
     // Update the actual size.
     actualSize.width = layout.length;
-    actualSize.height = lineRun.lineSize.height;
+    actualSize.height = lineRun.ascender + -lineRun.descender;
 
     float penX = 0.f;
     float penY = layout.ascender;
@@ -525,9 +540,11 @@ struct LayoutEngine::Impl
       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 + ( ( layout.widthAdvanceDiff > 0.f ) ? layout.widthAdvanceDiff : 0.f );
-      lineRun.lineSize.height = layout.ascender + layout.descender;
+      lineRun.width = layout.length + ( ( layout.widthAdvanceDiff > 0.f ) ? layout.widthAdvanceDiff : 0.f );
+      lineRun.ascender = layout.ascender;
+      lineRun.descender = layout.descender;
       lineRun.extraLength = layout.wsLengthEndOfLine;
+      lineRun.direction = false;
 
       lines.PushBack( lineRun );
 
@@ -537,7 +554,7 @@ struct LayoutEngine::Impl
         actualSize.width = layout.length;
       }
 
-      actualSize.height += lineRun.lineSize.height;
+      actualSize.height += ( lineRun.ascender + -lineRun.descender );
 
       // Traverse the glyphs and set the positions.
 
@@ -555,7 +572,7 @@ struct LayoutEngine::Impl
         penX += glyph.advance;
       }
 
-      penY += layout.descender;
+      penY += -layout.descender;
 
       // Increase the glyph index.
       index += layout.numberOfGlyphs;
@@ -564,42 +581,42 @@ struct LayoutEngine::Impl
     return true;
   }
 
-  float CalculateAlignment( float boxWidth,
-                            float lineLength,
-                            float extraLength,
-                            bool paragraphDirection )
+  float CalculateHorizontalAlignment( float boxWidth,
+                                      float lineLength,
+                                      float extraLength,
+                                      bool paragraphDirection )
   {
     float offset = 0.f;
 
-    Alignment alignment = mAlignment;
+    HorizontalAlignment alignment = mHorizontalAlignment;
     if( paragraphDirection &&
-        ( ALIGN_CENTER != alignment ) )
+        ( HORIZONTAL_ALIGN_CENTER != alignment ) )
     {
-      if( ALIGN_BEGIN == alignment )
+      if( HORIZONTAL_ALIGN_BEGIN == alignment )
       {
-        alignment = ALIGN_END;
+        alignment = HORIZONTAL_ALIGN_END;
       }
       else
       {
-        alignment = ALIGN_BEGIN;
+        alignment = HORIZONTAL_ALIGN_BEGIN;
       }
     }
 
     switch( alignment )
     {
-      case ALIGN_BEGIN:
+      case HORIZONTAL_ALIGN_BEGIN:
       {
         offset = 0.f;
         break;
       }
-      case ALIGN_CENTER:
+      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 );
         break;
       }
-      case ALIGN_END:
+      case HORIZONTAL_ALIGN_END:
       {
         offset = boxWidth - lineLength;
         break;
@@ -615,7 +632,8 @@ struct LayoutEngine::Impl
   }
 
   LayoutEngine::Layout mLayout;
-  LayoutEngine::Alignment mAlignment;
+  LayoutEngine::HorizontalAlignment mHorizontalAlignment;
+  LayoutEngine::VerticalAlignment mVerticalAlignment;
 
   TextAbstraction::FontClient mFontClient;
 };
@@ -641,14 +659,24 @@ unsigned int LayoutEngine::GetLayout() const
   return mImpl->mLayout;
 }
 
-void LayoutEngine::SetAlignment( Alignment alignment )
+void LayoutEngine::SetHorizontalAlignment( HorizontalAlignment alignment )
+{
+  mImpl->mHorizontalAlignment = alignment;
+}
+
+LayoutEngine::HorizontalAlignment LayoutEngine::GetHorizontalAlignment() const
+{
+  return mImpl->mHorizontalAlignment;
+}
+
+void LayoutEngine::SetVerticalAlignment( VerticalAlignment alignment )
 {
-  mImpl->mAlignment = alignment;
+  mImpl->mVerticalAlignment = alignment;
 }
 
-LayoutEngine::Alignment LayoutEngine::GetAlignment() const
+LayoutEngine::VerticalAlignment LayoutEngine::GetVerticalAlignment() const
 {
-  return mImpl->mAlignment;
+  return mImpl->mVerticalAlignment;
 }
 
 bool LayoutEngine::LayoutText( const LayoutParameters& layoutParameters,