Text Shadow Implementation via copied renderer. 65/49465/8
authorRichard Underhill <r.underhill@partner.samsung.com>
Thu, 15 Oct 2015 13:25:00 +0000 (14:25 +0100)
committerRichard Underhill <r.underhill@partner.samsung.com>
Thu, 15 Oct 2015 13:50:08 +0000 (14:50 +0100)
Change-Id: I1549e0b0c788b252ad176210f503c76397112e51
Signed-off-by: Richard Underhill <r.underhill@partner.samsung.com>
12 files changed:
dali-toolkit/internal/file.list
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h
dali-toolkit/internal/text/rendering/atlas/atlas-manager-impl.cpp [moved from dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp with 50% similarity]
dali-toolkit/internal/text/rendering/atlas/atlas-manager-impl.h [moved from dali-toolkit/internal/atlas-manager/atlas-manager-impl.h with 82% similarity]
dali-toolkit/internal/text/rendering/atlas/atlas-manager.cpp [moved from dali-toolkit/internal/atlas-manager/atlas-manager.cpp with 84% similarity]
dali-toolkit/internal/text/rendering/atlas/atlas-manager.h [moved from dali-toolkit/internal/atlas-manager/atlas-manager.h with 62% similarity]
dali-toolkit/internal/text/rendering/atlas/atlas-mesh-factory.cpp [new file with mode: 0644]
dali-toolkit/internal/text/rendering/atlas/atlas-mesh-factory.h [new file with mode: 0644]
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp

index 9ecd378..34d10cc 100644 (file)
@@ -1,8 +1,6 @@
 # Add local source files here
 
 toolkit_src_files = \
-   $(toolkit_src_dir)/atlas-manager/atlas-manager.cpp \
-   $(toolkit_src_dir)/atlas-manager/atlas-manager-impl.cpp \
    $(toolkit_src_dir)/builder/builder-actor.cpp \
    $(toolkit_src_dir)/builder/builder-animations.cpp \
    $(toolkit_src_dir)/builder/builder-impl.cpp \
@@ -99,6 +97,9 @@ toolkit_src_files = \
    $(toolkit_src_dir)/text/rendering/atlas/text-atlas-renderer.cpp \
    $(toolkit_src_dir)/text/rendering/atlas/atlas-glyph-manager.cpp \
    $(toolkit_src_dir)/text/rendering/atlas/atlas-glyph-manager-impl.cpp \
+   $(toolkit_src_dir)/text/rendering/atlas/atlas-manager.cpp \
+   $(toolkit_src_dir)/text/rendering/atlas/atlas-manager-impl.cpp \
+   $(toolkit_src_dir)/text/rendering/atlas/atlas-mesh-factory.cpp \
    $(toolkit_src_dir)/text/rendering/text-backend-impl.cpp \
    $(toolkit_src_dir)/transition-effects/cube-transition-effect-impl.cpp \
    $(toolkit_src_dir)/transition-effects/cube-transition-cross-effect-impl.cpp \
index 92c5b42..f2c328e 100644 (file)
@@ -20,8 +20,6 @@
 // EXTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
 
-#define MAKE_SHADER(A)#A
-
 namespace
 {
 
@@ -29,52 +27,42 @@ namespace
   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING");
 #endif
 
+#define MAKE_SHADER(A)#A
+
 const char* VERTEX_SHADER = MAKE_SHADER(
 attribute mediump vec2    aPosition;
 attribute mediump vec2    aTexCoord;
+uniform   mediump vec2    uOffset;
 uniform   mediump mat4    uMvpMatrix;
 varying   mediump vec2    vTexCoord;
 
 void main()
 {
-  mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
+  mediump vec4 position = vec4( aPosition.xy + uOffset, 0.0, 1.0 );
   gl_Position = uMvpMatrix * position;
   vTexCoord = aTexCoord;
 }
 );
 
-const char* FRAGMENT_SHADER = MAKE_SHADER(
+const char* FRAGMENT_SHADER_L8 = MAKE_SHADER(
+uniform lowp    vec4      uColor;
 uniform         sampler2D sTexture;
 varying mediump vec2      vTexCoord;
 
 void main()
 {
-  gl_FragColor = texture2D( sTexture, vTexCoord );
-}
-);
-
-const char* VERTEX_SHADER_SHADOW = MAKE_SHADER(
-attribute mediump vec2    aPosition;
-attribute mediump vec2    aTexCoord;
-varying   mediump vec2    vTexCoord;
-
-void main()
-{
-  mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
-  gl_Position = position;
-  vTexCoord = aTexCoord;
+  mediump vec4 color = texture2D( sTexture, vTexCoord );
+  gl_FragColor = vec4( uColor.rgb, uColor.a * color.r );
 }
 );
 
-const char* FRAGMENT_SHADER_SHADOW = MAKE_SHADER(
+const char* FRAGMENT_SHADER_RGBA = MAKE_SHADER(
 uniform         sampler2D sTexture;
-uniform lowp    vec4      uColor;
 varying mediump vec2      vTexCoord;
 
 void main()
 {
-  mediump vec4 color = texture2D( sTexture, vTexCoord );
-  gl_FragColor = vec4(uColor.rgb, uColor.a*color.r);
+  gl_FragColor = texture2D( sTexture, vTexCoord );
 }
 );
 
@@ -91,9 +79,9 @@ namespace Internal
 
 AtlasGlyphManager::AtlasGlyphManager()
 {
+  mShaderL8 = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_L8 );
+  mShaderRgba = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_RGBA );
   mAtlasManager = Dali::Toolkit::AtlasManager::New();
-  mEffectBufferShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
-  mShadowShader = Shader::New( VERTEX_SHADER_SHADOW, FRAGMENT_SHADER_SHADOW, Dali::Shader::HINT_MODIFIES_GEOMETRY );
 }
 
 void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
@@ -102,7 +90,16 @@ void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "Added glyph, font: %d index: %d\n", glyph.fontId, glyph.index );
 
-  mAtlasManager.Add( bitmap, slot );
+  if ( mAtlasManager.Add( bitmap, slot ) )
+  {
+    // A new atlas was created so set the material details for the atlas
+    Dali::Atlas atlas = mAtlasManager.GetAtlasContainer( slot.mAtlasId );
+    Pixel::Format pixelFormat = mAtlasManager.GetPixelFormat( slot.mAtlasId );
+    Material material = Material::New( pixelFormat == Pixel::L8 ? mShaderL8 : mShaderRgba );
+    material.AddTexture( atlas, "sTexture" );
+    material.SetBlendMode( BlendingMode::ON );
+    mAtlasManager.SetMaterial( slot.mAtlasId, material );
+  }
 
   GlyphRecordEntry record;
   record.mIndex = glyph.index;
@@ -140,13 +137,7 @@ void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
   mAtlasManager.GenerateMeshData( imageId, position, mesh, false );
 }
 
-void AtlasGlyphManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
-                                    const Toolkit::AtlasManager::Mesh2D& second )
-{
-  mAtlasManager.StitchMesh( first, second );
-}
-
-bool AtlasGlyphManager::Cached( Text::FontId fontId,
+bool AtlasGlyphManager::IsCached( Text::FontId fontId,
                                 Text::GlyphIndex index,
                                 Dali::Toolkit::AtlasManager::AtlasSlot& slot )
 {
@@ -263,11 +254,6 @@ Material AtlasGlyphManager::GetMaterial( uint32_t atlasId ) const
   return mAtlasManager.GetMaterial( atlasId );
 }
 
-Image AtlasGlyphManager::GetImage( uint32_t atlasId ) const
-{
-  return mAtlasManager.GetImage( atlasId );
-}
-
 AtlasGlyphManager::~AtlasGlyphManager()
 {
   // mAtlasManager handle is automatically released here
index da659bc..0c67501 100644 (file)
@@ -81,17 +81,11 @@ public:
                          Toolkit::AtlasManager::Mesh2D& mesh );
 
   /**
-   * @copydoc Toolkit::AtlasGlyphManager::StitchMesh
+   * @copydoc Toolkit::AtlasGlyphManager::IsCached
    */
-  void StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
-                   const Toolkit::AtlasManager::Mesh2D& second );
-
-  /**
-   * @copydoc Toolkit::AtlasGlyphManager::Cached
-   */
-  bool Cached( Text::FontId fontId,
-               Text::GlyphIndex index,
-               Dali::Toolkit::AtlasManager::AtlasSlot& slot );
+  bool IsCached( Text::FontId fontId,
+                 Text::GlyphIndex index,
+                 Dali::Toolkit::AtlasManager::AtlasSlot& slot );
 
   /**
    * @copydoc Toolkit::AtlasGlyphManager::GetAtlasSize
@@ -119,31 +113,10 @@ public:
   Material GetMaterial( uint32_t atlasId ) const;
 
   /**
-   * @copydoc Toolkit::AtlasGlyphManager::GetMaterial
-   */
-  Image GetImage( uint32_t atlasId ) const;
-
-  /**
    * @copydoc Toolkit::AtlasGlyphManager::GetMetrics
    */
   const Toolkit::AtlasGlyphManager::Metrics& GetMetrics();
 
