Merge "Fix for text renderer. Set the right size in order to cull the actor correctly...
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / rendering / atlas / text-atlas-renderer.cpp
index e336e0b..7d17847 100644 (file)
@@ -25,7 +25,7 @@
 #include <dali/devel-api/text-abstraction/font-client.h>
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/internal/text/glyph-run.h>
 #include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h>
 #include <dali-toolkit/internal/text/rendering/atlas/atlas-mesh-factory.h>
@@ -59,12 +59,10 @@ struct AtlasRenderer::Impl
   struct MeshRecord
   {
     MeshRecord()
-    : mColor( Color::BLACK ),
-      mAtlasId( 0 )
+    : mAtlasId( 0u )
     {
     }
 
-    Vector4 mColor;
     uint32_t mAtlasId;
     AtlasManager::Mesh2D mMesh;
     FrameBufferImage mBuffer;
@@ -82,7 +80,7 @@ struct AtlasRenderer::Impl
       mRight( 0.0f ),
       mUnderlinePosition( 0.0f ),
       mUnderlineThickness( 0.0f ),
-      mMeshRecordIndex( 0 )
+      mMeshRecordIndex( 0u )
     {
     }
 
@@ -142,6 +140,7 @@ struct AtlasRenderer::Impl
 
     mQuadVertexFormat[ "aPosition" ] = Property::VECTOR2;
     mQuadVertexFormat[ "aTexCoord" ] = Property::VECTOR2;
+    mQuadVertexFormat[ "aColor" ] = Property::VECTOR4;
     mQuadIndexFormat[ "indices" ] = Property::INTEGER;
   }
 
@@ -167,6 +166,7 @@ struct AtlasRenderer::Impl
   void AddGlyphs( Text::ViewInterface& view,
                   const Vector<Vector2>& positions,
                   const Vector<GlyphInfo>& glyphs,
+                  const Vector<Vector4>& colors,
                   int depth )
   {
     AtlasManager::AtlasSlot slot;
@@ -176,8 +176,8 @@ struct AtlasRenderer::Impl
     mDepth = depth;
 
     const Vector2& actorSize( view.GetControlSize() );
-    const Vector2 halfActorSize( actorSize * 0.5f );
-    const Vector4& textColor( view.GetTextColor() );
+    const Vector2& textSize( view.GetActualSize() );
+    const Vector2 halfTextSize( textSize * 0.5f );
     const Vector2& shadowOffset( view.GetShadowOffset() );
     const Vector4& shadowColor( view.GetShadowColor() );
     const bool underlineEnabled( view.IsUnderlineEnabled() );
@@ -212,6 +212,7 @@ struct AtlasRenderer::Impl
     Vector< TextCacheEntry > newTextCache;
     const GlyphInfo* const glyphsBuffer = glyphs.Begin();
     const Vector2* const positionsBuffer = positions.Begin();
+    const Vector4* const colorsBuffer = colors.Begin();
 
     for( uint32_t i = 0, glyphSize = glyphs.Size(); i < glyphSize; ++i )
     {
@@ -323,7 +324,7 @@ struct AtlasRenderer::Impl
         }
 
         // Move the origin (0,0) of the mesh to the center of the actor
-        const Vector2 position = *( positionsBuffer + i ) - halfActorSize;
+        const Vector2 position = *( positionsBuffer + i ) - halfTextSize;
 
         // Generate mesh data for this quad, plugging in our supplied position
         AtlasManager::Mesh2D newMesh;
@@ -350,11 +351,23 @@ struct AtlasRenderer::Impl
           }
         }
 
+        // Get the color of the character.
+        const Vector4& color = *( colorsBuffer + i );
+
+        for( unsigned int index = 0u, size = newMesh.mVertices.Count();
+             index < size;
+             ++index )
+        {
+          AtlasManager::Vertex2D& vertex = *( verticesBuffer + index );
+
+          // Set the color of the vertex.
+          vertex.mColor = color;
+        }
+
         // 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,
                         newMesh,
                         extents,
-                        textColor,
                         position.y + glyph.yBearing,
                         underlineGlyph,
                         currentUnderlinePosition,
