Merge "Make internal actors size match TextLabel size" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / rendering / atlas / text-atlas-renderer.cpp
index 789dfaf..e6d548f 100644 (file)
@@ -97,23 +97,19 @@ struct AtlasRenderer::Impl : public ConnectionTracker
   };
 
   Impl()
+  : mDepth( 0 )
   {
     mGlyphManager = AtlasGlyphManager::Get();
     mFontClient = TextAbstraction::FontClient::Get();
 
     mQuadVertexFormat[ "aPosition" ] = Property::VECTOR2;
     mQuadVertexFormat[ "aTexCoord" ] = Property::VECTOR2;
-    mQuadIndexFormat[ "indices" ] = Property::UNSIGNED_INTEGER;
+    mQuadIndexFormat[ "indices" ] = Property::INTEGER;
   }
 
-  void AddGlyphs( const std::vector<Vector2>& positions,
+  void AddGlyphs( Text::ViewInterface& view,
+                  const std::vector<Vector2>& positions,
                   const Vector<GlyphInfo>& glyphs,
-                  const Vector4& textColor,
-                  const Vector2& shadowOffset,
-                  const Vector4& shadowColor,
-                  bool underlineEnabled,
-                  const Vector4& underlineColor,
-                  float underlineHeight,
                   int depth )
   {
     AtlasManager::AtlasSlot slot;
@@ -122,6 +118,15 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     TextCacheEntry textCacheEntry;
     mDepth = depth;
 
+    const Vector2& actorSize( view.GetControlSize() );
+    Vector2 halfActorSize( actorSize * 0.5f );
+    const Vector4& textColor( view.GetTextColor() );
+    const Vector2& shadowOffset( view.GetShadowOffset() );
+    const Vector4& shadowColor( view.GetShadowColor() );
+    bool underlineEnabled( view.IsUnderlineEnabled() );
+    const Vector4& underlineColor( view.GetUnderlineColor() );
+    float underlineHeight( view.GetUnderlineHeight() );
+
     float currentUnderlinePosition = ZERO;
     float currentUnderlineThickness = underlineHeight;
     uint32_t currentBlockSize = 0;
@@ -133,14 +138,11 @@ struct AtlasRenderer::Impl : public ConnectionTracker
       style = STYLE_DROP_SHADOW;
     }
 
-    if ( mTextCache.Size() )
-    {
-      // Update the glyph cache with any changes to current text
-      RemoveText( glyphs );
-    }
-
     CalculateBlocksSize( glyphs );
 
+    // Avoid emptying mTextCache (& removing references) until after incremented references for the new text
+    Vector< TextCacheEntry > newTextCache;
+
     for( uint32_t i = 0, glyphSize = glyphs.Size(); i < glyphSize; ++i )
     {
       const GlyphInfo& glyph = glyphs[ i ];
@@ -184,9 +186,6 @@ struct AtlasRenderer::Impl : public ConnectionTracker
           }
         }
 
-        const Vector2& position = positions[ i ];
-        AtlasManager::Mesh2D newMesh;
-
         if ( !mGlyphManager.Cached( glyph.fontId, glyph.index, slot ) )
         {
           // Select correct size for new atlas if needed....?
@@ -234,13 +233,22 @@ struct AtlasRenderer::Impl : public ConnectionTracker
             mGlyphManager.Add( glyph, bitmap, slot );
           }
         }
+        else
+        {
+          // We have 2+ copies of the same glyph
+          mGlyphManager.AdjustReferenceCount( glyph.fontId, glyph.index, 1/*increment*/ );
+        }
+
+        // Move the origin (0,0) of the mesh to the center of the actor
+        Vector2 position = positions[ i ] - halfActorSize;
 
         // Generate mesh data for this quad, plugging in our supplied position
+        AtlasManager::Mesh2D newMesh;
         mGlyphManager.GenerateMeshData( slot.mImageId, position, newMesh );
         textCacheEntry.mFontId = glyph.fontId;
         textCacheEntry.mImageId = slot.mImageId;
         textCacheEntry.mIndex = glyph.index;
