From: Paul Wisbey
Date: Tue, 10 Mar 2015 14:13:45 +0000 (-0700)
Subject: Merge "TextModel - Clear the buffers if the number of items is zero." into new_text
X-Git-Tag: new_text_0.1~4
X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=bc3f6676e011edfad5d5c40558e7250e9b50e015;hp=479e2b5a95c62cf2b6d39c4499e11aab49ded6cb
Merge "TextModel - Clear the buffers if the number of items is zero." into new_text
---
diff --git a/dali-toolkit/internal/text/rendering/basic/text-basic-renderer.cpp b/dali-toolkit/internal/text/rendering/basic/text-basic-renderer.cpp
index 4521d94..ac95892 100644
--- a/dali-toolkit/internal/text/rendering/basic/text-basic-renderer.cpp
+++ b/dali-toolkit/internal/text/rendering/basic/text-basic-renderer.cpp
@@ -20,6 +20,7 @@
// INTERNAL INCLUDES
#include
+#include
#include
#include
#include
@@ -50,9 +51,9 @@ struct TextureCoordinates
Vector2 bottomRight;
};
-struct AtlasHelperGlyph
+struct AtlasGlyph
{
- AtlasHelperGlyph()
+ AtlasGlyph()
: fontId( 0 ),
index( 0 ),
xOffset( 0 ),
@@ -61,16 +62,18 @@ struct AtlasHelperGlyph
{
}
- AtlasHelperGlyph( FontId id,
- GlyphIndex glyphIndex,
- std::size_t offset,
- std::size_t widthPixels,
- std::size_t heightPixels )
+ AtlasGlyph( FontId id,
+ GlyphIndex glyphIndex,
+ std::size_t offset,
+ std::size_t widthPixels,
+ std::size_t heightPixels,
+ BufferImage bitmap )
: fontId( id ),
index( glyphIndex ),
xOffset( offset ),
width( widthPixels ),
- height( heightPixels )
+ height( heightPixels ),
+ mBitmap( bitmap )
{
}
@@ -79,140 +82,179 @@ struct AtlasHelperGlyph
std::size_t xOffset;
std::size_t width;
std::size_t height;
+ BufferImage mBitmap;
TextureCoordinates coords;
};
-struct AtlasHelper
+} // unnamed namespace
+
+struct BasicRenderer::Impl
{
- AtlasHelper()
- : mWidth( 0.0f ),
- mHeight( 0.0f )
+ /**
+ * @brief Create the renderer implementation.
+ */
+ Impl()
+ : mWidthL8( 0.0f ),
+ mHeightL8( 0.0f ),
+ mWidthBGRA8888( 0.0f ),
+ mHeightBGRA8888( 0.0f )
{
mFontClient = TextAbstraction::FontClient::Get();
}
- void Reset()
+ /**
+ * @brief Reset the previous glyph calculations.
+ *
+ * @param[in] size The glyph space to reserve.
+ */
+ void Reset( std::size_t size )
{
- mWidth = 0.0f;
- mHeight = 0.0f;
+ mWidthL8 = 0.0f;
+ mHeightL8 = 0.0f;
+ mWidthBGRA8888 = 0.0f;
+ mHeightBGRA8888 = 0.0f;
mGlyphs.clear();
- }
-
- void Reserve( std::size_t size )
- {
mGlyphs.reserve( size );
+ mAtlasL8.Reset();
+ mAtlasBGRA8888.Reset();
}
- bool GlyphFound( FontId fontId, GlyphIndex index ) const
+ /**
+ * @brief Ccreate an Atlas, uploading the necessary glyph bitmaps
+ *
+ * @param[in] glyphs The glyphs to upload.
+ */
+ void CreateAtlases( const Vector& glyphs )
{
- for( unsigned int i=0; i 0 &&
+ height > 0 ) // skip whitespace
{
- return true;
+ if( !GlyphFound( glyphs[i].fontId, glyphs[i].index ) )
+ {
+ AddGlyph( glyphs[i] );
+ }
}
}
- return false;
+ mAtlasL8 = CreateAtlas( mWidthL8, mHeightL8, Pixel::L8 );
+ mAtlasBGRA8888 = CreateAtlas( mWidthBGRA8888, mHeightBGRA8888, Pixel::BGRA8888 );
}
- void AddGlyph( const GlyphInfo& glyphInfo )
+ Atlas CreateAtlas( unsigned int width, unsigned int height, Pixel::Format format )
{
- mGlyphs.push_back( AtlasHelperGlyph( glyphInfo.fontId, glyphInfo.index, mWidth, glyphInfo.width, glyphInfo.height ) );
+ Atlas atlas;
- mWidth += glyphInfo.width + PADDING;
- if( mHeight < glyphInfo.height + PADDING )
+ if( width > 0 && height > 0 )
{
- mHeight = glyphInfo.height + PADDING;
- }
- }
+ atlas = Atlas::New( width, height, format );
- Atlas CreateAtlas()
- {
- Atlas atlas = Atlas::New( mWidth, mHeight, Pixel::L8 );
+ for( unsigned int i=0; i(glyph.xOffset) / static_cast(mWidth);
- coords.topLeft.y = 0.0f;
- coords.topRight.x = static_cast(glyph.xOffset + glyph.width) / static_cast(mWidth);
- coords.topRight.y = 0.0f;
- coords.bottomLeft.x = static_cast(glyph.xOffset) / static_cast(mWidth);
- coords.bottomLeft.y = static_cast(glyph.height) / static_cast(mHeight);
- coords.bottomRight.x = static_cast(glyph.xOffset + glyph.width) / static_cast(mWidth);
- coords.bottomRight.y = static_cast(glyph.height) / static_cast(mHeight);
+ const Pixel::Format glyphFormat = glyph.mBitmap.GetPixelFormat();
+
+ if( format == glyphFormat )
+ {
+ atlas.Upload( glyph.mBitmap, glyph.xOffset, 0 );
+
+ TextureCoordinates& coords = glyph.coords;
+ coords.topLeft.x = static_cast(glyph.xOffset) / static_cast(width);
+ coords.topLeft.y = 0.0f;
+ coords.topRight.x = static_cast(glyph.xOffset + glyph.width) / static_cast(width);
+ coords.topRight.y = 0.0f;
+ coords.bottomLeft.x = static_cast(glyph.xOffset) / static_cast(width);
+ coords.bottomLeft.y = static_cast(glyph.height) / static_cast(height);
+ coords.bottomRight.x = static_cast(glyph.xOffset + glyph.width) / static_cast(width);
+ coords.bottomRight.y = static_cast(glyph.height) / static_cast(height);
+ }
+ }
}
return atlas;
}
- void GetTextureCoordinates( FontId fontId, GlyphIndex index, TextureCoordinates& coords )
+ /**
+ * @brief Check whether we already have the glyph.
+ */
+ bool GlyphFound( FontId fontId, GlyphIndex index ) const
{
for( unsigned int i=0; i mGlyphs;
+ if( Pixel::L8 == format )
+ {
+ mGlyphs.push_back( AtlasGlyph( glyphInfo.fontId, glyphInfo.index, mWidthL8, glyphInfo.width, glyphInfo.height, bitmap ) );
- TextAbstraction::FontClient mFontClient;
-};
+ // Increase the Atlas width/height
+ mWidthL8 += glyphInfo.width + PADDING;
+ if( mHeightL8 < glyphInfo.height + PADDING )
+ {
+ mHeightL8 = glyphInfo.height + PADDING;
+ }
+ }
+ else if ( Pixel::BGRA8888 == format )
+ {
+ mGlyphs.push_back( AtlasGlyph( glyphInfo.fontId, glyphInfo.index, mWidthBGRA8888, glyphInfo.width, glyphInfo.height, bitmap ) );
-} // unnamed namespace
+ // A separate Atlas is used for color Emojis
+ mWidthBGRA8888 += glyphInfo.width + PADDING;
+ if( mHeightBGRA8888 < glyphInfo.height + PADDING )
+ {
+ mHeightBGRA8888 = glyphInfo.height + PADDING;
+ }
+ }
+ }
-struct BasicRenderer::Impl
-{
/**
- * @brief Ccreate an Atlas, uploading the necessary glyph bitmaps
- *
- * @param[in] glyphs The glyphs to upload.
+ * @brief Get the texture coordinates for a glyph.
*/
- Atlas CreateAtlas( const Vector& glyphs )
+ bool GetTextureCoordinates( Pixel::Format format, FontId fontId, GlyphIndex index, TextureCoordinates& coords )
{
- AtlasHelper& helper = mAtlasHelper;
-
- // Clear previous atlas
- helper.Reset();
- helper.Reserve( glyphs.Count() );
-
- for( unsigned int i=0; i 0 &&
- height > 0 ) // skip whitespace
+ const Pixel::Format glyphFormat = glyph.mBitmap.GetPixelFormat();
+
+ if( format == glyphFormat &&
+ fontId == glyph.fontId &&
+ index == glyph.index )
{
- if( !helper.GlyphFound( glyphs[i].fontId, glyphs[i].index ) )
- {
- helper.AddGlyph( glyphs[i] );
- }
+ coords = glyph.coords;
+ return true;
}
}
- // Uploads the bitmaps to Dali
- return helper.CreateAtlas();
+ return false;
}
/**
@@ -222,7 +264,7 @@ struct BasicRenderer::Impl
* @param[in] positions The 2D positions of the glyphs.
* @param[in] image The material uses this as a diffuse texture.
*/
- Mesh CreateMesh( const Vector& glyphs, const std::vector& positions, Image image )
+ Mesh CreateMesh( const Vector& glyphs, const std::vector& positions, Pixel::Format format, Image image )
{
MeshData::VertexContainer vertices( 4 * glyphs.Count() ); // 1 quad per glyph
@@ -240,15 +282,16 @@ struct BasicRenderer::Impl
const Vector2& position = positions[i];
TextureCoordinates coords;
- mAtlasHelper.GetTextureCoordinates( glyphs[i].fontId, glyphs[i].index, coords );
-
- vertices[ i*4 + 0 ] = MeshData::Vertex( Vector3( position.x + 0.0f*width, position.y + 0.0f*height, 0.0f ), coords.topLeft, Vector3( 1.0f, 0.0f, 0.0f ) );
- vertices[ i*4 + 1 ] = MeshData::Vertex( Vector3( position.x + 1.0f*width, position.y + 0.0f*height, 0.0f ), coords.topRight, Vector3( 1.0f, 1.0f, 0.0f ) );
- vertices[ i*4 + 2 ] = MeshData::Vertex( Vector3( position.x + 0.0f*width, position.y + 1.0f*height, 0.0f ), coords.bottomLeft, Vector3( 0.0f, 1.0f, 0.0f ) );
- vertices[ i*4 + 3 ] = MeshData::Vertex( Vector3( position.x + 1.0f*width, position.y + 1.0f*height, 0.0f ), coords.bottomRight, Vector3( 0.0f, 0.0f, 1.0f ) );
+ if( GetTextureCoordinates( format, glyphs[i].fontId, glyphs[i].index, coords ) )
+ {
+ vertices[ i*4 + 0 ] = MeshData::Vertex( Vector3( position.x + 0.0f*width, position.y + 0.0f*height, 0.0f ), coords.topLeft, Vector3( 1.0f, 0.0f, 0.0f ) );
+ vertices[ i*4 + 1 ] = MeshData::Vertex( Vector3( position.x + 1.0f*width, position.y + 0.0f*height, 0.0f ), coords.topRight, Vector3( 1.0f, 1.0f, 0.0f ) );
+ vertices[ i*4 + 2 ] = MeshData::Vertex( Vector3( position.x + 0.0f*width, position.y + 1.0f*height, 0.0f ), coords.bottomLeft, Vector3( 0.0f, 1.0f, 0.0f ) );
+ vertices[ i*4 + 3 ] = MeshData::Vertex( Vector3( position.x + 1.0f*width, position.y + 1.0f*height, 0.0f ), coords.bottomRight, Vector3( 0.0f, 0.0f, 1.0f ) );
- faces.push_back( i*4 + 0 ); faces.push_back( i*4 + 3 ); faces.push_back( i*4 + 1 );
- faces.push_back( i*4 + 0 ); faces.push_back( i*4 + 2 ); faces.push_back( i*4 + 3 );
+ faces.push_back( i*4 + 0 ); faces.push_back( i*4 + 3 ); faces.push_back( i*4 + 1 );
+ faces.push_back( i*4 + 0 ); faces.push_back( i*4 + 2 ); faces.push_back( i*4 + 3 );
+ }
}
}
@@ -269,7 +312,18 @@ struct BasicRenderer::Impl
RenderableActor mActor; ///< The actor which renders the text
- AtlasHelper mAtlasHelper; ///< A helper class for storing atlas positions etc.
+ Atlas mAtlasL8;
+ unsigned int mWidthL8;
+ unsigned int mHeightL8;
+
+ // A separate Atlas is used for color Emojis
+ Atlas mAtlasBGRA8888;
+ unsigned int mWidthBGRA8888;
+ unsigned int mHeightBGRA8888;
+
+ std::vector mGlyphs;
+
+ TextAbstraction::FontClient mFontClient;
};
Text::RendererPtr BasicRenderer::New()
@@ -279,6 +333,7 @@ Text::RendererPtr BasicRenderer::New()
RenderableActor BasicRenderer::Render( Text::ViewInterface& view )
{
+ // Remove the previous text
UnparentAndReset( mImpl->mActor );
Text::Length numberOfGlyphs = view.GetNumberOfGlyphs();
@@ -294,16 +349,46 @@ RenderableActor BasicRenderer::Render( Text::ViewInterface& view )
positions.resize( numberOfGlyphs );
view.GetGlyphPositions( &positions[0], 0, numberOfGlyphs );
- Atlas atlas = mImpl->CreateAtlas( glyphs );
+ mImpl->CreateAtlases( glyphs );
+
+ MeshActor actorL8;
+ if( mImpl->mAtlasL8 )
+ {
+ actorL8 = MeshActor::New( mImpl->CreateMesh( glyphs, positions, Pixel::L8, mImpl->mAtlasL8 ) );
+ actorL8.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
- MeshActor actor = MeshActor::New( mImpl->CreateMesh( glyphs, positions, atlas ) );
- actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
- actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
+ ShaderEffect shader = BasicShader::New();
+ actorL8.SetShaderEffect( shader );
+ }
- ShaderEffect shader = BasicShader::New();
- actor.SetShaderEffect( shader );
+ MeshActor actorBGRA8888;
+ if( mImpl->mAtlasBGRA8888 )
+ {
+ actorBGRA8888 = MeshActor::New( mImpl->CreateMesh( glyphs, positions, Pixel::BGRA8888, mImpl->mAtlasBGRA8888 ) );
+ actorBGRA8888.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
- mImpl->mActor = actor;
+ ShaderEffect shader = BasicShader::New();
+ actorBGRA8888.SetShaderEffect( shader );
+ }
+
+ // If we have both monochrome & color glyphs, two mesh actors are returned in a container
+ if( actorL8 && actorBGRA8888 )
+ {
+ mImpl->mActor = ImageActor::New();
+ mImpl->mActor.Add( actorL8 );
+ mImpl->mActor.Add( actorBGRA8888 );
+ }
+ else
+ {
+ if( actorL8 )
+ {
+ mImpl->mActor = actorL8;
+ }
+ else if( actorBGRA8888 )
+ {
+ mImpl->mActor = actorBGRA8888;
+ }
+ }
}
return mImpl->mActor;
diff --git a/dali-toolkit/internal/text/text-view.cpp b/dali-toolkit/internal/text/text-view.cpp
index 235f534..d12c697 100644
--- a/dali-toolkit/internal/text/text-view.cpp
+++ b/dali-toolkit/internal/text/text-view.cpp
@@ -55,7 +55,14 @@ Length View::GetNumberOfGlyphs() const
{
if( mImpl->mVisualModel )
{
- return mImpl->mVisualModel->GetNumberOfGlyphs();
+ VisualModel& model = *mImpl->mVisualModel;
+
+ Length glyphCount = model.GetNumberOfGlyphs();
+ Length positionCount = model.GetNumberOfGlyphPositions();
+
+ DALI_ASSERT_DEBUG( positionCount <= glyphCount && "Invalid glyph positions in Model" );
+
+ return (positionCount < glyphCount) ? positionCount : glyphCount;
}
return 0;
diff --git a/dali-toolkit/internal/text/visual-model.cpp b/dali-toolkit/internal/text/visual-model.cpp
index 6351ec3..9daa2d1 100644
--- a/dali-toolkit/internal/text/visual-model.cpp
+++ b/dali-toolkit/internal/text/visual-model.cpp
@@ -199,6 +199,11 @@ void VisualModel::SetGlyphPositions( const Vector2* glyphPositions,
}
}
+Length VisualModel::GetNumberOfGlyphPositions() const
+{
+ return mImpl->mGlyphPositions.Count();
+}
+
void VisualModel::GetGlyphPositions( Vector2* glyphPositions,
GlyphIndex glyphIndex,
Length numberOfGlyphs ) const
diff --git a/dali-toolkit/internal/text/visual-model.h b/dali-toolkit/internal/text/visual-model.h
index 44e42d6..9593fd8 100644
--- a/dali-toolkit/internal/text/visual-model.h
+++ b/dali-toolkit/internal/text/visual-model.h
@@ -183,6 +183,14 @@ public:
Length numberOfGlyphs );
/**
+ * Retrieves the number of glyph positions set.
+ *
+ * @note This may be less than the number of glyphs in the model.
+ * @return The number of glyphs.
+ */
+ Length GetNumberOfGlyphPositions() const;
+
+ /**
* @brief Retrieves the glyph positions.
*
* @pre The size of the @p positions buffer needs to be big enough to copy the @p numberOfGlyphs positions.