@@ -371,7 +384,7 @@ struct AtlasRenderer::Impl
     if( thereAreUnderlinedGlyphs )
     {
       // Check to see if any of the text needs an underline
-      GenerateUnderlines( meshContainer, extents, underlineColor, textColor );
+      GenerateUnderlines( meshContainer, extents, underlineColor );
     }
 
     // For each MeshData object, create a mesh actor and add to the renderable actor
@@ -383,17 +396,28 @@ struct AtlasRenderer::Impl
       {
         MeshRecord& meshRecord = *it;
 
-        Actor actor = CreateMeshActor( meshRecord, actorSize );
+        Actor actor = CreateMeshActor( meshRecord, textSize );
 
         // Create an effect if necessary
         if( style == STYLE_DROP_SHADOW )
         {
+          // Change the color of the vertices.
+          for( Vector<AtlasManager::Vertex2D>::Iterator vIt =  meshRecord.mMesh.mVertices.Begin(),
+                 vEndIt = meshRecord.mMesh.mVertices.End();
+               vIt != vEndIt;
+               ++vIt )
+          {
+            AtlasManager::Vertex2D& vertex = *vIt;
+
+            vertex.mColor = shadowColor;
+          }
+
           // Create a container actor to act as a common parent for text and shadow, to avoid color inheritence issues.
           Actor containerActor = Actor::New();
           containerActor.SetParentOrigin( ParentOrigin::CENTER );
           containerActor.SetSize( actorSize );
 
-          Actor shadowActor = Actor::New();
+          Actor shadowActor = CreateMeshActor( meshRecord, textSize );
 #if defined(DEBUG_ENABLED)
           shadowActor.SetName( "Text Shadow renderable actor" );
 #endif
@@ -401,16 +425,9 @@ struct AtlasRenderer::Impl
           shadowActor.RegisterProperty("uOffset", shadowOffset );
           if( actor.GetRendererCount() )
           {
-            Dali::Renderer renderer( actor.GetRendererAt( 0 ) );
-            Geometry geometry = renderer.GetGeometry();
-            Material material = renderer.GetMaterial();
-
-            Dali::Renderer shadowRenderer = Dali::Renderer::New( geometry, material );
-            shadowRenderer.SetDepthIndex( renderer.GetDepthIndex() - 1 );
-            shadowActor.AddRenderer( shadowRenderer );
-            shadowActor.SetParentOrigin( ParentOrigin::CENTER );
-            shadowActor.SetSize( actorSize );
-            shadowActor.SetColor( shadowColor );
+            Dali::Renderer renderer( shadowActor.GetRendererAt( 0 ) );
+            int depthIndex = renderer.GetProperty<int>(Dali::Renderer::Property::DEPTH_INDEX);
+            renderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, depthIndex - 1 );
             containerActor.Add( shadowActor );
             containerActor.Add( actor );
             actor = containerActor;
@@ -462,10 +479,10 @@ struct AtlasRenderer::Impl
 
   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() );
-    quadVertices.SetData( const_cast< AtlasManager::Vertex2D* >( &meshRecord.mMesh.mVertices[ 0 ] ) );
-    quadIndices.SetData( const_cast< unsigned int* >( &meshRecord.mMesh.mIndices[ 0 ] ) );
+    PropertyBuffer quadVertices = PropertyBuffer::New( mQuadVertexFormat );
+    PropertyBuffer quadIndices = PropertyBuffer::New( mQuadIndexFormat );
+    quadVertices.SetData( const_cast< AtlasManager::Vertex2D* >( &meshRecord.mMesh.mVertices[ 0 ] ), meshRecord.mMesh.mVertices.Size() );
+    quadIndices.SetData(  const_cast< unsigned int* >(           &meshRecord.mMesh.mIndices[ 0 ] ),  meshRecord.mMesh.mIndices.Size() );
 
     Geometry quadGeometry = Geometry::New();
     quadGeometry.AddVertexBuffer( quadVertices );
@@ -473,15 +490,19 @@ struct AtlasRenderer::Impl
 
     Material material = mGlyphManager.GetMaterial( meshRecord.mAtlasId );
     Dali::Renderer renderer = Dali::Renderer::New( quadGeometry, material );
-    renderer.SetDepthIndex( CONTENT_DEPTH_INDEX + mDepth );
+    renderer.SetProperty( Dali::Renderer::Property::BLENDING_MODE, BlendingMode::ON );
+    renderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, DepthIndex::CONTENT + mDepth );
     Actor actor = Actor::New();
 #if defined(DEBUG_ENABLED)
     actor.SetName( "Text renderable actor" );
 #endif
     actor.AddRenderer( renderer );
