- /*
+/*
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
#include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h>
// EXTERNAL INCLUDES
-#include <dali/public-api/actors/image-actor.h>
-#include <dali/public-api/common/stage.h>
+#include <dali/integration-api/debug.h>
+
+namespace
+{
+
+#if defined(DEBUG_ENABLED)
+ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING");
+#endif
+
+} // unnamed namespace
namespace Dali
{
namespace Internal
{
-//#define DISPLAY_ATLAS
-
AtlasGlyphManager::AtlasGlyphManager()
-: mCount( 0 )
{
mAtlasManager = Dali::Toolkit::AtlasManager::New();
}
-AtlasGlyphManager::~AtlasGlyphManager()
-{
-}
-
-AtlasGlyphManagerPtr AtlasGlyphManager::New()
-{
- AtlasGlyphManagerPtr internal = new AtlasGlyphManager();
- return internal;
-}
-
void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
- const BufferImage& bitmap,
+ const PixelData& bitmap,
Dali::Toolkit::AtlasManager::AtlasSlot& slot )
{
- GlyphRecord record;
- record.mFontId = glyph.fontId;
- record.mIndex = glyph.index;
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Added glyph, font: %d index: %d\n", glyph.fontId, glyph.index );
- mAtlasManager.Add( bitmap, slot );
+ // If glyph added to an existing or new atlas then a new glyph record is required.
+ // Check if an existing atlas will fit the image, create a new one if required.
+ if ( mAtlasManager.Add( bitmap, slot ) )
+ {
+ // A new atlas was created so set the texture set details for the atlas
+ Dali::Texture atlas = mAtlasManager.GetAtlasContainer( slot.mAtlasId );
+ TextureSet textureSet = TextureSet::New();
+ textureSet.SetTexture( 0u, atlas );
+ mAtlasManager.SetTextures( slot.mAtlasId, textureSet );
+ }
+
+ GlyphRecordEntry record;
+ record.mIndex = glyph.index;
record.mImageId = slot.mImageId;
- mGlyphRecords.PushBack( record );
+ record.mCount = 1;
-#ifdef DISPLAY_ATLAS
+ // Have glyph records been created for this fontId ?
+ bool foundGlyph = false;
+ for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+ fontGlyphRecordIt != mFontGlyphRecords.end(); ++fontGlyphRecordIt )
{
- uint32_t atlasCount = mAtlasManager.GetAtlasCount();
- if ( atlasCount > mCount )
+ if ( fontGlyphRecordIt->mFontId == glyph.fontId )
{
- for ( uint32_t i = 0; i < atlasCount; ++i )
- {
- ImageActor actor = ImageActor::New( mAtlasManager.GetAtlasContainer( i + 1u ) );
- actor.SetParentOrigin( Vector3( 0.5f, 0.25f + ( static_cast< float >( i ) * 0.25f ), 0.5f ) );
- actor.SetAnchorPoint( AnchorPoint::CENTER );
- actor.SetSize( 256.0f, 256.0f );
- Stage::GetCurrent().Add( actor );
- }
+ fontGlyphRecordIt->mGlyphRecords.PushBack( record );
+ foundGlyph = true;
+ break;
}
- mCount = atlasCount;
}
-#endif
+
+ if ( !foundGlyph )
+ {
+ // We need to add a new font entry
+ FontGlyphRecord fontGlyphRecord;
+ fontGlyphRecord.mFontId = glyph.fontId;
+ fontGlyphRecord.mGlyphRecords.PushBack( record );
+ mFontGlyphRecords.push_back( fontGlyphRecord );
+ }
}
void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
const Vector2& position,
- MeshData& meshData )
+ Toolkit::AtlasManager::Mesh2D& mesh )
{
- mAtlasManager.GenerateMeshData( imageId, position, meshData );
+ // Generate mesh data and tell Atlas Manager not to handle reference counting ( we'll do it )
+ mAtlasManager.GenerateMeshData( imageId, position, mesh, false );
}
-void AtlasGlyphManager::StitchMesh( MeshData& first,
- const MeshData& second )
-{
- mAtlasManager.StitchMesh( first, second );
-}
-
-void AtlasGlyphManager::Cached( Text::FontId fontId,
- uint32_t index,
+bool AtlasGlyphManager::IsCached( Text::FontId fontId,
+ Text::GlyphIndex index,
Dali::Toolkit::AtlasManager::AtlasSlot& slot )
{
- for ( uint32_t i = 0; i < mGlyphRecords.Size(); ++i )
+ for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+ fontGlyphRecordIt != mFontGlyphRecords.end();
+ ++fontGlyphRecordIt )
{
- if ( fontId == mGlyphRecords[ i ].mFontId && index == mGlyphRecords[ i ].mIndex )
+ if ( fontGlyphRecordIt->mFontId == fontId )
{
- slot.mImageId = mGlyphRecords[ i ].mImageId;
- slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
- return;
+ for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+ glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
+ ++glyphRecordIt )
+ {
+ if ( glyphRecordIt->mIndex == index )
+ {
+ slot.mImageId = glyphRecordIt->mImageId;
+ slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
+ return true;
+ }
+ }
}
}
slot.mImageId = 0;
+ return false;
}
Vector2 AtlasGlyphManager::GetAtlasSize( uint32_t atlasId )
{
- return mAtlasManager.GetAtlasSize( atlasId );
+ Toolkit::AtlasManager::AtlasSize size = mAtlasManager.GetAtlasSize( atlasId );
+ return Vector2( static_cast< float >( size.mWidth ), static_cast< float >( size.mHeight ) );
+}
+
+void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight )
+{
+ Toolkit::AtlasManager::AtlasSize size;
+ size.mWidth = width;
+ size.mHeight = height;
+ size.mBlockWidth = blockWidth;
+ size.mBlockHeight = blockHeight;
+ mAtlasManager.SetNewAtlasSize( size );
+}
+
+Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
+{
+ return mAtlasManager.GetPixelFormat( atlasId );
}
-void AtlasGlyphManager::SetNewAtlasSize( const Vector2& size,
- const Vector2& blockSize )
+const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
{
- mAtlasManager.SetNewAtlasSize( size, blockSize );
+ std::ostringstream verboseMetrics;
+
+ mMetrics.mGlyphCount = 0u;
+ for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+ fontGlyphRecordIt != mFontGlyphRecords.end();
+ ++fontGlyphRecordIt )
+ {
+ mMetrics.mGlyphCount += fontGlyphRecordIt->mGlyphRecords.Size();
+
+ verboseMetrics << "[FontId " << fontGlyphRecordIt->mFontId << " Glyph ";
+ for ( Vector< GlyphRecordEntry >::Iterator glyphRecordEntryIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+ glyphRecordEntryIt != fontGlyphRecordIt->mGlyphRecords.End();
+ ++glyphRecordEntryIt )
+ {
+ verboseMetrics << glyphRecordEntryIt->mIndex << "(" << glyphRecordEntryIt->mCount << ") ";
+ }
+ verboseMetrics << "] ";
+ }
+ mMetrics.mVerboseGlyphCounts = verboseMetrics.str();
+
+ mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
+
+ return mMetrics;
}
-void AtlasGlyphManager::Remove( uint32_t imageId )
+void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta )
{
- if ( mAtlasManager.Remove( imageId ) )
+ if( 0 != delta )
{
- for ( uint32_t i = 0; i < mGlyphRecords.Size(); ++i )
+ DALI_LOG_INFO( gLogFilter, Debug::General, "AdjustReferenceCount %d, font: %d index: %d\n", delta, fontId, index );
+
+ for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+ fontGlyphRecordIt != mFontGlyphRecords.end();
+ ++fontGlyphRecordIt )
{
- if ( mGlyphRecords[ i ].mImageId == imageId )
+ if ( fontGlyphRecordIt->mFontId == fontId )
{
- mGlyphRecords.Remove( mGlyphRecords.Begin() + i );
- return;
+ for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+ glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
+ ++glyphRecordIt )
+ {
+ if ( glyphRecordIt->mIndex == index )
+ {
+ glyphRecordIt->mCount += delta;
+ DALI_ASSERT_DEBUG( glyphRecordIt->mCount >= 0 && "Glyph ref-count should not be negative" );
+
+ if ( !glyphRecordIt->mCount )
+ {
+ mAtlasManager.Remove( glyphRecordIt->mImageId );
+ fontGlyphRecordIt->mGlyphRecords.Remove( glyphRecordIt );
+ }
+ return;
+ }
+ }
}
}
+
+ // Should not arrive here
+ DALI_ASSERT_DEBUG( false && "Failed to adjust ref-count" );
}
}
-Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
+TextureSet AtlasGlyphManager::GetTextures( uint32_t atlasId ) const
{
- return mAtlasManager.GetPixelFormat( atlasId );
+ return mAtlasManager.GetTextures( atlasId );
}
-const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
+AtlasGlyphManager::~AtlasGlyphManager()
{
- mMetrics.mGlyphCount = mGlyphRecords.Size();
- mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
- return mMetrics;
+ // mAtlasManager handle is automatically released here
}
} // namespace Internal