#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>
-
-#define MAKE_SHADER(A)#A
+#include <dali/integration-api/debug.h>
namespace
{
+
+#if defined(DEBUG_ENABLED)
+ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING");
+#endif
+
+#define MAKE_SHADER(A)#A
+
const char* VERTEX_SHADER = MAKE_SHADER(
attribute mediump vec2 aPosition;
attribute mediump vec2 aTexCoord;
+attribute mediump vec4 aColor;
+uniform mediump vec2 uOffset;
uniform mediump mat4 uMvpMatrix;
-uniform mediump vec3 uSize;
varying mediump vec2 vTexCoord;
+varying mediump vec4 vColor;
void main()
{
- mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
- position.xyz *= uSize;
+ mediump vec4 position = vec4( aPosition.xy + uOffset, 0.0, 1.0 );
gl_Position = uMvpMatrix * position;
vTexCoord = aTexCoord;
+ vColor = aColor;
}
);
-const char* FRAGMENT_SHADER = MAKE_SHADER(
+const char* FRAGMENT_SHADER_L8 = MAKE_SHADER(
+uniform lowp vec4 uColor;
uniform sampler2D sTexture;
varying mediump vec2 vTexCoord;
+varying mediump vec4 vColor;
void main()
{
- gl_FragColor = texture2D( sTexture, vTexCoord );
-}
-);
-
-const char* VERTEX_SHADER_SHADOW = MAKE_SHADER(
-attribute mediump vec2 aPosition;
-attribute mediump vec2 aTexCoord;
-uniform mediump vec3 uSize;
-varying mediump vec2 vTexCoord;
-
-void main()
-{
- mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
- position.xyz *= uSize;
- gl_Position = position;
- vTexCoord = aTexCoord;
+ mediump vec4 color = texture2D( sTexture, vTexCoord );
+ gl_FragColor = vec4( vColor.rgb * uColor.rgb, vColor.a * uColor.a * color.r );
}
);
-const char* FRAGMENT_SHADER_SHADOW = MAKE_SHADER(
+const char* FRAGMENT_SHADER_RGBA = MAKE_SHADER(
uniform sampler2D sTexture;
-uniform lowp vec4 uColor;
varying mediump vec2 vTexCoord;
void main()
{
- mediump vec4 color = texture2D( sTexture, vTexCoord );
- gl_FragColor = vec4(uColor.rgb, uColor.a*color.r);
+ gl_FragColor = texture2D( sTexture, vTexCoord );
}
);
-}
+
+} // unnamed namespace
namespace Dali
{
AtlasGlyphManager::AtlasGlyphManager()
{
+ mShaderL8 = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_L8 );
+ mShaderRgba = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_RGBA );
mAtlasManager = Dali::Toolkit::AtlasManager::New();
- mEffectBufferShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
- mShadowShader = Shader::New( VERTEX_SHADER_SHADOW, FRAGMENT_SHADER_SHADOW, Dali::Shader::HINT_MODIFIES_GEOMETRY );
-}
-
-AtlasGlyphManager::~AtlasGlyphManager()
-{
- // Clear up any remaining references
- for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
- fontGlyphRecordIt != mFontGlyphRecords.end();
- ++fontGlyphRecordIt )
- {
- for ( Vector< GlyphRecordEntry >::Iterator glyphRecordEntryIt = fontGlyphRecordIt->mGlyphRecords.Begin();
- glyphRecordEntryIt != fontGlyphRecordIt->mGlyphRecords.End();
- ++glyphRecordEntryIt )
- {
- mAtlasManager.Remove( glyphRecordEntryIt->mImageId );
- }
- }
-}
-
-AtlasGlyphManagerPtr AtlasGlyphManager::New()
-{
- AtlasGlyphManagerPtr internal = new AtlasGlyphManager();
- return internal;
}
-void AtlasGlyphManager::Add( Text::FontId fontId,
- const Text::GlyphInfo& glyph,
+void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
const BufferImage& bitmap,
Dali::Toolkit::AtlasManager::AtlasSlot& slot )
{
- mAtlasManager.Add( bitmap, slot );
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Added glyph, font: %d index: %d\n", glyph.fontId, glyph.index );
+
+ if ( mAtlasManager.Add( bitmap, slot ) )
+ {
+ // A new atlas was created so set the material details for the atlas
+ Dali::Atlas atlas = mAtlasManager.GetAtlasContainer( slot.mAtlasId );
+ Pixel::Format pixelFormat = mAtlasManager.GetPixelFormat( slot.mAtlasId );
+ Material material = Material::New( pixelFormat == Pixel::L8 ? mShaderL8 : mShaderRgba );
+ material.AddTexture( atlas, "sTexture" );
+ material.SetBlendMode( BlendingMode::ON );
+ mAtlasManager.SetMaterial( slot.mAtlasId, material );
+ }
GlyphRecordEntry record;
record.mIndex = glyph.index;
for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
fontGlyphRecordIt != mFontGlyphRecords.end(); ++fontGlyphRecordIt )
{
- if ( fontGlyphRecordIt->mFontId == fontId )
+ if ( fontGlyphRecordIt->mFontId == glyph.fontId )
{
fontGlyphRecordIt->mGlyphRecords.PushBack( record );
foundGlyph = true;
{
// We need to add a new font entry
FontGlyphRecord fontGlyphRecord;
- fontGlyphRecord.mFontId = fontId;
+ fontGlyphRecord.mFontId = glyph.fontId;
fontGlyphRecord.mGlyphRecords.PushBack( record );
mFontGlyphRecords.push_back( fontGlyphRecord );
}
mAtlasManager.GenerateMeshData( imageId, position, mesh, false );
}
-void AtlasGlyphManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
- const Toolkit::AtlasManager::Mesh2D& second )
-{
- mAtlasManager.StitchMesh( first, second );
-}
-
-bool AtlasGlyphManager::Cached( Text::FontId fontId,
- uint32_t index,
+bool AtlasGlyphManager::IsCached( Text::FontId fontId,
+ Text::GlyphIndex index,
Dali::Toolkit::AtlasManager::AtlasSlot& slot )
{
for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
{
- mMetrics.mGlyphCount = mFontGlyphRecords.size();
+ 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::AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta )
+void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta )
{
- for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
- fontGlyphRecordIt != mFontGlyphRecords.end();
- ++fontGlyphRecordIt )
+ if( 0 != delta )
{
- if ( fontGlyphRecordIt->mFontId == fontId )
+ 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 )
{
- for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
- glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
- ++glyphRecordIt )
+ if ( fontGlyphRecordIt->mFontId == fontId )
{
- if ( glyphRecordIt->mImageId == imageId )
+ for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+ glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
+ ++glyphRecordIt )
{
- glyphRecordIt->mCount += delta;
- if ( !glyphRecordIt->mCount )
+ if ( glyphRecordIt->mIndex == index )
{
- mAtlasManager.Remove( glyphRecordIt->mImageId );
- fontGlyphRecordIt->mGlyphRecords.Remove( glyphRecordIt );
+ 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;
}
- return;
}
}
}
+
+ // Should not arrive here
+ DALI_ASSERT_DEBUG( false && "Failed to adjust ref-count" );
}
}
return mAtlasManager.GetMaterial( atlasId );
}
-Sampler AtlasGlyphManager::GetSampler( uint32_t atlasId ) const
+AtlasGlyphManager::~AtlasGlyphManager()
{
- return mAtlasManager.GetSampler( atlasId );
+ // mAtlasManager handle is automatically released here
}
} // namespace Internal