-    actor.SetParentOrigin( ParentOrigin::CENTER ); // Keep all of the origins aligned
+
+    // Keep all of the origins aligned
+    actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+    actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
     actor.SetSize( actorSize );
-    actor.SetColor( meshRecord.mColor );
     actor.RegisterProperty("uOffset", Vector2::ZERO );
     return actor;
   }
@@ -489,7 +510,6 @@ struct AtlasRenderer::Impl
   void StitchTextMesh( std::vector< MeshRecord >& meshContainer,
                        AtlasManager::Mesh2D& newMesh,
                        Vector< Extent >& extents,
-                       const Vector4& color,
                        float baseLine,
                        bool underlineGlyph,
                        float underlinePosition,
@@ -508,7 +528,7 @@ struct AtlasRenderer::Impl
             mIt != mEndIt;
             ++mIt, ++index )
       {
-        if( slot.mAtlasId == mIt->mAtlasId && color == mIt->mColor )
+        if( slot.mAtlasId == mIt->mAtlasId )
         {
           // Append the mesh to the existing mesh and adjust any extents
           Toolkit::Internal::AtlasMeshFactory::AppendMesh( mIt->mMesh, newMesh );
@@ -533,7 +553,6 @@ struct AtlasRenderer::Impl
       MeshRecord meshRecord;
       meshRecord.mAtlasId = slot.mAtlasId;
       meshRecord.mMesh = newMesh;
-      meshRecord.mColor = color;
       meshContainer.push_back( meshRecord );
 
       if( underlineGlyph )
@@ -640,8 +659,7 @@ struct AtlasRenderer::Impl
 
   void GenerateUnderlines( std::vector< MeshRecord >& meshRecords,
                            Vector< Extent >& extents,
-                           const Vector4& underlineColor,
-                           const Vector4& textColor )
+                           const Vector4& underlineColor )
   {
     AtlasManager::Mesh2D newMesh;
     unsigned short faceIndex = 0;
@@ -693,18 +711,9 @@ struct AtlasRenderer::Impl
       newMesh.mIndices.PushBack( faceIndex + 1u );
       faceIndex += 4;
 
-      if( underlineColor == textColor )
-      {
-        Toolkit::Internal::AtlasMeshFactory::AppendMesh( meshRecords[ index ].mMesh, newMesh );
-      }
-      else
-      {
-        MeshRecord record;
-        record.mMesh = newMesh;
-        record.mAtlasId = meshRecords[ index ].mAtlasId;
-        record.mColor = underlineColor;
-        meshRecords.push_back( record );
-      }
+      vert.mColor = underlineColor;
+
+      Toolkit::Internal::AtlasMeshFactory::AppendMesh( meshRecords[ index ].mMesh, newMesh );
     }
   }
 
@@ -739,16 +748,23 @@ Actor AtlasRenderer::Render( Text::ViewInterface& view, int depth )
     Vector<Vector2> positions;
     positions.Resize( numberOfGlyphs );
 
+    Vector<Vector4> colors;
+    colors.Resize( numberOfGlyphs, view.GetTextColor() );
+
     numberOfGlyphs = view.GetGlyphs( glyphs.Begin(),
                                      positions.Begin(),
+                                     colors.Begin(),
                                      0u,
                                      numberOfGlyphs );
+
     glyphs.Resize( numberOfGlyphs );
     positions.Resize( numberOfGlyphs );
+    colors.Resize( numberOfGlyphs );
 
     mImpl->AddGlyphs( view,
                       positions,
                       glyphs,
+                      colors,
                       depth );
 
     /* In the case where AddGlyphs does not create a renderable Actor for example when glyphs are all whitespace create a new Actor. */