-        mTextCache.PushBack( textCacheEntry );
+        newTextCache.PushBack( textCacheEntry );
 
         // Find an existing mesh data object to attach to ( or create a new one, if we can't find one using the same atlas)
         StitchTextMesh( meshContainer,
@@ -255,6 +263,10 @@ struct AtlasRenderer::Impl : public ConnectionTracker
       }
     }
 
+    // Now remove references for the old text
+    RemoveText();
+    mTextCache.Swap( newTextCache );
+
     if ( underlineEnabled )
     {
       // Check to see if any of the text needs an underline
@@ -266,17 +278,16 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     {
       for ( std::vector< MeshRecord >::iterator mIt = meshContainer.begin(); mIt != meshContainer.end(); ++mIt )
       {
-        Actor actor = CreateMeshActor( *mIt );
+        Actor actor = CreateMeshActor( *mIt, actorSize );
 
         // Create an effect if necessary
         if ( style == STYLE_DROP_SHADOW )
         {
-          actor.Add( GenerateShadow( *mIt, shadowOffset, shadowColor ) );
+          actor.Add( GenerateShadow( *mIt, actorSize, shadowOffset, shadowColor ) );
         }
 
         if( mActor )
         {
-          actor.SetParentOrigin( ParentOrigin::CENTER ); // Keep all of the origins aligned
           mActor.Add( actor );
         }
         else
@@ -291,9 +302,12 @@ struct AtlasRenderer::Impl : public ConnectionTracker
                                                 metrics.mGlyphCount,
                                                 metrics.mAtlasMetrics.mAtlasCount,
                                                 metrics.mAtlasMetrics.mTextureMemoryUsed / 1024 );
+
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "%s\n", metrics.mVerboseGlyphCounts.c_str() );
+
     for ( uint32_t i = 0; i < metrics.mAtlasMetrics.mAtlasCount; ++i )
     {
-      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Atlas [%i] %sPixels: %s Size: %ix%i, BlockSize: %ix%i, BlocksUsed: %i/%i\n",
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "   Atlas [%i] %sPixels: %s Size: %ix%i, BlockSize: %ix%i, BlocksUsed: %i/%i\n",
                                                  i + 1, i > 8 ? "" : " ",
                                                  metrics.mAtlasMetrics.mAtlasMetrics[ i ].mPixelFormat == Pixel::L8 ? "L8  " : "BGRA",
                                                  metrics.mAtlasMetrics.mAtlasMetrics[ i ].mSize.mWidth,
@@ -306,7 +320,16 @@ struct AtlasRenderer::Impl : public ConnectionTracker
 #endif
   }
 
-  Actor CreateMeshActor( const MeshRecord& meshRecord )
+  void RemoveText()
+  {
+    for ( Vector< TextCacheEntry >::Iterator oldTextIter = mTextCache.Begin(); oldTextIter != mTextCache.End(); ++oldTextIter )
+    {
+      mGlyphManager.AdjustReferenceCount( oldTextIter->mFontId, oldTextIter->mIndex, -1/*decrement*/ );
+    }
+    mTextCache.Resize( 0 );
+  }
+
+  Actor CreateMeshActor( const MeshRecord& meshRecord, const Vector2& actorSize )
   {
     PropertyBuffer quadVertices = PropertyBuffer::New( mQuadVertexFormat, meshRecord.mMesh.mVertices.Size() );
     PropertyBuffer quadIndices = PropertyBuffer::New( mQuadIndexFormat, meshRecord.mMesh.mIndices.Size() );
@@ -325,7 +348,8 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     actor.SetName( "Text renderable actor" );
 #endif
     actor.AddRenderer( renderer );
-    actor.SetSize( 1.0f, 1.0f );
+    actor.SetParentOrigin( ParentOrigin::CENTER ); // Keep all of the origins aligned
+    actor.SetSize( actorSize );
     actor.SetColor( meshRecord.mColor );
 
     if ( meshRecord.mIsUnderline )
@@ -441,58 +465,6 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     }
   }
 
