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=2e94ce13fdc88fe22c5f9b132278f14ba9f6a0ea;hp=a9810c9e2968b257a866cfb3f5a4622fbc23a449;hb=5b3cf0e6742934674bdf62bbe15af00e39eae566;hpb=456a3e43364ba389325170d8355384bbd3f6dd6c 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 a9810c9..2e94ce1 100644 --- a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp @@ -19,17 +19,19 @@ #include // EXTERNAL INCLUDES -#include -#include -#include +#include +#include +#include +#include +#include #include -#include -#include +#include #include -#include + // INTERNAL INCLUDES #include #include +#include using namespace Dali; using namespace Dali::Toolkit; @@ -50,7 +52,6 @@ const uint32_t DEFAULT_ATLAS_HEIGHT = 512u; } struct AtlasRenderer::Impl : public ConnectionTracker { - enum Style { STYLE_NORMAL, @@ -59,15 +60,30 @@ struct AtlasRenderer::Impl : public ConnectionTracker struct MeshRecord { + MeshRecord() + : mColor( Color::BLACK ), + mAtlasId( 0 ) + { + } + Vector4 mColor; uint32_t mAtlasId; AtlasManager::Mesh2D mMesh; FrameBufferImage mBuffer; - bool mIsUnderline; }; struct Extent { + Extent() + : mBaseLine( 0.0f ), + mLeft( 0.0f ), + mRight( 0.0f ), + mUnderlinePosition( 0.0f ), + mUnderlineThickness( 0.0f ), + mMeshRecordIndex( 0 ) + { + } + float mBaseLine; float mLeft; float mRight; @@ -78,6 +94,13 @@ struct AtlasRenderer::Impl : public ConnectionTracker struct MaxBlockSize { + MaxBlockSize() + : mFontId( 0 ), + mNeededBlockWidth( 0 ), + mNeededBlockHeight( 0 ) + { + } + FontId mFontId; uint32_t mNeededBlockWidth; uint32_t mNeededBlockHeight; @@ -85,12 +108,25 @@ struct AtlasRenderer::Impl : public ConnectionTracker struct CheckEntry { + CheckEntry() + : mFontId( 0 ), + mIndex( 0 ) + { + } + FontId mFontId; Text::GlyphIndex mIndex; }; struct TextCacheEntry { + TextCacheEntry() + : mFontId( 0 ), + mIndex( 0 ), + mImageId( 0 ) + { + } + FontId mFontId; Text::GlyphIndex mIndex; uint32_t mImageId; @@ -107,14 +143,9 @@ struct AtlasRenderer::Impl : public ConnectionTracker mQuadIndexFormat[ "indices" ] = Property::INTEGER; } - void AddGlyphs( const std::vector& positions, + void AddGlyphs( Text::ViewInterface& view, + const std::vector& positions, const Vector& glyphs, - const Vector4& textColor, - const Vector2& shadowOffset, - const Vector4& shadowColor, - bool underlineEnabled, - const Vector4& underlineColor, - float underlineHeight, int depth ) { AtlasManager::AtlasSlot slot; @@ -123,6 +154,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; @@ -134,17 +174,15 @@ 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; + const GlyphInfo* const glyphsBuffer = glyphs.Begin(); + for( uint32_t i = 0, glyphSize = glyphs.Size(); i < glyphSize; ++i ) { - const GlyphInfo& glyph = glyphs[ i ]; + const GlyphInfo& glyph = *( glyphsBuffer + i ); // No operation for white space if ( glyph.width && glyph.height ) @@ -156,7 +194,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker FontMetrics fontMetrics; mFontClient.GetFontMetrics( glyph.fontId, fontMetrics ); currentUnderlinePosition = ceil( fabsf( fontMetrics.underlinePosition ) ); - float descender = ceil( fabsf( fontMetrics.descender ) ); + const float descender = ceil( fabsf( fontMetrics.descender ) ); if ( underlineHeight == ZERO ) { @@ -185,9 +223,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....? @@ -235,13 +270,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, @@ -254,7 +298,11 @@ struct AtlasRenderer::Impl : public ConnectionTracker slot ); lastFontId = glyph.fontId; } - } + } // glyphs + + // Now remove references for the old text + RemoveText(); + mTextCache.Swap( newTextCache ); if ( underlineEnabled ) { @@ -267,17 +315,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 @@ -292,9 +339,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, @@ -307,7 +357,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() ); @@ -326,17 +385,9 @@ 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 ) - { - actor.SetColorMode( USE_OWN_COLOR ); - } - else - { - actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR ); - } return actor; } @@ -356,7 +407,10 @@ struct AtlasRenderer::Impl : public ConnectionTracker // Check to see if there's a mesh data object that references the same atlas ? uint32_t index = 0; - for ( std::vector< MeshRecord >::iterator mIt = meshContainer.begin(); mIt != meshContainer.end(); ++mIt, ++index ) + for ( std::vector< MeshRecord >::iterator mIt = meshContainer.begin(), + mEndIt = meshContainer.end(); + mIt != mEndIt; + ++mIt, ++index ) { if ( slot.mAtlasId == mIt->mAtlasId && color == mIt->mColor ) { @@ -379,7 +433,6 @@ struct AtlasRenderer::Impl : public ConnectionTracker meshRecord.mAtlasId = slot.mAtlasId; meshRecord.mMesh = newMesh; meshRecord.mColor = color; - meshRecord.mIsUnderline = false; meshContainer.push_back( meshRecord ); // Adjust extents for this new meshrecord @@ -405,7 +458,10 @@ struct AtlasRenderer::Impl : public ConnectionTracker float underlineThickness ) { bool foundExtent = false; - for ( Vector< Extent >::Iterator eIt = extents.Begin(); eIt != extents.End(); ++eIt ) + for ( Vector< Extent >::Iterator eIt = extents.Begin(), + eEndIt = extents.End(); + eIt != eEndIt; + ++eIt ) { if ( Equals( baseLine, eIt->mBaseLine ) ) { @@ -442,58 +498,6 @@ struct AtlasRenderer::Impl : public ConnectionTracker } } - void RemoveText( const Vector& 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& glyphs ) { MaxBlockSize maxBlockSize; @@ -520,14 +524,17 @@ struct AtlasRenderer::Impl : public ConnectionTracker } } - void GenerateUnderlines( std::vector< MeshRecord>& meshRecords, + void GenerateUnderlines( std::vector< MeshRecord >& meshRecords, Vector< Extent >& extents, const Vector4& underlineColor, const Vector4& textColor ) { AtlasManager::Mesh2D newMesh; unsigned short faceIndex = 0; - for ( Vector< Extent >::ConstIterator eIt = extents.Begin(); eIt != extents.End(); ++eIt ) + for ( Vector< Extent >::ConstIterator eIt = extents.Begin(), + eEndIt = extents.End(); + eIt != eEndIt; + ++eIt ) { AtlasManager::Vertex2D vert; uint32_t index = eIt->mMeshRecordIndex; @@ -582,13 +589,13 @@ struct AtlasRenderer::Impl : public ConnectionTracker record.mMesh = newMesh; record.mAtlasId = meshRecords[ index ].mAtlasId; record.mColor = underlineColor; - record.mIsUnderline = true; meshRecords.push_back( record ); } } } Actor GenerateShadow( MeshRecord& meshRecord, + const Vector2& actorSize, const Vector2& shadowOffset, const Vector4& shadowColor ) { @@ -655,7 +662,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; @@ -682,7 +690,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 ); @@ -757,14 +766,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 ); } @@ -779,7 +783,6 @@ AtlasRenderer::AtlasRenderer() AtlasRenderer::~AtlasRenderer() { - Vector< GlyphInfo > emptyGlyphs; - mImpl->RemoveText( emptyGlyphs ); + mImpl->RemoveText(); delete mImpl; }