-  /**
-   * @copydoc Toolkit::AtlasGlyphManager::GetEffectBufferShader
-   */
-  Shader GetEffectBufferShader() const
-  {
-    return mEffectBufferShader;
-  }
-
-  /**
-   * @copydoc Toolkit::AtlasGlyphManager::GetGlyphShadowShader
-   */
-  Shader GetGlyphShadowShader() const
-  {
-    return mShadowShader;
-  }
-
 protected:
 
   /**
@@ -156,8 +129,9 @@ private:
   Dali::Toolkit::AtlasManager mAtlasManager;          ///> Atlas Manager created by GlyphManager
   std::vector< FontGlyphRecord > mFontGlyphRecords;
   Toolkit::AtlasGlyphManager::Metrics mMetrics;       ///> Metrics to pass back on GlyphManager status
-  Shader mEffectBufferShader;                         ///> Shader used to render drop shadow buffer textures
-  Shader mShadowShader;                               ///> Shader used to render drop shadow into buffer
+
+  Shader mShaderL8;
+  Shader mShaderRgba;
 };
 
 } // namespace Internal
index 39ce202..5a46ef5 100644 (file)
@@ -84,17 +84,11 @@ void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
                                              mesh );
 }
 
-void AtlasGlyphManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
-                                    const Toolkit::AtlasManager::Mesh2D& second )
+bool AtlasGlyphManager::IsCached( Text::FontId fontId,
+                                  Text::GlyphIndex index,
+                                  AtlasManager::AtlasSlot& slot )
 {
-  GetImplementation(*this).StitchMesh( first, second );
-}
-
-bool AtlasGlyphManager::Cached( Text::FontId fontId,
-                                Text::GlyphIndex index,
-                                AtlasManager::AtlasSlot& slot )
-{
-  return GetImplementation(*this).Cached( fontId, index, slot );
+  return GetImplementation(*this).IsCached( fontId, index, slot );
 }
 
 void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight )
@@ -117,11 +111,6 @@ Material AtlasGlyphManager::GetMaterial( uint32_t atlasId ) const
   return GetImplementation(*this).GetMaterial( atlasId );
 }
 
-Image AtlasGlyphManager::GetImage( uint32_t atlasId ) const
-{
-  return GetImplementation(*this).GetImage( atlasId );
-}
-
 const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
 {
   return GetImplementation(*this).GetMetrics();
@@ -132,16 +121,6 @@ void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIn
   GetImplementation(*this).AdjustReferenceCount( fontId, index, delta );
 }
 
-Shader AtlasGlyphManager::GetEffectBufferShader() const
-{
-  return GetImplementation(*this).GetEffectBufferShader();
-}
-
-Shader AtlasGlyphManager::GetGlyphShadowShader() const
-{
-  return GetImplementation(*this).GetGlyphShadowShader();
-}
-
 } // namespace Toolkit
 
 } // namespace Dali
index 2deba24..1870bd5 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/internal/atlas-manager/atlas-manager.h>
+#include <dali-toolkit/internal/text/rendering/atlas/atlas-manager.h>
 #include <dali-toolkit/internal/text/text-definitions.h>
 
 namespace Dali
@@ -99,15 +99,6 @@ public:
                          Toolkit::AtlasManager::Mesh2D& mesh );
 
   /**
-   * @brief Stitch Two Meshes together
-   *
-   * @param[in] first first mesh
-   * @param[in] second second mesh
-   */
-  void StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
-                   const Toolkit::AtlasManager::Mesh2D& second );
-
-  /**
    * @brief Check to see if a glyph is being cached
    *
    * @param[in] fontId The font that this glyph comes from
@@ -116,9 +107,9 @@ public:
    *
    * @return Whether glyph is cached or not ?
    */
-  bool Cached( Text::FontId fontId,
-               Text::GlyphIndex index,
-               AtlasManager::AtlasSlot& slot );
+  bool IsCached( Text::FontId fontId,
+                 Text::GlyphIndex index,
+                 AtlasManager::AtlasSlot& slot );
 
   /**
    * @brief Retrieve the size of an atlas
@@ -158,15 +149,6 @@ public:
   Material GetMaterial( uint32_t atlasId ) const;
 
   /**
-   * @brief Get the sampler used by an atlas
-   *
-   * @param[in] atlasId Id of an atlas
-   *
-   * @return The sampler used by the atlas
-   */
-  Image GetImage( uint32_t atlasId ) const;
-
-  /**
    * @brief Get Glyph Manager metrics
    *
    * @return const reference to glyph manager metrics
@@ -182,20 +164,6 @@ public:
    */
   void AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta );
 
-  /**
-   * @brief Get Shader used for rendering glyph effect buffers
-   *
-   * @return Handle of shader needed
-   */
-  Shader GetEffectBufferShader() const;
-
-  /**
-   * @brief Get Shader used rendering Glyph Shadows
-   *
-   * @return Handle of shader needed
-   */
-  Shader GetGlyphShadowShader() const;
-
 private:
 
   explicit DALI_INTERNAL AtlasGlyphManager(Internal::AtlasGlyphManager *impl);
  */
 
 // CLASS HEADER
-#include <dali-toolkit/internal/atlas-manager/atlas-manager-impl.h>
+#include <dali-toolkit/internal/text/rendering/atlas/atlas-manager-impl.h>
 
-// EXTERNAL INCLUDE
-#include <iostream>
+// EXTERNAL INCLUDES
 #include <string.h>
-#include <dali/devel-api/rendering/sampler.h>
-#include <dali/devel-api/rendering/shader.h>
 #include <dali/integration-api/debug.h>
 
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/rendering/atlas/atlas-mesh-factory.h>
+
 namespace Dali
 {
 
@@ -43,45 +43,6 @@ namespace
   const uint32_t DOUBLE_PIXEL_PADDING( SINGLE_PIXEL_PADDING << 1 );
   const uint32_t FILLED_PIXEL( -1 );
   Toolkit::AtlasManager::AtlasSize EMPTY_SIZE;
-
-  #define MAKE_SHADER(A)#A
-
-  const char* VERTEX_SHADER = MAKE_SHADER(
-  attribute mediump vec2    aPosition;
-  attribute mediump vec2    aTexCoord;
-  uniform   mediump mat4    uMvpMatrix;
-  varying   mediump vec2    vTexCoord;
-
-  void main()
-  {
-    mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
-    gl_Position = uMvpMatrix * position;
-    vTexCoord = aTexCoord;
-  }
-  );
-
-  const char* FRAGMENT_SHADER_L8 = MAKE_SHADER(
-  uniform lowp    vec4      uColor;
-  uniform         sampler2D sTexture;
-  varying mediump vec2      vTexCoord;
-
-  void main()
-  {
-    mediump vec4 color = texture2D( sTexture, vTexCoord );
-    gl_FragColor = vec4( uColor.rgb, uColor.a * color.r );
-  }
-  );
-
-  const char* FRAGMENT_SHADER_RGBA = MAKE_SHADER(
-  uniform         sampler2D sTexture;
-  varying mediump vec2      vTexCoord;
-
-  void main()
-  {
-    gl_FragColor = texture2D( sTexture, vTexCoord );
-  }
-  );
-
 }
 
 AtlasManager::AtlasManager()
@@ -91,8 +52,6 @@ AtlasManager::AtlasManager()
   mNewAtlasSize.mHeight = DEFAULT_ATLAS_HEIGHT;
   mNewAtlasSize.mBlockWidth = DEFAULT_BLOCK_WIDTH;
   mNewAtlasSize.mBlockHeight = DEFAULT_BLOCK_HEIGHT;
-  mShaderL8 = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_L8 );
-  mShaderRgba = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_RGBA );
 }
 
 AtlasManagerPtr AtlasManager::New()
@@ -158,11 +117,6 @@ Toolkit::AtlasManager::AtlasId AtlasManager::CreateAtlas( const Toolkit::AtlasMa
 
   memset( buffer, 0xFF, filledPixelImage.GetBufferSize() );
   atlas.Upload( filledPixelImage, 0, 0 );
-
-  atlasDescriptor.mMaterial = Material::New( pixelformat == Pixel::L8 ? mShaderL8 : mShaderRgba );
-  atlasDescriptor.mMaterial.AddTexture(atlas, "sTexture" );
-  atlasDescriptor.mImage = atlas;
-  atlasDescriptor.mMaterial.SetBlendMode( BlendingMode::ON );
   mAtlasList.push_back( atlasDescriptor );
   return mAtlasList.size();
 }
@@ -172,16 +126,14 @@ void AtlasManager::SetAddPolicy( Toolkit::AtlasManager::AddFailPolicy policy )
   mAddFailPolicy = policy;
 }
 