-  void RemoveText( const Vector<GlyphInfo>& glyphs )
-  {
-    Vector< CheckEntry > checked;
-    CheckEntry checkEntry;
-
-    for ( Vector< TextCacheEntry >::Iterator tCit = mTextCache.Begin(); tCit != mTextCache.End(); ++tCit )
-    {
-      uint32_t index = tCit->mIndex;
-      uint32_t fontId = tCit->mFontId;
-
-      // Check that this character has not already been checked...
-      bool wasChecked = false;
-      for ( Vector< CheckEntry >::Iterator cEit = checked.Begin(); cEit != checked.End(); ++cEit )
-      {
-        if ( fontId == cEit->mFontId && index == cEit->mIndex )
-        {
-          wasChecked = true;
-        }
-      }
-
-      if ( !wasChecked )
-      {
-
-        int32_t newCount = 0;
-        int32_t oldCount = 0;
-
-        // How many times does this character occur in the old text ?
-        for ( Vector< TextCacheEntry >::Iterator oTcit = mTextCache.Begin(); oTcit != mTextCache.End(); ++oTcit )
-        {
-          if ( fontId == oTcit->mFontId && index == oTcit->mIndex )
-          {
-            oldCount++;
-          }
-        }
-
-        // And how many times in the new ?
-        for ( Vector< GlyphInfo >::Iterator cGit = glyphs.Begin(); cGit != glyphs.End(); ++cGit )
-        {
-          if ( fontId == cGit->fontId && index == cGit->index )
-          {
-            newCount++;
-          }
-        }
-        mGlyphManager.AdjustReferenceCount( fontId, tCit->mImageId, newCount - oldCount );
-        checkEntry.mIndex = index;
-        checkEntry.mFontId = fontId;
-        checked.PushBack( checkEntry );
-      }
-    }
-    mTextCache.Resize( 0 );
-  }
-
   void CalculateBlocksSize( const Vector<GlyphInfo>& glyphs )
   {
     MaxBlockSize maxBlockSize;
@@ -588,6 +560,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker
   }
 
   Actor GenerateShadow( MeshRecord& meshRecord,
+                        const Vector2& actorSize,
                         const Vector2& shadowOffset,
                         const Vector4& shadowColor )
   {
@@ -654,7 +627,8 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     renderer.SetDepthIndex( CONTENT_DEPTH_INDEX + mDepth - 1 );
     Actor actor = Actor::New();
     actor.AddRenderer( renderer );
-    actor.SetSize( 1.0f, 1.0f );
+    actor.SetParentOrigin( ParentOrigin::CENTER ); // Keep all of the origins aligned
+    actor.SetSize( actorSize );
 
     // Create a sub actor to render the source with normalized vertex positions
     Vector< AtlasManager::Vertex2D > normVertexList;
@@ -681,7 +655,8 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     Dali::Renderer normRenderer = Dali::Renderer::New( normGeometry, normMaterial );
     Actor subActor = Actor::New();
     subActor.AddRenderer( normRenderer );
-    subActor.SetSize( 1.0f, 1.0f );
+    subActor.SetParentOrigin( ParentOrigin::CENTER ); // Keep all of the origins aligned
+    subActor.SetSize( actorSize );
     subActor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
     subActor.SetColor( shadowColor );
 
@@ -756,14 +731,9 @@ Actor AtlasRenderer::Render( Text::ViewInterface& view, int depth )
     glyphs.Resize( numberOfGlyphs );
     positions.resize( numberOfGlyphs );
 
-    mImpl->AddGlyphs( positions,
+    mImpl->AddGlyphs( view,
+                      positions,
                       glyphs,
-                      view.GetTextColor(),
-                      view.GetShadowOffset(),
-                      view.GetShadowColor(),
-                      view.IsUnderlineEnabled(),
-                      view.GetUnderlineColor(),
-                      view.GetUnderlineHeight(),
                       depth );
   }
 
@@ -778,7 +748,6 @@ AtlasRenderer::AtlasRenderer()
 
 AtlasRenderer::~AtlasRenderer()
 {
-  Vector< GlyphInfo > emptyGlyphs;
-  mImpl->RemoveText( emptyGlyphs );
+  mImpl->RemoveText();
   delete mImpl;
 }