Support Underline to Markup using underlined-character-run
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / rendering / atlas / text-atlas-renderer.cpp
index 208460c..7b51d5b 100644 (file)
@@ -85,7 +85,8 @@ struct AtlasRenderer::Impl
       mRight(0.0f),
       mUnderlinePosition(0.0f),
       mUnderlineThickness(0.0f),
-      mMeshRecordIndex(0u)
+      mMeshRecordIndex(0u),
+      mUnderlineChunkId(0u)
     {
     }
 
@@ -95,6 +96,7 @@ struct AtlasRenderer::Impl
     float    mUnderlinePosition;
     float    mUnderlineThickness;
     uint32_t mMeshRecordIndex;
+    uint32_t mUnderlineChunkId;
   };
 
   struct MaxBlockSize
@@ -288,7 +290,8 @@ struct AtlasRenderer::Impl
                     float                    currentUnderlineThickness,
                     std::vector<MeshRecord>& meshContainer,
                     Vector<TextCacheEntry>&  newTextCache,
-                    Vector<Extent>&          extents)
+                    Vector<Extent>&          extents,
+                    uint32_t                 underlineChunkId)
   {
     // Generate mesh data for this quad, plugging in our supplied position
     AtlasManager::Mesh2D newMesh;
@@ -324,7 +327,8 @@ struct AtlasRenderer::Impl
                    underlineGlyph,
                    currentUnderlinePosition,
                    currentUnderlineThickness,
-                   slot);
+                   slot,
+                   underlineChunkId);
   }
 
   void CreateActors(const std::vector<MeshRecord>& meshContainer,
@@ -458,6 +462,10 @@ struct AtlasRenderer::Impl
     const Vector2* const   positionsBuffer = positions.Begin();
     const Vector2          lineOffsetPosition(minLineOffset, 0.f);
 
+    //For septated underlined chunks. (this is for Markup case)
+    uint32_t underlineChunkId = 0u; // give id for each chunk.
+    bool     isPreUnderlined = false; // status of underlined for previous glyph.
+
     for(uint32_t i = 0, glyphSize = glyphs.Size(); i < glyphSize; ++i)
     {
       const GlyphInfo& glyph             = *(glyphsBuffer + i);
@@ -504,6 +512,7 @@ struct AtlasRenderer::Impl
           }
 
           lastUnderlinedFontId = glyph.fontId;
+
         } // underline
 
         AtlasGlyphManager::GlyphStyle style;
@@ -548,7 +557,8 @@ struct AtlasRenderer::Impl
                        currentUnderlineThickness,
                        meshContainer,
                        newTextCache,
-                       extents);
+                       extents,
+                       underlineChunkId);
 
           lastFontId = glyph.fontId; // Prevents searching for existing blocksizes when string of the same fontId.
         }
@@ -565,8 +575,19 @@ struct AtlasRenderer::Impl
                        currentUnderlineThickness,
                        meshContainerOutline,
                        newTextCache,
-                       extents);
+                       extents,
+                       0u);
+        }
+
+
+        //The new underlined chunk. Add new id if they are not consecutive indices (this is for Markup case)
+        // Examples: "Hello <u>World</u> Hello <u>World</u>", "<u>World</u> Hello <u>World</u>", "<u>   World</u> Hello <u>World</u>"
+        if( isPreUnderlined && (isPreUnderlined != isGlyphUnderlined))
+        {
+          underlineChunkId++;
         }
+        //Keep status of underlined for previous glyph to check consecutive indices
+        isPreUnderlined = isGlyphUnderlined;
       }
     } // glyphs
 
@@ -717,7 +738,8 @@ struct AtlasRenderer::Impl
                       bool                     underlineGlyph,
                       float                    underlinePosition,
                       float                    underlineThickness,
-                      AtlasManager::AtlasSlot& slot)
+                      AtlasManager::AtlasSlot& slot,
+                      uint32_t                 underlineChunkId)
   {
     if(slot.mImageId)
     {
@@ -745,7 +767,8 @@ struct AtlasRenderer::Impl
                           right,
                           baseLine,
                           underlinePosition,
-                          underlineThickness);
+                          underlineThickness,
+                          underlineChunkId);
           }
 
           return;
@@ -768,7 +791,8 @@ struct AtlasRenderer::Impl
                       right,
                       baseLine,
                       underlinePosition,
-                      underlineThickness);
+                      underlineThickness,
+                      underlineChunkId);
       }
     }
   }
@@ -780,7 +804,8 @@ struct AtlasRenderer::Impl
                      float                    right,
                      float                    baseLine,
                      float                    underlinePosition,
-                     float                    underlineThickness)
+                     float                    underlineThickness,
+                     uint32_t                 underlineChunkId)
   {
     bool foundExtent = false;
     for(Vector<Extent>::Iterator eIt    = extents.Begin(),
@@ -788,7 +813,7 @@ struct AtlasRenderer::Impl
         eIt != eEndIt;
         ++eIt)
     {
-      if(Equals(baseLine, eIt->mBaseLine))
+      if(Equals(baseLine, eIt->mBaseLine) && underlineChunkId == eIt->mUnderlineChunkId)
       {
         foundExtent = true;
         if(left < eIt->mLeft)
@@ -819,6 +844,7 @@ struct AtlasRenderer::Impl
       extent.mUnderlinePosition  = underlinePosition;
       extent.mUnderlineThickness = underlineThickness;
       extent.mMeshRecordIndex    = index;
+      extent.mUnderlineChunkId = underlineChunkId;
       extents.PushBack(extent);
     }
   }