-void AtlasManager::Add( const BufferImage& image,
+bool AtlasManager::Add( const BufferImage& image,
                         Toolkit::AtlasManager::AtlasSlot& slot,
                         Toolkit::AtlasManager::AtlasId atlas )
 {
-  // See if there's a slot in an atlas that matches the requirements of this image
-  // A bitmap must be sliceable into a single atlas
+  bool created = false;
   Pixel::Format pixelFormat = image.GetPixelFormat();
   SizeType width = image.GetWidth();
   SizeType height = image.GetHeight();
-  SizeType blockArea = 0;
   SizeType foundAtlas = 0;
   SizeType index = 0;
   slot.mImageId = 0;
@@ -191,13 +143,13 @@ void AtlasManager::Add( const BufferImage& image,
   // If there is a preferred atlas then check for room in that first
   if ( atlas-- )
   {
-    foundAtlas = CheckAtlas( atlas, width, height, pixelFormat, blockArea );
+    foundAtlas = CheckAtlas( atlas, width, height, pixelFormat );
   }
 
   // Search current atlases to see if there is a good match
   while( !foundAtlas && index < mAtlasList.size() )
   {
-    foundAtlas = CheckAtlas( index, width, height, pixelFormat, blockArea );
+    foundAtlas = CheckAtlas( index, width, height, pixelFormat );
     ++index;
   }
 
@@ -214,35 +166,32 @@ void AtlasManager::Add( const BufferImage& image,
                        mNewAtlasSize.mHeight,
                        mNewAtlasSize.mBlockWidth,
                        mNewAtlasSize.mBlockHeight );
-        return;
+        return created;
       }
-
-      foundAtlas = CheckAtlas( foundAtlas, width, height, pixelFormat, blockArea );
+      created = true;
+      foundAtlas = CheckAtlas( foundAtlas, width, height, pixelFormat );
     }
 
     if ( !foundAtlas-- || Toolkit::AtlasManager::FAIL_ON_ADD_FAILS == mAddFailPolicy )
     {
       // Haven't found an atlas for this image!!!!!!
       DALI_LOG_ERROR("Failed to create an atlas under current policy.\n");
-      return;
+      return created;
     }
   }
 
-  // Work out where the blocks are we're going to use
-  for ( SizeType i = 0; i < blockArea; ++i )
+  // Work out which the block we're going to use
+  // Is there currently a next free block available ?
+  if ( mAtlasList[ foundAtlas ].mAvailableBlocks )
   {
-    // Is there currently a next free block available ?
-    if ( mAtlasList[ foundAtlas ].mAvailableBlocks )
-    {
-      // Yes, so select our next block
-      desc.mBlocksList.PushBack( mAtlasList[ foundAtlas ].mTotalBlocks - mAtlasList[ foundAtlas ].mAvailableBlocks-- );
-    }
-    else
-    {
-      // Our next block must be from the free list, fetch from the start of the list
-      desc.mBlocksList.PushBack( mAtlasList[ foundAtlas ].mFreeBlocksList[ 0 ] );
-      mAtlasList[ foundAtlas ].mFreeBlocksList.Remove( mAtlasList[ foundAtlas ].mFreeBlocksList.Begin() );
-    }
+    // Yes, so select our next block
+    desc.mBlock = mAtlasList[ foundAtlas ].mTotalBlocks - mAtlasList[ foundAtlas ].mAvailableBlocks--;
+  }
+  else
+  {
+    // Our next block must be from the free list, fetch from the start of the list
+    desc.mBlock = mAtlasList[ foundAtlas ].mFreeBlocksList[ 0 ];
+    mAtlasList[ foundAtlas ].mFreeBlocksList.Remove( mAtlasList[ foundAtlas ].mFreeBlocksList.Begin() );
   }
 
   desc.mImageWidth = width;
