From 7e85bd91f75df91102fa1cb39d7e4d5f4b3df61a Mon Sep 17 00:00:00 2001 From: Richard Underhill Date: Wed, 15 Apr 2015 09:35:19 +0100 Subject: [PATCH] Fix for Text Rendering Artefacts Change-Id: I64f318791b61629a750ec2e558625ada7da1de97 Signed-off-by: Richard Underhill --- .../internal/atlas-manager/atlas-manager-impl.cpp | 131 +++++++++------------ .../internal/atlas-manager/atlas-manager-impl.h | 19 +-- .../internal/atlas-manager/atlas-manager.cpp | 20 +--- .../internal/atlas-manager/atlas-manager.h | 43 +++---- .../rendering/atlas/atlas-glyph-manager-impl.cpp | 13 +- .../rendering/atlas/atlas-glyph-manager-impl.h | 3 +- .../text/rendering/atlas/atlas-glyph-manager.cpp | 5 +- .../text/rendering/atlas/atlas-glyph-manager.h | 17 +-- .../text/rendering/atlas/text-atlas-renderer.cpp | 71 ++++++----- 9 files changed, 148 insertions(+), 174 deletions(-) diff --git a/dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp b/dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp index 83bb423..853c0ae 100644 --- a/dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp +++ b/dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp @@ -33,19 +33,24 @@ namespace Internal namespace { - const Vector2 DEFAULT_ATLAS_SIZE( 512.0f, 512.0f ); - const Vector2 DEFAULT_BLOCK_SIZE( 32.0f, 32.0f ); + const uint32_t DEFAULT_ATLAS_WIDTH( 512u ); + const uint32_t DEFAULT_ATLAS_HEIGHT( 512u ); + const uint32_t DEFAULT_BLOCK_WIDTH( 16u ); + const uint32_t DEFAULT_BLOCK_HEIGHT( 16u ); const uint32_t SINGLE_PIXEL_PADDING( 1u ); const uint32_t DOUBLE_PIXEL_PADDING( SINGLE_PIXEL_PADDING << 1 ); const uint32_t FILLED_PIXEL( -1 ); + Toolkit::AtlasManager::AtlasSize EMPTY_SIZE; } AtlasManager::AtlasManager() -: mNewAtlasSize( DEFAULT_ATLAS_SIZE ), - mNewBlockSize( DEFAULT_BLOCK_SIZE ), - mAddFailPolicy( Toolkit::AtlasManager::FAIL_ON_ADD_CREATES ), +: mAddFailPolicy( Toolkit::AtlasManager::FAIL_ON_ADD_CREATES ), mFilledPixel( FILLED_PIXEL ) { + mNewAtlasSize.mWidth = DEFAULT_ATLAS_WIDTH; + mNewAtlasSize.mHeight = DEFAULT_ATLAS_HEIGHT; + mNewAtlasSize.mBlockWidth = DEFAULT_BLOCK_WIDTH; + mNewAtlasSize.mBlockHeight = DEFAULT_BLOCK_HEIGHT; } AtlasManagerPtr AtlasManager::New() @@ -62,12 +67,13 @@ AtlasManager::~AtlasManager() } } -Toolkit::AtlasManager::AtlasId AtlasManager::CreateAtlas( SizeType width, - SizeType height, - SizeType blockWidth, - SizeType blockHeight, - Pixel::Format pixelformat ) +Toolkit::AtlasManager::AtlasId AtlasManager::CreateAtlas( const Toolkit::AtlasManager::AtlasSize& size, Pixel::Format pixelformat ) { + SizeType width = size.mWidth; + SizeType height = size.mHeight; + SizeType blockWidth = size.mBlockWidth; + SizeType blockHeight = size.mBlockHeight; + // Check to see if the atlas is large enough to hold a single block even ? if ( blockWidth > width || blockHeight > height ) { @@ -79,10 +85,7 @@ Toolkit::AtlasManager::AtlasId AtlasManager::CreateAtlas( SizeType width, Dali::Atlas atlas = Dali::Atlas::New( width, height, pixelformat ); AtlasDescriptor atlasDescriptor; atlasDescriptor.mAtlas = atlas; - atlasDescriptor.mWidth = width; - atlasDescriptor.mHeight = height; - atlasDescriptor.mBlockWidth = blockWidth; - atlasDescriptor.mBlockHeight = blockHeight; + atlasDescriptor.mSize = size; atlasDescriptor.mPixelFormat = pixelformat; std::stringstream materialLabel; materialLabel << "Atlas Material - "; @@ -152,7 +155,7 @@ void AtlasManager::Add( const BufferImage& image, { if ( Toolkit::AtlasManager::FAIL_ON_ADD_CREATES == mAddFailPolicy ) { - SizeType newAtlas = CreateAtlas( mNewAtlasSize.x, mNewAtlasSize.y, mNewBlockSize.x, mNewBlockSize.y, pixelFormat ); + SizeType newAtlas = CreateAtlas( mNewAtlasSize, pixelFormat ); if ( !newAtlas-- ) { return; @@ -237,8 +240,8 @@ AtlasManager::SizeType AtlasManager::CheckAtlas( SizeType atlas, if ( pixelFormat == mAtlasList[ atlas ].mPixelFormat ) { // Check to see if there are any unused blocks in this atlas to accomodate our image - SizeType blocksInX = mAtlasList[ atlas ].mWidth / mAtlasList[ atlas ].mBlockWidth; - SizeType blocksInY = mAtlasList[ atlas ].mHeight / mAtlasList[ atlas ].mBlockHeight; + SizeType blocksInX = mAtlasList[ atlas ].mSize.mWidth / mAtlasList[ atlas ].mSize.mBlockWidth; + SizeType blocksInY = mAtlasList[ atlas ].mSize.mHeight / mAtlasList[ atlas ].mSize.mBlockHeight; totalBlocks = blocksInX * blocksInY; SizeType blocksFree = mAtlasList[ atlas ].mNextFreeBlock ? totalBlocks - mAtlasList[ atlas ].mNextFreeBlock + 1u : @@ -246,8 +249,8 @@ AtlasManager::SizeType AtlasManager::CheckAtlas( SizeType atlas, // Check to see if the image will fit in these blocks, if not we'll need to create a new atlas if ( blocksFree - && width + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mBlockWidth - && height + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mBlockHeight ) + && width + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mSize.mBlockWidth + && height + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mSize.mBlockHeight ) { blockArea = 1u; return ( atlas + 1u ); @@ -273,14 +276,14 @@ void AtlasManager::CreateMesh( SizeType atlas, meshData.SetHasColor( true ); meshData.SetHasTextureCoords( true ); - SizeType blockWidth = mAtlasList[ atlas ].mBlockWidth; - SizeType blockHeight = mAtlasList[ atlas ].mBlockHeight; + 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 ].mWidth; - SizeType height = mAtlasList[ atlas ].mHeight; + SizeType width = mAtlasList[ atlas ].mSize.mWidth; + SizeType height = mAtlasList[ atlas ].mSize.mHeight; SizeType atlasWidthInBlocks = width / blockWidth; @@ -581,9 +584,9 @@ void AtlasManager::UploadImage( const BufferImage& image, return; } - SizeType atlasBlockWidth = mAtlasList[ atlas ].mBlockWidth; - SizeType atlasBlockHeight = mAtlasList[ atlas ].mBlockHeight; - SizeType atlasWidthInBlocks = mAtlasList[ atlas ].mWidth / mAtlasList[ atlas ].mBlockWidth; + SizeType atlasBlockWidth = mAtlasList[ atlas ].mSize.mBlockWidth; + SizeType atlasBlockHeight = mAtlasList[ atlas ].mSize.mBlockHeight; + SizeType atlasWidthInBlocks = mAtlasList[ atlas ].mSize.mWidth / mAtlasList[ atlas ].mSize.mBlockWidth; SizeType block = desc.mBlocksList[ 0 ]; SizeType blockX = block % atlasWidthInBlocks; @@ -624,7 +627,7 @@ void AtlasManager::UploadImage( const BufferImage& image, } // Blit bottom strip - if ( blockOffsetY + height + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mHeight ) + if ( blockOffsetY + height + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mSize.mHeight ) { if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mHorizontalStrip, blockOffsetX, @@ -635,7 +638,7 @@ void AtlasManager::UploadImage( const BufferImage& image, } // Blit right strip - if ( blockOffsetX + width + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mWidth ) + if ( blockOffsetX + width + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mSize.mWidth ) { if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mVerticalStrip, blockOffsetX + width + SINGLE_PIXEL_PADDING, @@ -656,13 +659,13 @@ void AtlasManager::GenerateMeshData( ImageId id, SizeType width = mImageList[ imageId ].mImageWidth; SizeType height = mImageList[ imageId ].mImageHeight; - SizeType widthInBlocks = width / mAtlasList[ atlas ].mBlockWidth; - if ( width % mAtlasList[ atlas ].mBlockWidth ) + SizeType widthInBlocks = width / mAtlasList[ atlas ].mSize.mBlockWidth; + if ( width % mAtlasList[ atlas ].mSize.mBlockWidth ) { widthInBlocks++; } - SizeType heightInBlocks = height / mAtlasList[ atlas ].mBlockHeight; - if ( height % mAtlasList[ atlas ].mBlockHeight ) + SizeType heightInBlocks = height / mAtlasList[ atlas ].mSize.mBlockHeight; + if ( height % mAtlasList[ atlas ].mSize.mBlockHeight ) { heightInBlocks++; } @@ -704,7 +707,7 @@ bool AtlasManager::Remove( ImageId id ) return false; } - if ( 1u == --mImageList[ imageId ].mCount ) + if ( 2u > --mImageList[ imageId ].mCount ) { // 'Remove the blocks' from this image and add to the atlas' freelist removed = true; @@ -730,37 +733,20 @@ AtlasManager::AtlasId AtlasManager::GetAtlas( ImageId id ) const } } -void AtlasManager::SetNewAtlasSize( const Vector2& size, - const Vector2& blockSize ) +void AtlasManager::SetNewAtlasSize( const Toolkit::AtlasManager::AtlasSize& size ) { mNewAtlasSize = size; - mNewBlockSize = blockSize; -} - -Vector2 AtlasManager::GetBlockSize( AtlasId atlas ) -{ - if ( atlas && atlas <= mAtlasList.size() ) - { - return Vector2( static_cast< float >( mAtlasList[ atlas - 1u ].mBlockWidth ), - static_cast< float >( mAtlasList[ atlas - 1u ].mBlockHeight) ); - } - else - { - return Vector2::ZERO; - } + mNewAtlasSize.mBlockWidth += DOUBLE_PIXEL_PADDING; + mNewAtlasSize.mBlockHeight += DOUBLE_PIXEL_PADDING; } -Vector2 AtlasManager::GetAtlasSize( AtlasId atlas ) +const Toolkit::AtlasManager::AtlasSize& AtlasManager::GetAtlasSize( AtlasId atlas ) { - if ( atlas && atlas <= mAtlasList.size() ) + if ( atlas && atlas-- <= mAtlasList.size() ) { - return Vector2( static_cast< float >( mAtlasList[ atlas - 1u ].mWidth ), - static_cast< float >( mAtlasList[ atlas - 1u ].mHeight ) ); - } - else - { - return Vector2::ZERO; + return mAtlasList[ atlas ].mSize; } + return EMPTY_SIZE; } AtlasManager::SizeType AtlasManager::GetFreeBlocks( AtlasId atlas ) const @@ -768,17 +754,24 @@ AtlasManager::SizeType AtlasManager::GetFreeBlocks( AtlasId atlas ) const if ( atlas && atlas <= mAtlasList.size() ) { uint32_t index = atlas - 1u; - uint32_t width = mAtlasList[ index ].mWidth; - uint32_t height = mAtlasList[ index ].mHeight; - uint32_t blockWidth = mAtlasList[ index ].mBlockWidth; - uint32_t blockHeight = mAtlasList[ index ].mBlockHeight; + uint32_t width = mAtlasList[ index ].mSize.mWidth; + uint32_t height = mAtlasList[ index ].mSize.mHeight; + uint32_t blockWidth = mAtlasList[ index ].mSize.mBlockWidth; + uint32_t blockHeight = mAtlasList[ index ].mSize.mBlockHeight; SizeType widthInBlocks = width / blockWidth; SizeType heightInBlocks = height / blockHeight; uint32_t blockCount = widthInBlocks * heightInBlocks; // Check free previously unallocated blocks and any free blocks - blockCount -= mAtlasList[ index ].mNextFreeBlock - mAtlasList[ index ].mFreeBlocksList.Size(); + if ( mAtlasList[ index ].mNextFreeBlock ) + { + blockCount -= mAtlasList[ index ].mNextFreeBlock -1u - mAtlasList[ index ].mFreeBlocksList.Size(); + } + else + { + blockCount = mAtlasList[ index ].mFreeBlocksList.Size(); + } return blockCount; } else @@ -813,23 +806,15 @@ void AtlasManager::GetMetrics( Toolkit::AtlasManager::Metrics& metrics ) for ( uint32_t i = 0; i < atlasCount; ++i ) { - SizeType width = mAtlasList[ i ].mWidth; - SizeType height = mAtlasList[ i ].mHeight; - SizeType blockWidth = mAtlasList[ i ].mBlockWidth; - SizeType blockHeight = mAtlasList[ i ].mBlockHeight; - - entry.mWidth = width; - entry.mHeight = height; - entry.mBlockWidth = blockWidth; - entry.mBlockHeight = blockHeight; - entry.mTotalBlocks = ( width / blockWidth ) * ( height / blockHeight ); + entry.mSize = mAtlasList[ i ].mSize; + entry.mTotalBlocks = ( entry.mSize.mWidth / entry.mSize.mBlockWidth ) * ( entry.mSize.mHeight / entry.mSize.mBlockHeight ); uint32_t reuseBlocks = mAtlasList[ i ].mFreeBlocksList.Size(); entry.mBlocksUsed = mAtlasList[ i ].mNextFreeBlock ? mAtlasList[ i ].mNextFreeBlock - reuseBlocks - 1u: entry.mTotalBlocks - reuseBlocks; entry.mPixelFormat = GetPixelFormat( i + 1 ); metrics.mAtlasMetrics.PushBack( entry ); - uint32_t size = width * height; + uint32_t size = entry.mSize.mWidth * entry.mSize.mHeight; if ( entry.mPixelFormat == Pixel::BGRA8888 ) { size <<= 2; diff --git a/dali-toolkit/internal/atlas-manager/atlas-manager-impl.h b/dali-toolkit/internal/atlas-manager/atlas-manager-impl.h index 0656da7..ef078f8 100644 --- a/dali-toolkit/internal/atlas-manager/atlas-manager-impl.h +++ b/dali-toolkit/internal/atlas-manager/atlas-manager-impl.h @@ -60,10 +60,7 @@ public: struct AtlasDescriptor { Dali::Atlas mAtlas; // atlas image - SizeType mWidth; // width of atlas - SizeType mHeight; // height of atlas - SizeType mBlockWidth; // width of a block in atlas - SizeType mBlockHeight; // height of a block in atlas + Toolkit::AtlasManager::AtlasSize mSize; // size of atlas Pixel::Format mPixelFormat; // pixel format used by atlas BufferImage mHorizontalStrip; // Image used to pad upload BufferImage mVerticalStrip; // Image used to pad upload @@ -95,11 +92,7 @@ public: /** * @copydoc: Toolkit::AtlasManager::CreateAtlas */ - AtlasId CreateAtlas( SizeType width, - SizeType height, - SizeType blockWidth, - SizeType blockHeight, - Pixel::Format pixelformat ); + AtlasId CreateAtlas( const Toolkit::AtlasManager::AtlasSize& size, Pixel::Format pixelformat ); /** * @copydoc Toolkit::AtlasManager::SetAddPolicy @@ -152,13 +145,12 @@ public: /** * @copydoc Toolkit::AtlasManager::SetNewAtlasSize */ - void SetNewAtlasSize( const Vector2& size, - const Vector2& blockSize ); + void SetNewAtlasSize( const Toolkit::AtlasManager::AtlasSize& size ); /** * @copydoc Toolkit::AtlasManager::GetAtlasSize */ - Vector2 GetAtlasSize( AtlasId atlas ); + const Toolkit::AtlasManager::AtlasSize& GetAtlasSize( AtlasId atlas ); /** * @copydoc Toolkit::AtlasManager::GetBlockSize @@ -215,8 +207,7 @@ private: void PrintMeshData( const MeshData& meshData ); - Vector2 mNewAtlasSize; - Vector2 mNewBlockSize; + Toolkit::AtlasManager::AtlasSize mNewAtlasSize; Toolkit::AtlasManager::AddFailPolicy mAddFailPolicy; uint32_t mFilledPixel; }; diff --git a/dali-toolkit/internal/atlas-manager/atlas-manager.cpp b/dali-toolkit/internal/atlas-manager/atlas-manager.cpp index 6d21245..e46eb1d 100644 --- a/dali-toolkit/internal/atlas-manager/atlas-manager.cpp +++ b/dali-toolkit/internal/atlas-manager/atlas-manager.cpp @@ -45,13 +45,9 @@ AtlasManager::AtlasManager(Internal::AtlasManager *impl) { } -AtlasManager::AtlasId AtlasManager::CreateAtlas( SizeType width, - SizeType height, - SizeType blockWidth, - SizeType blockHeight, - Pixel::Format pixelformat ) +AtlasManager::AtlasId AtlasManager::CreateAtlas( const AtlasManager::AtlasSize& size, Pixel::Format pixelformat ) { - return GetImplementation(*this).CreateAtlas( width, height, blockWidth, blockHeight, pixelformat ); + return GetImplementation(*this).CreateAtlas( size, pixelformat ); } void AtlasManager::SetAddPolicy( AddFailPolicy policy ) @@ -105,12 +101,7 @@ AtlasManager::AtlasId AtlasManager::GetAtlas( ImageId id ) return GetImplementation(*this).GetAtlas( id ); } -Vector2 AtlasManager::GetBlockSize( AtlasId atlas ) -{ - return GetImplementation(*this).GetBlockSize( atlas ); -} - -Vector2 AtlasManager::GetAtlasSize( AtlasId atlas ) +const AtlasManager::AtlasSize& AtlasManager::GetAtlasSize( AtlasId atlas ) { return GetImplementation(*this).GetAtlasSize( atlas ); } @@ -120,10 +111,9 @@ AtlasManager::SizeType AtlasManager::GetFreeBlocks( AtlasId atlas ) return GetImplementation(*this).GetFreeBlocks( atlas ); } -void AtlasManager::SetNewAtlasSize( const Vector2& size, - const Vector2& blockSize ) +void AtlasManager::SetNewAtlasSize( const AtlasSize& size ) { - GetImplementation(*this).SetNewAtlasSize( size, blockSize ); + GetImplementation(*this).SetNewAtlasSize( size ); } AtlasManager::SizeType AtlasManager::GetAtlasCount() const diff --git a/dali-toolkit/internal/atlas-manager/atlas-manager.h b/dali-toolkit/internal/atlas-manager/atlas-manager.h index 9263ea4..5fc10d0 100644 --- a/dali-toolkit/internal/atlas-manager/atlas-manager.h +++ b/dali-toolkit/internal/atlas-manager/atlas-manager.h @@ -160,16 +160,21 @@ public: typedef SizeType ImageId; static const bool MESH_OPTIMIZE = true; + struct AtlasSize + { + SizeType mWidth; // width of the atlas in pixels + SizeType mHeight; // height of the atlas in pixels + SizeType mBlockWidth; // width of a block in pixels + SizeType mBlockHeight; // height of a block in pixels + }; + /** * Metrics structures to describe Atlas Manager state * */ struct AtlasMetricsEntry { - SizeType mWidth; // width of the atlas in pixels - SizeType mHeight;; // height of the atlas in pixels - SizeType mBlockWidth; // width of a block in pixels - SizeType mBlockHeight; // height of a block in pixels + AtlasSize mSize; // size of atlas and blocks SizeType mBlocksUsed; // number of blocks used in the atlas SizeType mTotalBlocks; // total blocks used by atlas Pixel::Format mPixelFormat; // pixel format of the atlas @@ -225,19 +230,12 @@ public: /** * @brief Create a blank atlas of specific dimensions and pixel format with a certain block size * - * @param[in] width desired atlas width in pixels - * @param[in] height desired atlas height in pixels - * @param[in] blockWidth block width to use in atlas in pixels - * @param[in] blockHeight block height to use in atlas in pixels + * @param[in] size desired atlas dimensions * @param[in] pixelformat format of a pixel in atlas * * @return atlas Id */ - AtlasId CreateAtlas( SizeType width, - SizeType height, - SizeType blockWidth, - SizeType blockHeight, - Pixel::Format pixelformat = Pixel::RGBA8888 ); + AtlasId CreateAtlas( const AtlasSize& size, Pixel::Format pixelformat = Pixel::RGBA8888 ); /** * @brief Set the policy on failure to add an image to an atlas @@ -322,24 +320,14 @@ public: * @return Atlas Id */ AtlasId GetAtlas( ImageId id ); - - /** - * @brief Get the size of the blocks used in an atlas - * - * @param[in] atlas AtlasId - * - * @return width and height of the blocks used - */ - Vector2 GetBlockSize( AtlasId atlas ); - /** * @brief Get the current size of an atlas * * @param[in] atlas AtlasId * - * @return width and height of the atlas + * @return AtlasSize structure for the atlas */ - Vector2 GetAtlasSize( AtlasId atlas ); + const AtlasSize& GetAtlasSize( AtlasId atlas ); /** * @brief Get the number of blocks available in an atlas @@ -353,12 +341,11 @@ public: /** * @brief Sets the pixel area of any new atlas and also the individual block size * - * @param[in] size pixel area of atlas + * @param[in] size Atlas size structure * * @param blockSize pixel area in atlas for a block */ - void SetNewAtlasSize( const Vector2& size, - const Vector2& blockSize ); + void SetNewAtlasSize( const AtlasSize& size ); /** * @brief Get the number of atlases created diff --git a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp index 16fdc8a..734b82a 100644 --- a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp @@ -110,13 +110,18 @@ void AtlasGlyphManager::Cached( Text::FontId fontId, 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( const Vector2& size, - const Vector2& blockSize ) +void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight ) { - mAtlasManager.SetNewAtlasSize( size, blockSize ); + Toolkit::AtlasManager::AtlasSize size; + size.mWidth = width; + size.mHeight = height; + size.mBlockWidth = blockWidth; + size.mBlockHeight = blockHeight; + mAtlasManager.SetNewAtlasSize( size ); } void AtlasGlyphManager::Remove( uint32_t imageId ) diff --git a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h index 5068426..cbbe732 100644 --- a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h +++ b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h @@ -100,8 +100,7 @@ public: /** * @copydoc Toolkit::AtlasGlyphManager::SetNewAtlasSize */ - void SetNewAtlasSize( const Vector2& size, - const Vector2& blockSize ); + void SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight ); /** * @copydoc Toolkit::AtlasGlyphManager::Remove diff --git a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp index d46ef18..ccb0efc 100644 --- a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp @@ -98,10 +98,9 @@ void AtlasGlyphManager::Cached( Text::FontId fontId, GetImplementation(*this).Cached( fontId, index, slot ); } -void AtlasGlyphManager::SetNewAtlasSize( const Vector2& size, - const Vector2& blockSize ) +void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight ) { - GetImplementation(*this).SetNewAtlasSize( size, blockSize ); + GetImplementation(*this).SetNewAtlasSize( width, height, blockWidth, blockHeight ); } Vector2 AtlasGlyphManager::GetAtlasSize( uint32_t atlasId ) diff --git a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h index 6a10947..ad2c5ea 100644 --- a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h +++ b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h @@ -119,14 +119,15 @@ public: */ Vector2 GetAtlasSize( uint32_t atlasId ); - /** - * @brief Set the Atlas size and block size for subsequent atlas generation - * - * @param[in] size size of the atlas in pixels - * @param[in] blockSize size of a block in this atlas in pixels - */ - void SetNewAtlasSize( const Vector2& size, - const Vector2& blockSize ); + /** + * @brief Set the atlas size and block size for subsequent Atlas generation + * + * @param[in] width width of atlas in pixels + * @param[in] height height of atlas in pixels + * @param[in] blockWidth width of a block in pixels + * @param[in] blockHeight height of a block in pixels + */ + void SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight ); /** * @brief Unreference an image from the atlas and remove from cache if no longer needed 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 b06d4e6..7891391 100644 --- a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp @@ -38,13 +38,12 @@ using namespace Dali::Toolkit::Text; namespace { - const Vector2 DEFAULT_ATLAS_SIZE( 512.0f, 512.0f ); - const Vector2 DEFAULT_BLOCK_SIZE( 16.0f, 16.0f ); - const Vector2 PADDING( 4.0f, 4.0f ); // Allow for variation in font glyphs 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 @@ -84,14 +83,14 @@ struct AtlasRenderer::Impl : public ConnectionTracker struct MaxBlockSize { FontId mFontId; - Vector2 mNeededBlockSize; + uint32_t mNeededBlockWidth; + uint32_t mNeededBlockHeight; }; Impl() { mGlyphManager = AtlasGlyphManager::Get(); mFontClient = TextAbstraction::FontClient::Get(); - mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_SIZE, DEFAULT_BLOCK_SIZE ); mBasicShader = BasicShader::New(); mBgraShader = BgraShader::New(); mBasicShadowShader = BasicShadowShader::New(); @@ -116,7 +115,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker float currentUnderlinePosition = ZERO; float currentUnderlineThickness = underlineHeight; - + uint32_t currentBlockSize = 0; FontId lastFontId = 0; Style style = STYLE_NORMAL; @@ -196,15 +195,39 @@ struct AtlasRenderer::Impl : public ConnectionTracker { if ( mBlockSizes[ j ].mFontId == glyph.fontId ) { - mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_SIZE, mBlockSizes[ j ].mNeededBlockSize ); + currentBlockSize = j; + mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_WIDTH, + DEFAULT_ATLAS_HEIGHT, + mBlockSizes[ j ].mNeededBlockWidth, + mBlockSizes[ j ].mNeededBlockHeight ); } } - lastFontId = glyph.fontId; } - // Glyph doesn't currently exist in atlas so upload + // Create a new image for the glyph BufferImage bitmap = mFontClient.CreateBitmap( glyph.fontId, glyph.index ); + // Ensure that the next image will fit into the current block size + bool setSize = false; + if ( bitmap.GetWidth() > mBlockSizes[ currentBlockSize ].mNeededBlockWidth ) + { + setSize = true; + mBlockSizes[ currentBlockSize ].mNeededBlockWidth = bitmap.GetWidth(); + } + if ( bitmap.GetHeight() > mBlockSizes[ currentBlockSize ].mNeededBlockHeight ) + { + setSize = true; + mBlockSizes[ currentBlockSize ].mNeededBlockHeight = bitmap.GetHeight(); + } + + if ( setSize ) + { + mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_WIDTH, + DEFAULT_ATLAS_HEIGHT, + mBlockSizes[ currentBlockSize ].mNeededBlockWidth, + mBlockSizes[ currentBlockSize ].mNeededBlockHeight ); + } + // Locate a new slot for our glyph mGlyphManager.Add( glyph, bitmap, slot ); @@ -224,6 +247,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker currentUnderlinePosition, currentUnderlineThickness, slot ); + lastFontId = glyph.fontId; } } @@ -240,6 +264,9 @@ struct AtlasRenderer::Impl : public ConnectionTracker { MeshActor actor = MeshActor::New( Mesh::New( mIt->mMeshData ) ); actor.SetColor( mIt->mColor ); + + // Ensure that text rendering is unfiltered + actor.SetFilterMode( FilterMode::NEAREST, FilterMode::NEAREST ); if ( mIt->mIsUnderline ) { actor.SetColorMode( USE_OWN_COLOR ); @@ -286,10 +313,10 @@ struct AtlasRenderer::Impl : public ConnectionTracker 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 ].mWidth, - metrics.mAtlasMetrics.mAtlasMetrics[ i ].mHeight, - metrics.mAtlasMetrics.mAtlasMetrics[ i ].mBlockWidth, - metrics.mAtlasMetrics.mAtlasMetrics[ i ].mBlockHeight, + metrics.mAtlasMetrics.mAtlasMetrics[ i ].mSize.mWidth, + metrics.mAtlasMetrics.mAtlasMetrics[ i ].mSize.mHeight, + metrics.mAtlasMetrics.mAtlasMetrics[ i ].mSize.mBlockWidth, + metrics.mAtlasMetrics.mAtlasMetrics[ i ].mSize.mBlockHeight, metrics.mAtlasMetrics.mAtlasMetrics[ i ].mBlocksUsed, metrics.mAtlasMetrics.mAtlasMetrics[ i ].mTotalBlocks ); } @@ -419,31 +446,21 @@ struct AtlasRenderer::Impl : public ConnectionTracker MaxBlockSize maxBlockSize; for ( uint32_t i = 0; i < glyphs.Size(); ++i ) { - // Get the fontId of this glyph and check to see if a max size exists? FontId fontId = glyphs[ i ].fontId; - float paddedWidth = glyphs[ i ].width + PADDING.x; - float paddedHeight = glyphs[ i ].height + PADDING.y; bool foundFont = false; - for ( uint32_t j = 0; j < mBlockSizes.size(); ++j ) { if ( mBlockSizes[ j ].mFontId == fontId ) { foundFont = true; - if ( mBlockSizes[ j ].mNeededBlockSize.x < paddedWidth ) - { - mBlockSizes[ j ].mNeededBlockSize.x = paddedWidth; - } - if ( mBlockSizes[ j ].mNeededBlockSize.y < paddedHeight ) - { - mBlockSizes[ j ].mNeededBlockSize.y = paddedHeight; - } } } - if ( !foundFont ) { - maxBlockSize.mNeededBlockSize = Vector2( paddedWidth, paddedHeight ); + FontMetrics fontMetrics; + mFontClient.GetFontMetrics( fontId, fontMetrics ); + maxBlockSize.mNeededBlockWidth = static_cast< uint32_t >( fontMetrics.height ); + maxBlockSize.mNeededBlockHeight = static_cast< uint32_t >( fontMetrics.height ); maxBlockSize.mFontId = fontId; mBlockSizes.push_back( maxBlockSize ); } -- 2.7.4