X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Frendering%2Fatlas%2Ftext-atlas-renderer.cpp;h=4cb19edff33b4e009676ca06c7d3ba85ea643300;hp=5af46ef2ddf0e0a192c692e6ff5d78f87b7d8ca7;hb=2039784e7811f5f68ffdfb13c6aa1bc39f2ab950;hpb=60f5b0594b5163663287ecaa0774f9206c31bb86 diff --git a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp index 5af46ef..4cb19ed 100644 --- a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp @@ -20,10 +20,6 @@ // EXTERNAL INCLUDES #include -#include -#include -#include -#include #include #include #include @@ -32,6 +28,7 @@ #include #include #include +#include #include 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& 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::ConstIterator it = underlineRuns.Begin(), endIt = underlineRuns.End(); it != endIt; @@ -238,7 +232,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker currentUnderlinePosition = ceil( fabsf( fontMetrics.underlinePosition ) ); const float descender = ceil( fabsf( fontMetrics.descender ) ); - if ( underlineHeight == ZERO ) + if( fabsf( underlineHeight ) < Math::MACHINE_EPSILON_1000 ) { currentUnderlineThickness = fontMetrics.underlineThickness; @@ -258,7 +252,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker { currentUnderlinePosition = descender; } - if ( ZERO == currentUnderlinePosition ) + if( fabsf( currentUnderlinePosition ) < Math::MACHINE_EPSILON_1000 ) { // Move offset down by one ( EFL behavior ) currentUnderlinePosition = ONE; @@ -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 ) @@ -375,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 ) @@ -445,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; } @@ -472,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 ) { @@ -646,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 { @@ -659,147 +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 ); - - Sampler sampler = Sampler::New( meshRecord.mBuffer, "sTexture" ); - Material material = Material::New( mGlyphManager.GetEffectBufferShader() ); - material.AddSampler( sampler ); - - 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() ); - Sampler normSampler = mGlyphManager.GetSampler( meshRecord.mAtlasId ); - normMaterial.AddSampler( normSampler ); - 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 task = Stage::GetCurrent().GetRenderTaskList().CreateTask(); - task.SetTargetFrameBuffer( meshRecord.mBuffer ); - task.SetSourceActor( subActor ); - task.SetClearEnabled( true ); - task.SetClearColor( Vector4::ZERO ); - task.SetExclusive( true ); - task.SetRefreshRate( RenderTask::REFRESH_ONCE ); - task.FinishedSignal().Connect( this, &AtlasRenderer::Impl::RenderComplete ); - actor.Add( subActor ); - - return actor; - } - - void RenderComplete( RenderTask& renderTask ) - { - // Disconnect and remove this single shot render task - renderTask.FinishedSignal().Disconnect( this, &AtlasRenderer::Impl::RenderComplete ); - Stage::GetCurrent().GetRenderTaskList().RemoveTask( 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 ); - } - } - } - Actor mActor; ///< The actor parent which renders the text AtlasGlyphManager mGlyphManager; ///< Glyph Manager to handle upload and caching 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() @@ -834,6 +720,13 @@ Actor AtlasRenderer::Render( Text::ViewInterface& view, int depth ) positions, glyphs, depth ); + + /* In the case where AddGlyphs does not create a renderable Actor for example when glyphs are all whitespace create a new Actor. */ + /* This renderable actor is used to position the text, other "decorations" can rely on there always being an Actor regardless of it is whitespace or regular text*/ + if ( !mImpl->mActor ) + { + mImpl->mActor = Actor::New(); + } } return mImpl->mActor;