2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h>
21 #include <dali/integration-api/debug.h>
26 #if defined(DEBUG_ENABLED)
27 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING");
30 #define MAKE_SHADER(A)#A
32 const char* VERTEX_SHADER = MAKE_SHADER(
33 attribute mediump vec2 aPosition;
34 attribute mediump vec2 aTexCoord;
35 attribute mediump vec4 aColor;
36 uniform mediump vec2 uOffset;
37 uniform mediump mat4 uMvpMatrix;
38 varying mediump vec2 vTexCoord;
39 varying mediump vec4 vColor;
43 mediump vec4 position = vec4( aPosition.xy + uOffset, 0.0, 1.0 );
44 gl_Position = uMvpMatrix * position;
45 vTexCoord = aTexCoord;
50 const char* FRAGMENT_SHADER_L8 = MAKE_SHADER(
51 uniform lowp vec4 uColor;
52 uniform sampler2D sTexture;
53 varying mediump vec2 vTexCoord;
54 varying mediump vec4 vColor;
58 mediump vec4 color = texture2D( sTexture, vTexCoord );
59 gl_FragColor = vec4( vColor.rgb * uColor.rgb, vColor.a * uColor.a * color.r );
63 const char* FRAGMENT_SHADER_RGBA = MAKE_SHADER(
64 uniform sampler2D sTexture;
65 varying mediump vec2 vTexCoord;
69 gl_FragColor = texture2D( sTexture, vTexCoord );
73 } // unnamed namespace
84 AtlasGlyphManager::AtlasGlyphManager()
86 mShaderL8 = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_L8 );
87 mShaderRgba = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_RGBA );
88 mAtlasManager = Dali::Toolkit::AtlasManager::New();
91 void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
92 const PixelData& bitmap,
93 Dali::Toolkit::AtlasManager::AtlasSlot& slot )
95 DALI_LOG_INFO( gLogFilter, Debug::General, "Added glyph, font: %d index: %d\n", glyph.fontId, glyph.index );
97 if ( mAtlasManager.Add( bitmap, slot ) )
99 // A new atlas was created so set the texture set details for the atlas
100 Dali::Texture atlas = mAtlasManager.GetAtlasContainer( slot.mAtlasId );
101 TextureSet textureSet = TextureSet::New();
102 textureSet.SetTexture( 0u, atlas );
103 mAtlasManager.SetTextures( slot.mAtlasId, textureSet );
106 GlyphRecordEntry record;
107 record.mIndex = glyph.index;
108 record.mImageId = slot.mImageId;
111 // Have glyph records been created for this fontId ?
112 bool foundGlyph = false;
113 for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
114 fontGlyphRecordIt != mFontGlyphRecords.end(); ++fontGlyphRecordIt )
116 if ( fontGlyphRecordIt->mFontId == glyph.fontId )
118 fontGlyphRecordIt->mGlyphRecords.PushBack( record );
126 // We need to add a new font entry
127 FontGlyphRecord fontGlyphRecord;
128 fontGlyphRecord.mFontId = glyph.fontId;
129 fontGlyphRecord.mGlyphRecords.PushBack( record );
130 mFontGlyphRecords.push_back( fontGlyphRecord );
134 void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
135 const Vector2& position,
136 Toolkit::AtlasManager::Mesh2D& mesh )
138 // Generate mesh data and tell Atlas Manager not to handle reference counting ( we'll do it )
139 mAtlasManager.GenerateMeshData( imageId, position, mesh, false );
142 bool AtlasGlyphManager::IsCached( Text::FontId fontId,
143 Text::GlyphIndex index,
144 Dali::Toolkit::AtlasManager::AtlasSlot& slot )
146 for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
147 fontGlyphRecordIt != mFontGlyphRecords.end();
148 ++fontGlyphRecordIt )
150 if ( fontGlyphRecordIt->mFontId == fontId )
152 for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
153 glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
156 if ( glyphRecordIt->mIndex == index )
158 slot.mImageId = glyphRecordIt->mImageId;
159 slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
169 Vector2 AtlasGlyphManager::GetAtlasSize( uint32_t atlasId )
171 Toolkit::AtlasManager::AtlasSize size = mAtlasManager.GetAtlasSize( atlasId );
172 return Vector2( static_cast< float >( size.mWidth ), static_cast< float >( size.mHeight ) );
175 void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight )
177 Toolkit::AtlasManager::AtlasSize size;
179 size.mHeight = height;
180 size.mBlockWidth = blockWidth;
181 size.mBlockHeight = blockHeight;
182 mAtlasManager.SetNewAtlasSize( size );
185 Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
187 return mAtlasManager.GetPixelFormat( atlasId );
190 const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
192 std::ostringstream verboseMetrics;
194 mMetrics.mGlyphCount = 0u;
195 for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
196 fontGlyphRecordIt != mFontGlyphRecords.end();
197 ++fontGlyphRecordIt )
199 mMetrics.mGlyphCount += fontGlyphRecordIt->mGlyphRecords.Size();
201 verboseMetrics << "[FontId " << fontGlyphRecordIt->mFontId << " Glyph ";
202 for ( Vector< GlyphRecordEntry >::Iterator glyphRecordEntryIt = fontGlyphRecordIt->mGlyphRecords.Begin();
203 glyphRecordEntryIt != fontGlyphRecordIt->mGlyphRecords.End();
204 ++glyphRecordEntryIt )
206 verboseMetrics << glyphRecordEntryIt->mIndex << "(" << glyphRecordEntryIt->mCount << ") ";
208 verboseMetrics << "] ";
210 mMetrics.mVerboseGlyphCounts = verboseMetrics.str();
212 mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
217 void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta )
221 DALI_LOG_INFO( gLogFilter, Debug::General, "AdjustReferenceCount %d, font: %d index: %d\n", delta, fontId, index );
223 for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
224 fontGlyphRecordIt != mFontGlyphRecords.end();
225 ++fontGlyphRecordIt )
227 if ( fontGlyphRecordIt->mFontId == fontId )
229 for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
230 glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
233 if ( glyphRecordIt->mIndex == index )
235 glyphRecordIt->mCount += delta;
236 DALI_ASSERT_DEBUG( glyphRecordIt->mCount >= 0 && "Glyph ref-count should not be negative" );
238 if ( !glyphRecordIt->mCount )
240 mAtlasManager.Remove( glyphRecordIt->mImageId );
241 fontGlyphRecordIt->mGlyphRecords.Remove( glyphRecordIt );
249 // Should not arrive here
250 DALI_ASSERT_DEBUG( false && "Failed to adjust ref-count" );
254 TextureSet AtlasGlyphManager::GetTextures( uint32_t atlasId ) const
256 return mAtlasManager.GetTextures( atlasId );
259 Shader AtlasGlyphManager::GetShader( uint32_t atlasId ) const
261 Pixel::Format pixelFormat = mAtlasManager.GetPixelFormat( atlasId );
262 return pixelFormat == Pixel::L8 ? mShaderL8 : mShaderRgba;
265 AtlasGlyphManager::~AtlasGlyphManager()
267 // mAtlasManager handle is automatically released here
270 } // namespace Internal
272 } // namespace Toolkit