[dali_2.3.22] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / rendering / atlas / atlas-glyph-manager-impl.cpp
index d7fde4e..bc2a146 100644 (file)
@@ -1,5 +1,5 @@
- /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h>
 
 // EXTERNAL INCLUDES
-#include <dali/public-api/actors/image-actor.h>
-#include <dali/public-api/common/stage.h>
+#include <dali/integration-api/debug.h>
 
-namespace Dali
+namespace
 {
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING");
+#endif
 
+} // unnamed namespace
+
+namespace Dali
+{
 namespace Toolkit
 {
-
 namespace Internal
 {
-
-//#define DISPLAY_ATLAS
-
 AtlasGlyphManager::AtlasGlyphManager()
-: mCount( 0 )
 {
   mAtlasManager = Dali::Toolkit::AtlasManager::New();
+  mSampler      = Sampler::New();
+  mSampler.SetFilterMode(FilterMode::LINEAR, FilterMode::LINEAR);
 }
 
-AtlasGlyphManager::~AtlasGlyphManager()
+void AtlasGlyphManager::Add(const Text::GlyphInfo&                        glyph,
+                            const Toolkit::AtlasGlyphManager::GlyphStyle& style,
+                            const PixelData&                              bitmap,
+                            Dali::Toolkit::AtlasManager::AtlasSlot&       slot)
 {
-  // Clear up any remaining references
-  for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
-        fontGlyphRecordIt != mFontGlyphRecords.end();
-        ++fontGlyphRecordIt )
+  DALI_LOG_INFO(gLogFilter, Debug::General, "Added glyph, font: %d index: %d\n", glyph.fontId, glyph.index);
+
+  // If glyph added to an existing or new atlas then a new glyph record is required.
+  // Check if an existing atlas will fit the image, create a new one if required.
+  if(mAtlasManager.Add(bitmap, slot))
   {
-    for ( Vector< GlyphRecordEntry >::Iterator glyphRecordEntryIt = fontGlyphRecordIt->mGlyphRecords.Begin();
-          glyphRecordEntryIt != fontGlyphRecordIt->mGlyphRecords.End();
-          ++glyphRecordEntryIt )
-    {
-      mAtlasManager.Remove( glyphRecordEntryIt->mImageId );
-    }
+    // A new atlas was created so set the texture set details for the atlas
+    Dali::Texture atlas      = mAtlasManager.GetAtlasContainer(slot.mAtlasId);
+    TextureSet    textureSet = TextureSet::New();
+    textureSet.SetTexture(0u, atlas);
+    textureSet.SetSampler(0u, mSampler);
+    mAtlasManager.SetTextures(slot.mAtlasId, textureSet);
   }
-}
-
-AtlasGlyphManagerPtr AtlasGlyphManager::New()
-{
-  AtlasGlyphManagerPtr internal = new AtlasGlyphManager();
-  return internal;
-}
-
-void AtlasGlyphManager::Add( Text::FontId fontId,
-                             const Text::GlyphInfo& glyph,
-                             const BufferImage& bitmap,
-                             Dali::Toolkit::AtlasManager::AtlasSlot& slot )
-{
-  mAtlasManager.Add( bitmap, slot );
 
   GlyphRecordEntry record;
-  record.mIndex = glyph.index;
-  record.mImageId = slot.mImageId;
-  record.mCount = 1;
+  record.mIndex        = glyph.index;
+  record.mImageId      = slot.mImageId;
+  record.mCount        = 1;
+  record.mOutlineWidth = style.outline;
+  record.isItalic      = style.isItalic;
+  record.isBold        = style.isBold;
 
   // Have glyph records been created for this fontId ?
   bool foundGlyph = false;
-  for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
-        fontGlyphRecordIt != mFontGlyphRecords.end(); ++fontGlyphRecordIt )
+  for(std::vector<FontGlyphRecord>::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+      fontGlyphRecordIt != mFontGlyphRecords.end();
+      ++fontGlyphRecordIt)
   {
-    if ( fontGlyphRecordIt->mFontId == fontId )
+    if(fontGlyphRecordIt->mFontId == glyph.fontId)
     {
-      fontGlyphRecordIt->mGlyphRecords.PushBack( record );
+      fontGlyphRecordIt->mGlyphRecords.PushBack(record);
       foundGlyph = true;
       break;
     }
   }
 
-  if ( !foundGlyph )
+  if(!foundGlyph)
   {
     // We need to add a new font entry
     FontGlyphRecord fontGlyphRecord;
-    fontGlyphRecord.mFontId = fontId;
-    fontGlyphRecord.mGlyphRecords.PushBack( record );
-    mFontGlyphRecords.push_back( fontGlyphRecord );
+    fontGlyphRecord.mFontId = glyph.fontId;
+    fontGlyphRecord.mGlyphRecords.PushBack(record);
+    mFontGlyphRecords.push_back(fontGlyphRecord);
   }
-
-#ifdef DISPLAY_ATLAS
-  {
-    uint32_t atlasCount = mAtlasManager.GetAtlasCount();
-    if ( atlasCount > mCount )
-    {
-      for ( uint32_t i = 0; i < atlasCount; ++i )
-      {
-        ImageActor actor = ImageActor::New( mAtlasManager.GetAtlasContainer( i + 1u ) );
-        actor.SetParentOrigin( Vector3( 0.5f, 0.25f + ( static_cast< float >( i ) * 0.25f ), 0.5f ) );
-        actor.SetAnchorPoint( AnchorPoint::CENTER );
-        actor.SetSize( 256.0f, 256.0f );
-        Stage::GetCurrent().Add( actor );
-      }
-    }
-    mCount = atlasCount;
-  }
-#endif
 }
 
-void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
-                                          const Vector2& position,
-                                          MeshData& meshData )
+void AtlasGlyphManager::GenerateMeshData(uint32_t                       imageId,
+                                         const Vector2&                 position,
+                                         Toolkit::AtlasManager::Mesh2D& mesh)
 {
   // Generate mesh data and tell Atlas Manager not to handle reference counting ( we'll do it )
-  mAtlasManager.GenerateMeshData( imageId, position, meshData, false );
+  mAtlasManager.GenerateMeshData(imageId, position, mesh, false);
 }
 
