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/public-api/actors/image-actor.h>
22 #include <dali/public-api/common/stage.h>
23 #include <dali/integration-api/debug.h>
25 #define MAKE_SHADER(A)#A
30 #if defined(DEBUG_ENABLED)
31 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING");
34 const char* VERTEX_SHADER = MAKE_SHADER(
35 attribute mediump vec2 aPosition;
36 attribute mediump vec2 aTexCoord;
37 uniform mediump mat4 uMvpMatrix;
38 varying mediump vec2 vTexCoord;
42 mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
43 gl_Position = uMvpMatrix * position;
44 vTexCoord = aTexCoord;
48 const char* FRAGMENT_SHADER = MAKE_SHADER(
49 uniform sampler2D sTexture;
50 varying mediump vec2 vTexCoord;
54 gl_FragColor = texture2D( sTexture, vTexCoord );
58 const char* VERTEX_SHADER_SHADOW = MAKE_SHADER(
59 attribute mediump vec2 aPosition;
60 attribute mediump vec2 aTexCoord;
61 varying mediump vec2 vTexCoord;
65 mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
66 gl_Position = position;
67 vTexCoord = aTexCoord;
71 const char* FRAGMENT_SHADER_SHADOW = MAKE_SHADER(
72 uniform sampler2D sTexture;
73 uniform lowp vec4 uColor;
74 varying mediump vec2 vTexCoord;
78 mediump vec4 color = texture2D( sTexture, vTexCoord );
79 gl_FragColor = vec4(uColor.rgb, uColor.a*color.r);
83 } // unnamed namespace
94 AtlasGlyphManager::AtlasGlyphManager()
96 mAtlasManager = Dali::Toolkit::AtlasManager::New();
97 mEffectBufferShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
98 mShadowShader = Shader::New( VERTEX_SHADER_SHADOW, FRAGMENT_SHADER_SHADOW, Dali::Shader::HINT_MODIFIES_GEOMETRY );
101 void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
102 const BufferImage& bitmap,
103 Dali::Toolkit::AtlasManager::AtlasSlot& slot )
105 DALI_LOG_INFO( gLogFilter, Debug::General, "Added glyph, font: %d index: %d\n", glyph.fontId, glyph.index );
107 mAtlasManager.Add( bitmap, slot );
109 GlyphRecordEntry record;
110 record.mIndex = glyph.index;
111 record.mImageId = slot.mImageId;
114 // Have glyph records been created for this fontId ?
115 bool foundGlyph = false;
116 for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
117 fontGlyphRecordIt != mFontGlyphRecords.end(); ++fontGlyphRecordIt )
119 if ( fontGlyphRecordIt->mFontId == glyph.fontId )
121 fontGlyphRecordIt->mGlyphRecords.PushBack( record );
129 // We need to add a new font entry
130 FontGlyphRecord fontGlyphRecord;
131 fontGlyphRecord.mFontId = glyph.fontId;
132 fontGlyphRecord.mGlyphRecords.PushBack( record );
133 mFontGlyphRecords.push_back( fontGlyphRecord );
137 void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
138 const Vector2& position,
139 Toolkit::AtlasManager::Mesh2D& mesh )
141 // Generate mesh data and tell Atlas Manager not to handle reference counting ( we'll do it )
142 mAtlasManager.GenerateMeshData( imageId, position, mesh, false );
145 void AtlasGlyphManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
146 const Toolkit::AtlasManager::Mesh2D& second )
148 mAtlasManager.StitchMesh( first, second );
151 bool AtlasGlyphManager::Cached( Text::FontId fontId,
152 Text::GlyphIndex index,
153 Dali::Toolkit::AtlasManager::AtlasSlot& slot )
155 for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
156 fontGlyphRecordIt != mFontGlyphRecords.end();
157 ++fontGlyphRecordIt )
159 if ( fontGlyphRecordIt->mFontId == fontId )
161 for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
162 glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
165 if ( glyphRecordIt->mIndex == index )
167 slot.mImageId = glyphRecordIt->mImageId;
168 slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
178 Vector2 AtlasGlyphManager::GetAtlasSize( uint32_t atlasId )
180 Toolkit::AtlasManager::AtlasSize size = mAtlasManager.GetAtlasSize( atlasId );
181 return Vector2( static_cast< float >( size.mWidth ), static_cast< float >( size.mHeight ) );
184 void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight )
186 Toolkit::AtlasManager::AtlasSize size;
188 size.mHeight = height;
189 size.mBlockWidth = blockWidth;
190 size.mBlockHeight = blockHeight;
191 mAtlasManager.SetNewAtlasSize( size );
194 Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
196 return mAtlasManager.GetPixelFormat( atlasId );
199 const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
201 std::ostringstream verboseMetrics;
203 mMetrics.mGlyphCount = 0u;
204 for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
205 fontGlyphRecordIt != mFontGlyphRecords.end();
206 ++fontGlyphRecordIt )
208 mMetrics.mGlyphCount += fontGlyphRecordIt->mGlyphRecords.Size();
210 verboseMetrics << "[FontId " << fontGlyphRecordIt->mFontId << " Glyph ";
211 for ( Vector< GlyphRecordEntry >::Iterator glyphRecordEntryIt = fontGlyphRecordIt->mGlyphRecords.Begin();
212 glyphRecordEntryIt != fontGlyphRecordIt->mGlyphRecords.End();
213 ++glyphRecordEntryIt )
215 verboseMetrics << glyphRecordEntryIt->mIndex << "(" << glyphRecordEntryIt->mCount << ") ";
217 verboseMetrics << "] ";
219 mMetrics.mVerboseGlyphCounts = verboseMetrics.str();
221 mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
226 void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta )
230 DALI_LOG_INFO( gLogFilter, Debug::General, "AdjustReferenceCount %d, font: %d index: %d\n", delta, fontId, index );
232 for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
233 fontGlyphRecordIt != mFontGlyphRecords.end();
234 ++fontGlyphRecordIt )
236 if ( fontGlyphRecordIt->mFontId == fontId )
238 for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
239 glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
242 if ( glyphRecordIt->mIndex == index )
244 glyphRecordIt->mCount += delta;
245 DALI_ASSERT_DEBUG( glyphRecordIt->mCount >= 0 && "Glyph ref-count should not be negative" );
247 if ( !glyphRecordIt->mCount )
249 mAtlasManager.Remove( glyphRecordIt->mImageId );
250 fontGlyphRecordIt->mGlyphRecords.Remove( glyphRecordIt );
258 // Should not arrive here
259 DALI_ASSERT_DEBUG( false && "Failed to adjust ref-count" );
263 Material AtlasGlyphManager::GetMaterial( uint32_t atlasId ) const
265 return mAtlasManager.GetMaterial( atlasId );
268 Sampler AtlasGlyphManager::GetSampler( uint32_t atlasId ) const
270 return mAtlasManager.GetSampler( atlasId );
273 AtlasGlyphManager::~AtlasGlyphManager()
275 // mAtlasManager handle is automatically released here
278 } // namespace Internal
280 } // namespace Toolkit