@@ -252,7 +201,7 @@ void AtlasManager::Add( const BufferImage& image,
 
   // See if there's a previously freed image ID that we can assign to this new image
   uint32_t imageId = 0u;
-  for ( uint32_t i = 0u; i < mImageList.size(); ++i )
+  for ( uint32_t i = 0u; i < mImageList.Size(); ++i )
   {
     if ( !mImageList[ i ].mCount )
     {
@@ -262,8 +211,8 @@ void AtlasManager::Add( const BufferImage& image,
   }
   if ( !imageId )
   {
-    mImageList.push_back( desc );
-    slot.mImageId = mImageList.size();
+    mImageList.PushBack( desc );
+    slot.mImageId = mImageList.Size();
   }
   else
   {
@@ -271,15 +220,18 @@ void AtlasManager::Add( const BufferImage& image,
     slot.mImageId = imageId;
   }
   slot.mAtlasId = foundAtlas + 1u;
+
+  // Upload the buffer image into the atlas
   UploadImage( image, desc );
+  return created;
 }
 
 AtlasManager::SizeType AtlasManager::CheckAtlas( SizeType atlas,
                                                  SizeType width,
                                                  SizeType height,
-                                                 Pixel::Format pixelFormat,
-                                                 SizeType& blockArea )
+                                                 Pixel::Format pixelFormat )
 {
+  AtlasManager::SizeType result = 0u;
   if ( pixelFormat == mAtlasList[ atlas ].mPixelFormat )
   {
     // Check to see if the image will fit in these blocks, if not we'll need to create a new atlas
@@ -287,254 +239,10 @@ AtlasManager::SizeType AtlasManager::CheckAtlas( SizeType atlas,
            && width + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mSize.mBlockWidth
            && height + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mSize.mBlockHeight )
     {
-      blockArea = 1u;
-      return ( atlas + 1u );
+      result = atlas + 1u;
     }
   }
-  return 0u;
-}
-
-void AtlasManager::CreateMesh( SizeType atlas,
-                               SizeType imageWidth,
-                               SizeType imageHeight,
-                               const Vector2& position,
-                               SizeType widthInBlocks,
-                               SizeType heightInBlocks,
-                               Toolkit::AtlasManager::Mesh2D& mesh,
-                               AtlasSlotDescriptor& desc )
-{
-  Toolkit::AtlasManager::Vertex2D vertex;
-  uint32_t faceIndex = 0;       // TODO change to unsigned short when property type is available
-
-  SizeType blockWidth = mAtlasList[ atlas ].mSize.mBlockWidth;
-  SizeType blockHeight = mAtlasList[ atlas ].mSize.mBlockHeight;
-
-  float vertexBlockWidth = static_cast< float >( blockWidth );
-  float vertexBlockHeight = static_cast< float >( blockHeight );
-
-  SizeType width = mAtlasList[ atlas ].mSize.mWidth;
-  SizeType height = mAtlasList[ atlas ].mSize.mHeight;
-
-  SizeType atlasWidthInBlocks = ( width - 1u ) / blockWidth;
-
-  // Get the normalized size of a texel in both directions
-  // TODO when texture resizing and passing texture size via uniforms is available,
-  //      we will encode pixel positions into the vertex data rather than normalized
-  //      meaning that geometry needn't be changed on an atlas resize
-  float texelX = 1.0f / static_cast< float >( width );
-  float texelY = 1.0f / static_cast< float >( height );
-
-  float oneAndAHalfTexelX = texelX + ( texelX * 0.5f );
-  float oneAndAHalfTexelY = texelY + ( texelY * 0.5f );
-
-  // Get the normalized size of a block in texels
-  float texelBlockWidth = texelX * vertexBlockWidth;
-  float texelBlockHeight = texelY * vertexBlockHeight;
-
-  // Get partial block space
-  float vertexEdgeWidth = static_cast< float >( imageWidth % blockWidth );
-  float vertexEdgeHeight = static_cast< float >( imageHeight % blockHeight );
-
-  // And in texels
-  float texelEdgeWidth = texelX * vertexEdgeWidth;
-  float texelEdgeHeight = texelY * vertexEdgeHeight;
-
-  // We're going to 'blit' half a pixel more on each edge
-  vertexBlockWidth++;
-  vertexEdgeWidth++;
-  vertexBlockHeight++;
-  vertexEdgeHeight++;
-
-   // Block by block create the two triangles for the quad
-  SizeType blockIndex = 0;
-  float ndcWidth;
-  float ndcHeight;
-  float ndcVWidth;
-  float ndcVHeight;
-
-  // Move back half a pixel
-  Vector2 topLeft = Vector2( position.x - 0.5f, position.y - 0.5f );
-
-  for ( SizeType y = 0; y < heightInBlocks; ++y )
-  {
-
-    float currentX = position.x;
-
-    if ( ( heightInBlocks - 1u ) == y && vertexEdgeHeight > 0.0f )
-    {
-      ndcHeight = texelEdgeHeight + texelY;
-      ndcVHeight = vertexEdgeHeight;
-    }
-    else
-    {
-      ndcHeight = texelBlockHeight + texelY;
-      ndcVHeight = vertexBlockHeight;
-    }
-
-    for ( SizeType x = 0; x < widthInBlocks; ++x )
-    {
-      SizeType block = desc.mBlocksList[ blockIndex++ ];
-
-      float fBlockX = texelBlockWidth * static_cast< float >( block % atlasWidthInBlocks );
-      float fBlockY = texelBlockHeight * static_cast< float >( block / atlasWidthInBlocks );
-
-      // Add on texture filtering compensation ( half a texel plus compensation for filled pixel in top left corner )
-      fBlockX += oneAndAHalfTexelX;
-      fBlockY += oneAndAHalfTexelY;
-
-      if (  ( widthInBlocks - 1u ) == x && vertexEdgeWidth > 0.0f )
-      {
-        ndcWidth = texelEdgeWidth + texelX;
-        ndcVWidth = vertexEdgeWidth;
-      }
-      else
-      {
-        ndcWidth = texelBlockWidth + texelX;
-        ndcVWidth = vertexBlockWidth;
-      }
-
-      // Top left
-      vertex.mPosition.x = topLeft.x;
-      vertex.mPosition.y = topLeft.y;
-      vertex.mTexCoords.x = fBlockX;
-      vertex.mTexCoords.y = fBlockY;
-
-      mesh.mVertices.PushBack( vertex );
-
-      // Top Right
-      vertex.mPosition.x = topLeft.x + ndcVWidth;
-      vertex.mPosition.y = topLeft.y;
-      vertex.mTexCoords.x = fBlockX + ndcWidth;
-      vertex.mTexCoords.y = fBlockY;
-
-      mesh.mVertices.PushBack( vertex );
-
-      // Bottom Left
-      vertex.mPosition.x = topLeft.x;
-      vertex.mPosition.y = topLeft.y + ndcVHeight;
-      vertex.mTexCoords.x = fBlockX;
-      vertex.mTexCoords.y = fBlockY + ndcHeight;
-
-      mesh.mVertices.PushBack( vertex );
-
-      // Bottom Right
-      topLeft.x += ndcVWidth;
-      vertex.mPosition.x = topLeft.x;
-      vertex.mPosition.y = topLeft.y + ndcVHeight;
-      vertex.mTexCoords.x = fBlockX + ndcWidth;
-      vertex.mTexCoords.y = fBlockY + ndcHeight;
-
-      mesh.mVertices.PushBack( vertex );
-
-      // Six indices in counter clockwise winding
-      mesh.mIndices.PushBack( faceIndex + 1u );
-      mesh.mIndices.PushBack( faceIndex );
-      mesh.mIndices.PushBack( faceIndex + 2u );
-      mesh.mIndices.PushBack( faceIndex + 2u );
-      mesh.mIndices.PushBack( faceIndex + 3u );
-      mesh.mIndices.PushBack( faceIndex + 1u );
-      faceIndex += 4;
-    }
-
-    // Move down a row
-    topLeft.x = currentX;
-    topLeft.y += vertexBlockHeight;
-  }
-
-  // If there's only one block then skip this next vertex optimisation
-  if ( widthInBlocks * heightInBlocks > 1 )
-  {
-    Toolkit::AtlasManager::Mesh2D optimizedMesh;
-    OptimizeMesh( mesh, optimizedMesh );
-  }
-}
-
-void AtlasManager::PrintMeshData( const Toolkit::AtlasManager::Mesh2D& mesh )
-{
-  uint32_t vertexCount = mesh.mVertices.Size();
-  uint32_t indexCount = mesh.mIndices.Size();
-  std::cout << "\nMesh Data for Image: VertexCount = " << vertexCount;
-  std::cout << ", Triangles = " << indexCount / 3 << std::endl;
-
-  for ( SizeType v = 0; v < vertexCount; ++v )
-  {
-    std::cout << " Vertex(" << v << ") x = " << mesh.mVertices[v].mPosition.x << ", ";
-    std::cout << "y = " << mesh.mVertices[v].mPosition.y << ", ";
-    std::cout << "u = " << mesh.mVertices[v].mTexCoords.x << ", ";
-    std::cout << "v = " << mesh.mVertices[v].mTexCoords.y << std::endl;
-  }
-
-  std::cout << "\n Indices: ";
-  for ( SizeType i = 0; i < indexCount; ++i )
-  {
-    std::cout << " " << mesh.mIndices[ i ];
-  }
-  std::cout << std::endl;
-}
-
-void AtlasManager::OptimizeMesh( const Toolkit::AtlasManager::Mesh2D& in,
-                                 Toolkit::AtlasManager::Mesh2D& out )
-{
-  unsigned short vertexIndex = 0;
-
-  // We could check to see if blocks are next to each other, but it's probably just as quick to compare verts
-  for ( SizeType i = 0; i < in.mIndices.Size(); ++i )
-  {
-    // Fetch a vertex, has it already been assigned?
-    bool foundVertex = false;
-    Toolkit::AtlasManager::Vertex2D v = in.mVertices[ in.mIndices[ i ] ];
-    for ( SizeType j = 0; j < out.mVertices.Size(); ++j )
-    {
-      if ( ( fabsf( v.mPosition.x - out.mVertices[ j ].mPosition.x ) < Math::MACHINE_EPSILON_1000 ) &&
-           ( fabsf( v.mPosition.y - out.mVertices[ j ].mPosition.y ) < Math::MACHINE_EPSILON_1000 ) &&
-           ( fabsf( v.mTexCoords.x - out.mVertices[ j ].mTexCoords.x ) < Math::MACHINE_EPSILON_1000 ) &&
-           ( fabsf( v.mTexCoords.y - out.mVertices[ j ].mTexCoords.y ) < Math::MACHINE_EPSILON_1000 ) )
-      {
-        // Yes, so store this down as the vertex to use
-        out.mIndices.PushBack( j );
-        foundVertex = true;
-        break;
-      }
-    }
-
-    // Did we find a vertex ?
-    if ( !foundVertex )
-    {
-      // No so add a new one
-      out.mVertices.PushBack( v );
-      vertexIndex++;
-    }
-  }
-}
-
-void AtlasManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
-                               const Toolkit::AtlasManager::Mesh2D& second,
-                               bool optimize )
-{
-  const uint32_t verticesCount = first.mVertices.Size();
-  first.mVertices.Insert( first.mVertices.End(),
-                          second.mVertices.Begin(),
-                          second.mVertices.End() );
-
-  const uint32_t indicesCount = first.mIndices.Size();
-  first.mIndices.Insert( first.mIndices.End(),
-                         second.mIndices.Begin(),
-                         second.mIndices.End() );
-
-  for( Vector<unsigned int>::Iterator it = first.mIndices.Begin() + indicesCount,
-         endIt = first.mIndices.End();
-       it != endIt;
-       ++it )
-  {
-    *it += verticesCount;
-  }
-
-  if ( optimize )
-  {
-    Toolkit::AtlasManager::Mesh2D optimizedMesh;
-    OptimizeMesh( first, optimizedMesh );
-    first = optimizedMesh;
-  }
+  return result;
 }
 
 void AtlasManager::UploadImage( const BufferImage& image,
@@ -554,9 +262,8 @@ void AtlasManager::UploadImage( const BufferImage& image,
   SizeType atlasBlockHeight = mAtlasList[ atlas ].mSize.mBlockHeight;
   SizeType atlasWidthInBlocks = ( mAtlasList[ atlas ].mSize.mWidth - 1u ) / mAtlasList[ atlas ].mSize.mBlockWidth;
 
-  SizeType block = desc.mBlocksList[ 0 ];
-  SizeType blockX = block % atlasWidthInBlocks;
-  SizeType blockY = block / atlasWidthInBlocks;
+  SizeType blockX = desc.mBlock % atlasWidthInBlocks;
+  SizeType blockY = desc.mBlock / atlasWidthInBlocks;
   SizeType blockOffsetX = ( blockX * atlasBlockWidth ) + 1u;
   SizeType blockOffsetY = ( blockY * atlasBlockHeight) + 1u;
 
@@ -623,18 +330,12 @@ void AtlasManager::GenerateMeshData( ImageId id,
     SizeType width = mImageList[ imageId ].mImageWidth;
     SizeType height = mImageList[ imageId ].mImageHeight;
 
-    SizeType widthInBlocks = width / mAtlasList[ atlas ].mSize.mBlockWidth;
-    if ( width % mAtlasList[ atlas ].mSize.mBlockWidth )
-    {
-      widthInBlocks++;
-    }
-    SizeType heightInBlocks = height / mAtlasList[ atlas ].mSize.mBlockHeight;
-    if ( height % mAtlasList[ atlas ].mSize.mBlockHeight )
-    {
-      heightInBlocks++;
-    }
-
-    CreateMesh( atlas, width, height, position, widthInBlocks, heightInBlocks, meshData, mImageList[ imageId ] );
+    AtlasMeshFactory::CreateQuad( width,
+                                  height,
+                                  mImageList[ imageId ].mBlock,
+                                  mAtlasList[ atlas ].mSize,
+                                  position,
+                                  meshData );
 
     // Mesh created so increase the reference count, if we're asked to
     if ( addReference )
@@ -650,14 +351,13 @@ void AtlasManager::GenerateMeshData( ImageId id,
 
 Dali::Atlas AtlasManager::GetAtlasContainer( AtlasId atlas ) const
 {
-  Dali::Atlas null;
-  if ( !atlas || atlas > mAtlasList.size( ) )
+  DALI_ASSERT_DEBUG( atlas && atlas <= mAtlasList.size() );
+  Dali::Atlas atlasContainer;
+  if ( atlas && atlas-- <= mAtlasList.size() )
   {
-
-    DALI_LOG_ERROR("Cannot get Atlas from AtlasID ( doesn't exist ).\n");
-    return null;
+    atlasContainer = mAtlasList[ atlas ].mAtlas;
   }
-  return mAtlasList[ atlas -1u ].mAtlas;
+  return atlasContainer;
 }
 
 bool AtlasManager::Remove( ImageId id )
@@ -666,7 +366,7 @@ bool AtlasManager::Remove( ImageId id )
   SizeType imageId = id - 1u;
   bool removed = false;
 
-  if ( id > mImageList.size() )
+  if ( id > mImageList.Size() )
      {
     DALI_LOG_ERROR("Atlas was asked to free an invalid imageID: %i\n", id );
     return false;
@@ -685,24 +385,20 @@ bool AtlasManager::Remove( ImageId id )
     removed = true;
     mImageList[ imageId ].mCount = 0;
     SizeType atlas = mImageList[ imageId ].mAtlasId - 1u;
-    for ( uint32_t i = 0; i < mImageList[ imageId ].mBlocksList.Size(); ++i )
-    {
-      mAtlasList[ atlas ].mFreeBlocksList.PushBack( mImageList[ imageId ].mBlocksList[ i ] );
-    }
+    mAtlasList[ atlas ].mFreeBlocksList.PushBack( mImageList[ imageId ].mBlock );
   }
   return removed;
 }
 
 AtlasManager::AtlasId AtlasManager::GetAtlas( ImageId id ) const
 {
-  if ( id && id <= mImageList.size() )
-  {
-    return mImageList[ id - 1u ].mAtlasId;
-  }
-  else
+  DALI_ASSERT_DEBUG( id && id <= mImageList.Size() );
+  AtlasManager::AtlasId atlasId = 0u;
+  if ( id && id-- <= mImageList.Size() )
   {
-    return 0;
+    atlasId = mImageList[ id ].mAtlasId;
   }
+  return atlasId;
 }
 
 void AtlasManager::SetNewAtlasSize( const Toolkit::AtlasManager::AtlasSize& size )
@@ -716,6 +412,7 @@ void AtlasManager::SetNewAtlasSize( const Toolkit::AtlasManager::AtlasSize& size
 
 const Toolkit::AtlasManager::AtlasSize& AtlasManager::GetAtlasSize( AtlasId atlas )
 {
+  DALI_ASSERT_DEBUG( atlas && atlas <= mAtlasList.size() );
   if ( atlas && atlas-- <= mAtlasList.size() )
   {
     return mAtlasList[ atlas ].mSize;
@@ -725,14 +422,13 @@ const Toolkit::AtlasManager::AtlasSize& AtlasManager::GetAtlasSize( AtlasId atla
 
 AtlasManager::SizeType AtlasManager::GetFreeBlocks( AtlasId atlas ) const
 {
+  DALI_ASSERT_DEBUG( atlas && atlas <= mAtlasList.size() );
+  AtlasManager::SizeType freeBlocks = 0u;
   if ( atlas && atlas-- <= mAtlasList.size() )
   {
-    return ( mAtlasList[ atlas ].mAvailableBlocks + mAtlasList[ atlas ].mFreeBlocksList.Size() );
-  }
-  else
-  {
-    return 0;
+    freeBlocks = mAtlasList[ atlas ].mAvailableBlocks + mAtlasList[ atlas ].mFreeBlocksList.Size();
   }
+  return freeBlocks;
 }
 
 AtlasManager::SizeType AtlasManager::GetAtlasCount() const
@@ -742,13 +438,13 @@ AtlasManager::SizeType AtlasManager::GetAtlasCount() const
 
 Pixel::Format AtlasManager::GetPixelFormat( AtlasId atlas )
 {
-  if ( !atlas || atlas > mAtlasList.size( ) )
+  DALI_ASSERT_DEBUG( atlas && atlas <= mAtlasList.size() );
+  Pixel::Format pixelFormat = Pixel::RGBA8888;
+  if ( atlas && atlas-- <= mAtlasList.size() )
   {
-
-    DALI_LOG_ERROR("Cannot get Atlas from AtlasID ( doesn't exist ).\n");
-    return Pixel::L8;
+    pixelFormat = mAtlasList[ atlas ].mPixelFormat;
   }
-  return mAtlasList[ --atlas].mPixelFormat;
+  return pixelFormat;
 }
 
 void AtlasManager::GetMetrics( Toolkit::AtlasManager::Metrics& metrics )
@@ -782,22 +478,22 @@ void AtlasManager::GetMetrics( Toolkit::AtlasManager::Metrics& metrics )
 
 Material AtlasManager::GetMaterial( AtlasId atlas ) const
 {
+  DALI_ASSERT_DEBUG( atlas && atlas <= mAtlasList.size() );
+  Material material;
   if ( atlas && atlas-- <= mAtlasList.size() )
   {
-    return mAtlasList[ atlas ].mMaterial;
+    material = mAtlasList[ atlas ].mMaterial;
   }
-  Material null;
-  return null;
+  return material;
 }
 
-Image AtlasManager::GetImage( AtlasId atlas ) const
+void AtlasManager::SetMaterial( AtlasId atlas, Material& material )
 {
+  DALI_ASSERT_DEBUG( atlas && atlas <= mAtlasList.size() );
   if ( atlas && atlas-- <= mAtlasList.size() )
   {
-    return mAtlasList[ atlas ].mImage;
+    mAtlasList[ atlas ].mMaterial = material;
   }
-  Image null;
-  return null;
 }
 
 } // namespace Internal
@@ -23,7 +23,7 @@
 #include <dali/public-api/object/base-object.h>
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/internal/atlas-manager/atlas-manager.h>
+#include <dali-toolkit/internal/text/rendering/atlas/atlas-manager.h>
 
 namespace Dali
 {
@@ -65,7 +65,6 @@ public:
     BufferImage mHorizontalStrip;                                       // Image used to pad upload
     BufferImage mVerticalStrip;                                         // Image used to pad upload
     Material mMaterial;                                                 // material used for atlas texture
-    Image mImage;
     SizeType mTotalBlocks;                                              // total number of blocks in atlas
     SizeType mAvailableBlocks;                                          // number of blocks available in atlas
     Dali::Vector< SizeType > mFreeBlocksList;                           // unless there are any previously freed blocks
@@ -77,7 +76,7 @@ public:
     SizeType mImageWidth;                                               // Width of image stored
     SizeType mImageHeight;                                              // Height of image stored
     AtlasId mAtlasId;                                                   // Image is stored in this Atlas
-    Dali::Vector< SizeType > mBlocksList;                               // List of blocks within atlas used for image
+    SizeType mBlock;                                                    // Block within atlas used for image
   };
 
   AtlasManager();
@@ -102,7 +101,7 @@ public:
   /**
    * @copydoc Toolkit::AtlasManager::Add
    */
-  void Add( const BufferImage& image,
+  bool Add( const BufferImage& image,
             Toolkit::AtlasManager::AtlasSlot& slot,
             Toolkit::AtlasManager::AtlasId atlas );
 
@@ -115,13 +114,6 @@ public:
                          bool addReference );
 
   /**
-   * @copydoc Toolkit::AtlasManager::StitchMesh
-   */
-  void StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
-                   const Toolkit::AtlasManager::Mesh2D& second,
-                   bool optimize );
-
-  /**
    * @copydoc Toolkit::AtlasManager::Remove
    */
   bool Remove( ImageId id );
@@ -176,44 +168,26 @@ public:
    */
   Material GetMaterial( AtlasId atlas ) const;
 
-/**
-   * @copydoc Toolkit::AtlasManager::GetImage
+  /**
+   * @copydoc Toolkit::AtlasManager::SetMaterial
    */
-  Image GetImage( AtlasId atlas ) const;
+  void SetMaterial( AtlasId atlas, Material& material );
 
 private:
 
   std::vector< AtlasDescriptor > mAtlasList;            // List of atlases created
-  std::vector< AtlasSlotDescriptor > mImageList;        // List of bitmaps store in atlases
+  Vector< AtlasSlotDescriptor > mImageList;             // List of bitmaps stored in atlases
   Toolkit::AtlasManager::AtlasSize mNewAtlasSize;       // Atlas size to use in next creation
   Toolkit::AtlasManager::AddFailPolicy mAddFailPolicy;  // Policy for faling to add an Image
 
   SizeType CheckAtlas( SizeType atlas,
                        SizeType width,
                        SizeType height,
-                       Pixel::Format pixelFormat,
-                       SizeType& blockArea );
-
-  void CreateMesh( SizeType atlas,
-                   SizeType imageWidth,
-                   SizeType imageHeight,
-                   const Vector2& position,
-                   SizeType widthInBlocks,
-                   SizeType heightInBlocks,
-                   Toolkit::AtlasManager::Mesh2D& mesh,
-                   AtlasSlotDescriptor& desc );
-
-  void OptimizeMesh( const Toolkit::AtlasManager::Mesh2D& in,
-                     Toolkit::AtlasManager::Mesh2D& out );
+                       Pixel::Format pixelFormat );
 
   void UploadImage( const BufferImage& image,
                     const AtlasSlotDescriptor& desc );
 
-  void PrintMeshData( const Toolkit::AtlasManager::Mesh2D& mesh );
-
-  Shader mShaderL8;
-  Shader mShaderRgba;
-
 };
 
 } // namespace Internal
  */
 
 // CLASS HEADER
-#include <dali-toolkit/internal/atlas-manager/atlas-manager.h>
+#include <dali-toolkit/internal/text/rendering/atlas/atlas-manager.h>
 
- // INTERNAL INCLUDES
-#include <dali-toolkit/internal/atlas-manager/atlas-manager-impl.h>
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/rendering/atlas/atlas-manager-impl.h>
 
 namespace Dali
 {
@@ -55,11 +55,11 @@ void AtlasManager::SetAddPolicy( AddFailPolicy policy )
   GetImplementation(*this).SetAddPolicy( policy );
 }
 
-void AtlasManager::Add( const BufferImage& image,
+bool AtlasManager::Add( const BufferImage& image,
                         AtlasManager::AtlasSlot& slot,
                         AtlasManager::AtlasId atlas )
 {
-  GetImplementation(*this).Add( image, slot, atlas );
+  return GetImplementation(*this).Add( image, slot, atlas );
 }
 
 bool AtlasManager::Remove( ImageId id )
@@ -78,13 +78,6 @@ void AtlasManager::GenerateMeshData( ImageId id,
                                              addReference );
 }
 
-void AtlasManager::StitchMesh( Mesh2D& first,
-                               const Mesh2D& second,
-                               bool optimize )
-{
-  GetImplementation(*this).StitchMesh( first, second, optimize );
-}
-
 Dali::Atlas AtlasManager::GetAtlasContainer( AtlasId atlas ) const
 {
   return GetImplementation(*this).GetAtlasContainer( atlas );
@@ -130,9 +123,9 @@ Material AtlasManager::GetMaterial( AtlasId atlas ) const
   return GetImplementation(*this).GetMaterial( atlas );
 }
 
-Image AtlasManager::GetImage( AtlasId atlas ) const
+void AtlasManager::SetMaterial( AtlasId atlas, Material& material )
 {
-  return GetImplementation(*this).GetImage( atlas );
+  GetImplementation(*this).SetMaterial( atlas, material );
 }
 
 } // namespace Toolkit
@@ -37,120 +37,6 @@ class AtlasManager;
 
 } // namespace Internal
 
-/**
- * AtlasManager
- * ------------
- *
- * Creates and manages additions and removals of images from Texture Atlases
- *
- * The AtlasManager will match pixeltype and optimal block use to determine
- * the appropriate atlas to upload an image to.
- *
- * A policy can be specified to determine the action the AtlasManager will carry
- * out, should it not be able to add an image. This can return an error, or create
- * a new atlas of pre-determined dimensions to accomodate the new image.
- *
- * Images are referenced by an ImageId once they have been successfully uploaded.
- *
- * Once an image has been successfully uploaded, Geometry can be generated by passing
- * the ImageId to the GenerateMeshData method and geometry can be consolidated via
- * the StitchMesh method.
- *
- * Images are reference counted once mesh data has been generated. An image is removed
- * from the Atlas via the Remove( ImageId ) method. This unreferences the image and only
- * physically removes it from the atlas once all references have been freed.
- *
- * If the AddPolicy is set to generate and error if an image can't be uploaded, then it
- * is the applications responsibility to deal with the situation. An error will be indicated
- * with an ImageId of 0.
- *
- * Examples using the AtlasManager
- *
- * Create or obtain the AtlasManager
- * @code
- *
- * AtlasManager manager = AtlasManager::Get();
- *
- * @endcode
- *
- * Set the AtlasManager AddPolicy
- *
- * @code
- *
- * // Tell the atlas manager to create a new atlas, if it needs to
- * manager.SetAddPolicy( FAIL_ON_ADD_CREATES );
- *
- * // Tell the atlas manager to return an error, if it can't add an image
- * manager.SetAddPolicy( FAIL_ON_ADD_FAILS );
- *
- * @endcode
- *
- * Simple add and removal of BufferImage to and from an atlas
- *
- * @code
- *
- * // Structure returned by AtlasManager operations
- * AtlasSlot slot;
- *
- * // Add image to an atlas ( will be created if none suitable exists )
- * manager.Add( bitmapImage, slot );
- *
- * // slot.mImage returns the imageId for the bitmap, slot.mAtlas indicates the atlasId
- * // that the image was added to. The imageId is used to communicate with the AtlasManager
- * uint32_t imageId = slot.mImage;
- * if ( !imageId )
- * {
- *  // Addition has failed.....
- * }
- * ...
- * ...
- * // Done with image, so remove from atlas, if not being used elsewhere
- * manager.Remove( imageId );
- *
- * @endcode
- *
- * Create a Specific Atlas for adding BufferImages to
- *
- * @code
- *
- * // Create an RGB888 atlas of 2048x2848, with a blocksize of 128x128
- * uint32_t atlas = manager.CreateAtlas( 2048u, 2048u, 128u, 128u, Pixel::RGB888 );
- *
- * // Add an image to a preferred atlas ( note not specifying atlas may still result
- * // in the bitmap being added to the atlas above )
- * manager.Add( bitmapImage, slot, atlas );
- *
- * @endcode
- *
- * Create Geometry for a previously added image
- *
- * @code
- *
- * // Top left corner of geometry to be generated
- * Vector2 position( 1.0f, 1.0f );
- *
- * // Geometry will end up here!
- * MeshData meshData;
- * manager.GenerateMeshData( imageId, position, meshData );
- *
- * @endcode
- *
- * Generating Geometry from multiple images in the same atlas
- *
- * @code
- *
- * MeshData firstMesh;
- * MeshData secondMesh;
- * manager.GenerateMeshData( imageid_1, position_1, firstMesh );
- * manager.GenerateMeshData( imageid_2, position_2, secondMesh );
- *
- * // Combine the two meshes. Passing MESH_OPTIMIZE as an optional third parameter will remove duplicate vertices
- * manager.StitchMesh( first, second );
- *
- * @endcode
- *
- */
-
 class AtlasManager : public BaseHandle
 {
 public:
@@ -158,7 +44,6 @@ public:
   typedef uint32_t SizeType;
   typedef SizeType AtlasId;
   typedef SizeType ImageId;
-  static const bool MESH_OPTIMIZE = true;
 
   struct AtlasSize
   {
@@ -197,14 +82,14 @@ public:
 
   struct Vertex2D
   {
-    Vector2 mPosition;
-    Vector2 mTexCoords;
+    Vector2 mPosition;        ///< Vertex posiiton
+    Vector2 mTexCoords;       ///< Vertex texture co-ordinates
   };
 
   struct Mesh2D
   {
-    Vector< Vertex2D > mVertices;
-    Vector< unsigned int> mIndices;
+    Vector< Vertex2D > mVertices;       ///< container of vertices
+    Vector< SizeType > mIndices;        ///< container of indices
   };
 
   /**
@@ -274,8 +159,10 @@ public:
    * @param[in] image reference to a bitmapimage
    * @param[out] slot result of add operation
    * @param[in] atlas optional preferred atlas
+   *
+   * @return true if a new atlas was created
    */
-  void Add( const BufferImage& image,
+  bool Add( const BufferImage& image,
             AtlasSlot& slot,
             AtlasId atlas = 0 );
 
@@ -302,17 +189,6 @@ public:
                          bool addReference = true );
 
   /**
-   * @brief Append second mesh to the first mesh
-   *
-   * @param[in] first First mesh
-   * @param[in] second Second mesh
-   * @param[in] optimize should we optimize vertex data
-   */
-  void StitchMesh( Mesh2D& first,
-                   const Mesh2D& second,
-                   bool optimize = false );
-
-  /**
    * @brief Get the BufferImage containing an atlas
    *
    * @param[in] atlas AtlasId returned when atlas was created
@@ -382,20 +258,20 @@ public:
   /**
    * @brief Get Material used by atlas
    *
-   * @param atlas[in] atlas AtlasId
+   * @param[in] atlas AtlasId
    *
    * @return Material used by atlas
    */
   Material GetMaterial( AtlasId atlas ) const;
 
- /**
-   * @brief Get Image used by atlas
-   *
-   * @param atlas[in] atlas AtlasId
+  /**
+   * @brief Set the material used by an atlas
    *
-   * @return Sampler used by atlas
+   * @param[in] atlas AtlasId
+   * @param[in] material The Material to assign
    */
-  Image GetImage( AtlasId atlas ) const;
+  void SetMaterial( AtlasId atlas, Material& material );
+
 private:
 
   explicit DALI_INTERNAL AtlasManager(Internal::AtlasManager *impl);
diff --git a/dali-toolkit/internal/text/rendering/atlas/atlas-mesh-factory.cpp b/dali-toolkit/internal/text/rendering/atlas/atlas-mesh-factory.cpp
new file mode 100644 (file)
index 0000000..3a64c96
--- /dev/null
@@ -0,0 +1,166 @@
+ /*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/text/rendering/atlas/atlas-mesh-factory.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace AtlasMeshFactory
+{
+
+void CreateQuad( SizeType imageWidth,
+                 SizeType imageHeight,
+                 SizeType block,
+                 const Toolkit::AtlasManager::AtlasSize& atlasSize,
+                 const Vector2& position,
+                 Toolkit::AtlasManager::Mesh2D& mesh )
+{
+  Toolkit::AtlasManager::Vertex2D vertex;
+
+  SizeType blockWidth = atlasSize.mBlockWidth;
+  SizeType blockHeight = atlasSize.mBlockHeight;
+
+  float vertexBlockWidth = static_cast< float >( blockWidth );
+  float vertexBlockHeight = static_cast< float >( blockHeight );
+
+  SizeType atlasWidth = atlasSize.mWidth;
+  SizeType atlasHeight = atlasSize.mHeight;
+
+  SizeType atlasWidthInBlocks = ( atlasWidth - 1u ) / blockWidth;
+
+  // Get the normalized size of a texel in both directions
+  float texelX = 1.0f / static_cast< float >( atlasWidth );
+  float texelY = 1.0f / static_cast< float >( atlasHeight );
+
+  float oneAndAHalfTexelX = texelX + ( texelX * 0.5f );
+  float oneAndAHalfTexelY = texelY + ( texelY * 0.5f );
+
+  float texelBlockWidth = texelX * vertexBlockWidth;
+  float texelBlockHeight = texelY * vertexBlockHeight;
+
+  uint32_t pixelsX = imageWidth % blockWidth;
+  uint32_t pixelsY = imageHeight % blockHeight;
+
+  if ( !pixelsX )
+  {
+    pixelsX = blockWidth;
+  }
+  if ( !pixelsY )
+  {
+    pixelsY = blockHeight;
+  }
+  float vertexWidth = static_cast< float >( pixelsX );
+  float vertexHeight = static_cast< float >( pixelsY );
+  float texelWidth = texelX * vertexWidth;
+  float texelHeight = texelY * vertexHeight;
+
+  // We're going to 'blit' half a pixel more on each edge
+  vertexWidth++;
+  vertexHeight++;
+
+  // Move back half a pixel
+  Vector2 topLeft = Vector2( position.x - 0.5f, position.y - 0.5f );
+
+  float fBlockX = texelBlockWidth * static_cast< float >( block % atlasWidthInBlocks );
+  float fBlockY = texelBlockHeight * static_cast< float >( block / atlasWidthInBlocks );
+
+  // Add on texture filtering compensation ( half a texel plus compensation for filled pixel in top left corner )
+  fBlockX += oneAndAHalfTexelX;
+  fBlockY += oneAndAHalfTexelY;
+
+  float texelWidthOffset = texelWidth + texelX;
+  float texelHeightOffset = texelHeight + texelY;
+
+  // Top left
+  vertex.mPosition.x = topLeft.x;
+  vertex.mPosition.y = topLeft.y;
+  vertex.mTexCoords.x = fBlockX;
+  vertex.mTexCoords.y = fBlockY;
+
+  mesh.mVertices.Reserve( 4u );
+  mesh.mVertices.PushBack( vertex );
+
+  // Top Right
+  vertex.mPosition.x = topLeft.x + vertexWidth;
+  vertex.mPosition.y = topLeft.y;
+  vertex.mTexCoords.x = fBlockX + texelWidthOffset;
+  vertex.mTexCoords.y = fBlockY;
+
+  mesh.mVertices.PushBack( vertex );
+
+  // Bottom Left
+  vertex.mPosition.x = topLeft.x;
+  vertex.mPosition.y = topLeft.y + vertexHeight;
+  vertex.mTexCoords.x = fBlockX;
+  vertex.mTexCoords.y = fBlockY + texelHeightOffset;
+
+  mesh.mVertices.PushBack( vertex );
+
+  // Bottom Right
+  vertex.mPosition.x = topLeft.x + vertexWidth;
+  vertex.mPosition.y = topLeft.y + vertexHeight;
+  vertex.mTexCoords.x = fBlockX + texelWidthOffset;
+  vertex.mTexCoords.y = fBlockY + texelHeightOffset;
+
+  mesh.mVertices.PushBack( vertex );
+
+  // Six indices in counter clockwise winding
+  mesh.mIndices.Reserve( 6u );
+  mesh.mIndices.PushBack( 1u );
+  mesh.mIndices.PushBack( 0u );
+  mesh.mIndices.PushBack( 2u );
+  mesh.mIndices.PushBack( 2u );
+  mesh.mIndices.PushBack( 3u );
+  mesh.mIndices.PushBack( 1u );
+}
+
+void AppendMesh( Toolkit::AtlasManager::Mesh2D& first,
+                 const Toolkit::AtlasManager::Mesh2D& second )
+{
+  const uint32_t verticesCount = first.mVertices.Size();
+  first.mVertices.Insert( first.mVertices.End(),
+                          second.mVertices.Begin(),
+                          second.mVertices.End() );
+
+  const uint32_t indicesCount = first.mIndices.Size();
+  first.mIndices.Insert( first.mIndices.End(),
+                         second.mIndices.Begin(),
+                         second.mIndices.End() );
+
+  for( Vector<unsigned int>::Iterator it = first.mIndices.Begin() + indicesCount,
+         endIt = first.mIndices.End();
+       it != endIt;
+       ++it )
+  {
+    *it += verticesCount;
+  }
+}
+
+} // namespace AtlasMeshFactory
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/rendering/atlas/atlas-mesh-factory.h b/dali-toolkit/internal/text/rendering/atlas/atlas-mesh-factory.h
new file mode 100644 (file)
index 0000000..f3a953c
--- /dev/null
@@ -0,0 +1,70 @@
+#ifndef __DALI_TOOLKIT_ATLAS_MESH_FACTORY_H__
+#define __DALI_TOOLKIT_ATLAS_MESH_FACTORY_H__
+
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/rendering/atlas/atlas-manager.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace AtlasMeshFactory
+{
+  typedef uint32_t SizeType;
+
+  /**
+   * @brief Create a Quad that describes an area in an atlas and a position.
+   *
+   * @param[in]  width Width of area in pixels.
+   * @param[in]  height Height of area in pixels.
+   * @param[in]  block Block position in atlas.
+   * @param[in]  atlasSize Atlas and block dimensions.
+   * @param[in]  position Position to place area in space.
+   * @param[out] mesh Mesh object to hold created quad.
+   */
+  void CreateQuad( SizeType width,
+                   SizeType height,
+                   SizeType block,
+                   const Toolkit::AtlasManager::AtlasSize& atlasSize,
+                   const Vector2& position,
+                   Toolkit::AtlasManager::Mesh2D& mesh );
+
+  /**
+   * @brief Append one mesh to another.
+   *
+   * @param[in,out] first Mesh to append to.
+   * @param[in]     second Mesh to append.
+   */
+  void AppendMesh( Toolkit::AtlasManager::Mesh2D& first,
+                   const Toolkit::AtlasManager::Mesh2D& second );
+
+} // namespace AtlasMeshFactory
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_ATLAS_MESH_FACTORY_H__
index 80459a8..8653b43 100644 (file)
 
 // EXTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
-#include <dali/public-api/common/stage.h>
-#include <dali/public-api/images/frame-buffer-image.h>
-#include <dali/public-api/render-tasks/render-task.h>
-#include <dali/public-api/render-tasks/render-task-list.h>
 #include <dali/devel-api/rendering/renderer.h>
 #include <dali/devel-api/rendering/geometry.h>
 #include <dali/devel-api/text-abstraction/font-client.h>
@@ -32,6 +28,7 @@
 #include <dali-toolkit/public-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>
 #include <dali-toolkit/internal/text/text-view.h>
 
 using namespace Dali;
@@ -47,11 +44,11 @@ namespace
 const float ZERO( 0.0f );
 const float HALF( 0.5f );
 const float ONE( 1.0f );
-const float TWO( 2.0f );
 const uint32_t DEFAULT_ATLAS_WIDTH = 512u;
 const uint32_t DEFAULT_ATLAS_HEIGHT = 512u;
 }
-struct AtlasRenderer::Impl : public ConnectionTracker
+
+struct AtlasRenderer::Impl
 {
   enum Style
   {
@@ -151,9 +148,6 @@ struct AtlasRenderer::Impl : public ConnectionTracker
   bool IsGlyphUnderlined( GlyphIndex index,
                           const Vector<GlyphRun>& underlineRuns )
   {
-    // TODO: At the moment it works because we always traverse the glyphs starting from the beginning
-    //       and there is only one glyph run! If there are more they should be ordered.
-
     for( Vector<GlyphRun>::ConstIterator it = underlineRuns.Begin(),
            endIt = underlineRuns.End();
            it != endIt;
@@ -267,7 +261,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker
           lastUnderlinedFontId = glyph.fontId;
         } // underline
 
-        if ( !mGlyphManager.Cached( glyph.fontId, glyph.index, slot ) )
+        if ( !mGlyphManager.IsCached( glyph.fontId, glyph.index, slot ) )
         {
           // Select correct size for new atlas if needed....?
           if ( lastFontId != glyph.fontId )
@@ -358,7 +352,6 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     // Now remove references for the old text
     RemoveText();
     mTextCache.Swap( newTextCache );
-    RemoveAllShadowRenderTasks();
 
     if( thereAreUnderlinedGlyphs )
     {
@@ -376,9 +369,33 @@ struct AtlasRenderer::Impl : public ConnectionTracker
         // Create an effect if necessary
         if ( style == STYLE_DROP_SHADOW )
         {
-          Actor shadowActor = GenerateShadow( *mIt, actorSize, shadowOffset, shadowColor );
-          shadowActor.Add( actor );
-          actor = shadowActor;
+          // 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();
+#if defined(DEBUG_ENABLED)
+          shadowActor.SetName( "Text Shadow renderable actor" );
+#endif
+          // Offset shadow in x and y
+          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 );
+            containerActor.Add( shadowActor );
+            containerActor.Add( actor );
+            actor = containerActor;
+          }
         }
 
         if( mActor )
@@ -446,6 +463,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     actor.SetParentOrigin( ParentOrigin::CENTER ); // Keep all of the origins aligned
     actor.SetSize( actorSize );
     actor.SetColor( meshRecord.mColor );
+    actor.RegisterProperty("uOffset", Vector2::ZERO );
     return actor;
   }
 
@@ -473,8 +491,8 @@ struct AtlasRenderer::Impl : public ConnectionTracker
       {
         if ( slot.mAtlasId == mIt->mAtlasId && color == mIt->mColor )
         {
-          // Stitch the mesh to the existing mesh and adjust any extents
-          mGlyphManager.StitchMesh( mIt->mMesh, newMesh );
+          // Append the mesh to the existing mesh and adjust any extents
+          Toolkit::Internal::AtlasMeshFactory::AppendMesh( mIt->mMesh, newMesh );
 
           if( underlineGlyph )
           {
@@ -647,7 +665,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker
 
       if ( underlineColor == textColor )
       {
-        mGlyphManager.StitchMesh( meshRecords[ index ].mMesh, newMesh );
+        Toolkit::Internal::AtlasMeshFactory::AppendMesh( meshRecords[ index ].mMesh, newMesh );
       }
       else
       {
@@ -660,170 +678,14 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     }
   }
 
-  Actor GenerateShadow( MeshRecord& meshRecord,
-                        const Vector2& actorSize,
-                        const Vector2& shadowOffset,
-                        const Vector4& shadowColor )
-  {
-    // Scan vertex buffer to determine width and height of effect buffer needed
-    const Vector< AtlasManager::Vertex2D >& verts = meshRecord.mMesh.mVertices;
-    float tlx = verts[ 0 ].mPosition.x;
-    float tly = verts[ 0 ].mPosition.y;
-    float brx = ZERO;
-    float bry = ZERO;
-
-    for ( uint32_t i = 0; i < verts.Size(); ++i )
-    {
-      if ( verts[ i ].mPosition.x < tlx )
-      {
-        tlx = verts[ i ].mPosition.x;
-      }
-      if ( verts[ i ].mPosition.y < tly )
-      {
-        tly = verts[ i ].mPosition.y;
-      }
-      if ( verts[ i ].mPosition.x > brx )
-      {
-        brx = verts[ i ].mPosition.x;
-      }
-      if ( verts[ i ].mPosition.y > bry )
-      {
-        bry = verts[ i ].mPosition.y;
-      }
-    }
-
-    float width = brx - tlx;
-    float height = bry - tly;
-    float divWidth = TWO / width;
-    float divHeight = TWO / height;
-
-    // Create a buffer to render to
-    meshRecord.mBuffer = FrameBufferImage::New( width, height );
-
-    // We will render a quad into this buffer
-    unsigned int indices[ 6 ] = { 1, 0, 2, 2, 3, 1 };
-    PropertyBuffer quadVertices = PropertyBuffer::New( mQuadVertexFormat, 4u );
-    PropertyBuffer quadIndices = PropertyBuffer::New( mQuadIndexFormat, sizeof(indices)/sizeof(indices[0]) );
-
-    AtlasManager::Vertex2D vertices[ 4 ] = {
-    { Vector2( tlx + shadowOffset.x, tly + shadowOffset.y ), Vector2( ZERO, ZERO ) },
-    { Vector2( brx + shadowOffset.x, tly + shadowOffset.y ), Vector2( ONE, ZERO ) },
-    { Vector2( tlx + shadowOffset.x, bry + shadowOffset.y ), Vector2( ZERO, ONE ) },
-    { Vector2( brx + shadowOffset.x, bry + shadowOffset.y ), Vector2( ONE, ONE ) } };
-
-    quadVertices.SetData( vertices );
-    quadIndices.SetData( indices );
-
-    Geometry quadGeometry = Geometry::New();
-    quadGeometry.AddVertexBuffer( quadVertices );
-    quadGeometry.SetIndexBuffer( quadIndices );
-
-    Material material = Material::New( mGlyphManager.GetEffectBufferShader() );
-    material.AddTexture(meshRecord.mBuffer, "sTexture");
-
-    Dali::Renderer renderer = Dali::Renderer::New( quadGeometry, material );
-
-    // Set depth index to -1.0 to make sure shadow is rendered first in 3D layers
-    renderer.SetDepthIndex( -1.0f );
-    Actor actor = Actor::New();
-    actor.AddRenderer( renderer );
-    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;
-    for ( uint32_t i = 0; i < verts.Size(); ++i )
-    {
-      AtlasManager::Vertex2D vertex = verts[ i ];
-      vertex.mPosition.x = ( ( vertex.mPosition.x - tlx ) * divWidth ) - ONE;
-      vertex.mPosition.y = ( ( vertex.mPosition.y - tly ) * divHeight ) - ONE;
-      normVertexList.PushBack( vertex );
-    }
-
-    PropertyBuffer normVertices = PropertyBuffer::New( mQuadVertexFormat, normVertexList.Size() );
-    PropertyBuffer normIndices = PropertyBuffer::New( mQuadIndexFormat, meshRecord.mMesh.mIndices.Size() );
-    normVertices.SetData( const_cast< AtlasManager::Vertex2D* >( &normVertexList[ 0 ] ) );
-    normIndices.SetData( const_cast< unsigned int* >( &meshRecord.mMesh.mIndices[ 0 ] ) );
-
-    Geometry normGeometry = Geometry::New();
-    normGeometry.AddVertexBuffer( normVertices );
-    normGeometry.SetIndexBuffer( normIndices );
-
-    Material normMaterial = Material::New( mGlyphManager.GetGlyphShadowShader() );
-    Image normImage =  mGlyphManager.GetImage( meshRecord.mAtlasId );
-    normMaterial.AddTexture( normImage, "sTexture" );
-    Dali::Renderer normRenderer = Dali::Renderer::New( normGeometry, normMaterial );
-    Actor subActor = Actor::New();
-    subActor.AddRenderer( normRenderer );
-    subActor.SetParentOrigin( ParentOrigin::CENTER ); // Keep all of the origins aligned
-    subActor.SetSize( actorSize );
-    subActor.SetColor( shadowColor );
-
-    // Create a render task to render the effect
-    RenderTask shadowTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
-    shadowTask.SetTargetFrameBuffer( meshRecord.mBuffer );
-    shadowTask.SetSourceActor( subActor );
-    shadowTask.SetClearEnabled( true );
-    shadowTask.SetClearColor( Vector4::ZERO );
-    shadowTask.SetExclusive( true );
-    shadowTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
-    shadowTask.FinishedSignal().Connect( this, &AtlasRenderer::Impl::RenderComplete );
-    mShadowTasks.push_back( shadowTask );
-    actor.Add( subActor );
-
-    return actor;
-  }
-
-  void RemoveShadowRenderTask( RenderTask renderTask )
-  {
-    if( renderTask )
-    {
-      renderTask.FinishedSignal().Disconnect( this, &AtlasRenderer::Impl::RenderComplete );
-
-      // Guard to prevent accessing Stage after dali-core destruction
-      if( Stage::IsInstalled() )
-      {
-        Stage::GetCurrent().GetRenderTaskList().RemoveTask( renderTask );
-      }
-      renderTask.Reset();
-    }
-  }
-
-  void RenderComplete( RenderTask& renderTask )
-  {
-    // Get the actor used for render to buffer and remove it from the parent
-    Actor renderActor = renderTask.GetSourceActor();
-    if ( renderActor )
-    {
-      Actor parent = renderActor.GetParent();
-      if ( parent )
-      {
-        parent.Remove( renderActor );
-      }
-    }
-
-    RemoveShadowRenderTask( renderTask );
-  }
-
-  void RemoveAllShadowRenderTasks()
-  {
-    for ( std::vector< RenderTask >::iterator shadowIterator = mShadowTasks.begin();
-          shadowIterator != mShadowTasks.end(); ++shadowIterator )
-    {
-      RemoveShadowRenderTask( *shadowIterator );
-    }
-  }
-
   Actor mActor;                                       ///< The actor parent which renders the text
   AtlasGlyphManager mGlyphManager;                    ///< Glyph Manager to handle upload and caching
-  std::vector< RenderTask > mShadowTasks;             ///< Used to render shadows
   TextAbstraction::FontClient mFontClient;            ///> The font client used to supply glyph information
   std::vector< MaxBlockSize > mBlockSizes;            ///> Maximum size needed to contain a glyph in a block within a new atlas
-  std::vector< uint32_t > mFace;                      ///> Face indices for a quad
-  Vector< TextCacheEntry > mTextCache;
-  Property::Map mQuadVertexFormat;
-  Property::Map mQuadIndexFormat;
-  int mDepth;
+  Vector< TextCacheEntry > mTextCache;                ///> Caches data from previous render
+  Property::Map mQuadVertexFormat;                    ///> Describes the vertex format for text
+  Property::Map mQuadIndexFormat;                     ///> Describes the index format for text
+  int mDepth;                                         ///> DepthIndex passed by control when connect to stage
 };
 
 Text::RendererPtr AtlasRenderer::New()
@@ -871,8 +733,6 @@ AtlasRenderer::AtlasRenderer()
 
 AtlasRenderer::~AtlasRenderer()
 {
-  mImpl->RemoveAllShadowRenderTasks();
-
   mImpl->RemoveText();
   delete mImpl;
 }