-void AtlasGlyphManager::StitchMesh( MeshData& first,
-                                    const MeshData& second )
+bool AtlasGlyphManager::IsCached(Text::FontId                                  fontId,
+                                 Text::GlyphIndex                              index,
+                                 const Toolkit::AtlasGlyphManager::GlyphStyle& style,
+                                 Dali::Toolkit::AtlasManager::AtlasSlot&       slot)
 {
-  mAtlasManager.StitchMesh( first, second );
-}
-
-bool AtlasGlyphManager::Cached( Text::FontId fontId,
-                                uint32_t index,
-                                Dali::Toolkit::AtlasManager::AtlasSlot& slot )
-{
-  for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
-        fontGlyphRecordIt != mFontGlyphRecords.end();
-        ++fontGlyphRecordIt )
+  for(std::vector<FontGlyphRecord>::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+      fontGlyphRecordIt != mFontGlyphRecords.end();
+      ++fontGlyphRecordIt)
   {
-    if ( fontGlyphRecordIt->mFontId == fontId )
+    if(fontGlyphRecordIt->mFontId == fontId)
     {
-      for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
-            glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
-            ++glyphRecordIt )
+      for(Vector<GlyphRecordEntry>::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+          glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
+          ++glyphRecordIt)
       {
-        if ( glyphRecordIt->mIndex == index )
+        if((glyphRecordIt->mIndex == index) &&
+           (glyphRecordIt->mOutlineWidth == style.outline) &&
+           (glyphRecordIt->isItalic == style.isItalic) &&
+           (glyphRecordIt->isBold == style.isBold))
         {
           slot.mImageId = glyphRecordIt->mImageId;
-          slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
+          slot.mAtlasId = mAtlasManager.GetAtlas(slot.mImageId);
           return true;
         }
       }
@@ -154,61 +131,104 @@ bool AtlasGlyphManager::Cached( Text::FontId fontId,
   return false;
 }
 
-Vector2 AtlasGlyphManager::GetAtlasSize( uint32_t atlasId )
+Vector2 AtlasGlyphManager::GetAtlasSize(uint32_t atlasId)
 {
-  Toolkit::AtlasManager::AtlasSize size = mAtlasManager.GetAtlasSize( atlasId );
-  return Vector2( static_cast< float >( size.mWidth ), static_cast< float >( size.mHeight ) );
+  Toolkit::AtlasManager::AtlasSize size = mAtlasManager.GetAtlasSize(atlasId);
+  return Vector2(static_cast<float>(size.mWidth), static_cast<float>(size.mHeight));
 }
 
-void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight )
+void AtlasGlyphManager::SetNewAtlasSize(uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight)
 {
   Toolkit::AtlasManager::AtlasSize size;
-  size.mWidth = width;
-  size.mHeight = height;
-  size.mBlockWidth = blockWidth;
+  size.mWidth       = width;
+  size.mHeight      = height;
+  size.mBlockWidth  = blockWidth;
   size.mBlockHeight = blockHeight;
-  mAtlasManager.SetNewAtlasSize( size );
+  mAtlasManager.SetNewAtlasSize(size);
 }
 
-Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
+Pixel::Format AtlasGlyphManager::GetPixelFormat(uint32_t atlasId)
 {
-  return mAtlasManager.GetPixelFormat( atlasId );
+  return mAtlasManager.GetPixelFormat(atlasId);
 }
 
 const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
 {
-  mMetrics.mGlyphCount = mFontGlyphRecords.size();
-  mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
+  std::ostringstream verboseMetrics;
+
+  mMetrics.mGlyphCount = 0u;
+  for(std::vector<FontGlyphRecord>::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+      fontGlyphRecordIt != mFontGlyphRecords.end();
+      ++fontGlyphRecordIt)
+  {
+    mMetrics.mGlyphCount += fontGlyphRecordIt->mGlyphRecords.Size();
+
+    verboseMetrics << "[FontId " << fontGlyphRecordIt->mFontId << " Glyph ";
+    for(Vector<GlyphRecordEntry>::Iterator glyphRecordEntryIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+        glyphRecordEntryIt != fontGlyphRecordIt->mGlyphRecords.End();
+        ++glyphRecordEntryIt)
+    {
+      verboseMetrics << glyphRecordEntryIt->mIndex << "(" << glyphRecordEntryIt->mCount << ") ";
+    }
+    verboseMetrics << "] ";
+  }
+  mMetrics.mVerboseGlyphCounts = verboseMetrics.str();
+
+  mAtlasManager.GetMetrics(mMetrics.mAtlasMetrics);
+
   return mMetrics;
 }
 
-void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta )
+void AtlasGlyphManager::AdjustReferenceCount(Text::FontId fontId, Text::GlyphIndex index, const Toolkit::AtlasGlyphManager::GlyphStyle& style, int32_t delta)
 {
-  for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
-        fontGlyphRecordIt != mFontGlyphRecords.end();
-        ++fontGlyphRecordIt )
+  if(0 != delta)
   {
-    if ( fontGlyphRecordIt->mFontId == fontId )
+    DALI_LOG_INFO(gLogFilter, Debug::General, "AdjustReferenceCount %d, font: %d index: %d\n", delta, fontId, index);
+
+    for(std::vector<FontGlyphRecord>::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+        fontGlyphRecordIt != mFontGlyphRecords.end();
+        ++fontGlyphRecordIt)
     {
-      for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
-            glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
-            ++glyphRecordIt )
+      if(fontGlyphRecordIt->mFontId == fontId)
       {
-        if ( glyphRecordIt->mImageId == imageId )
+        for(Vector<GlyphRecordEntry>::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+            glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
+            ++glyphRecordIt)
         {
-          glyphRecordIt->mCount += delta;
-          if ( !glyphRecordIt->mCount )
+          if((glyphRecordIt->mIndex == index) &&
+             (glyphRecordIt->mOutlineWidth == style.outline) &&
+             (glyphRecordIt->isItalic == style.isItalic) &&
+             (glyphRecordIt->isBold == style.isBold))
           {
-            mAtlasManager.Remove( glyphRecordIt->mImageId );
-            fontGlyphRecordIt->mGlyphRecords.Remove( glyphRecordIt );
+            glyphRecordIt->mCount += delta;
+            DALI_ASSERT_DEBUG(glyphRecordIt->mCount >= 0 && "Glyph ref-count should not be negative");
+
+            if(!glyphRecordIt->mCount)
+            {
+              mAtlasManager.Remove(glyphRecordIt->mImageId);
+              fontGlyphRecordIt->mGlyphRecords.Remove(glyphRecordIt);
+            }
+            return;
           }
-          return;
         }
       }
     }
+
+    // Should not arrive here
+    DALI_ASSERT_DEBUG(false && "Failed to adjust ref-count");
   }
 }
 
+TextureSet AtlasGlyphManager::GetTextures(uint32_t atlasId) const
+{
+  return mAtlasManager.GetTextures(atlasId);
+}
+
+AtlasGlyphManager::~AtlasGlyphManager()
+{
+  // mAtlasManager handle is automatically released here
+}
+
 } // namespace Internal
 
 } // namespace Toolkit