Merge "Stop setting crazy Z value with controls (at the moment depth is ignored by...
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / rendering / atlas / atlas-glyph-manager-impl.cpp
1  /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 // CLASS HEADER
18 #include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h>
19
20 // EXTERNAL INCLUDES
21 #include <dali/integration-api/debug.h>
22
23 #define MAKE_SHADER(A)#A
24
25 namespace
26 {
27
28 #if defined(DEBUG_ENABLED)
29   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING");
30 #endif
31
32 const char* VERTEX_SHADER = MAKE_SHADER(
33 attribute mediump vec2    aPosition;
34 attribute mediump vec2    aTexCoord;
35 uniform   mediump mat4    uMvpMatrix;
36 varying   mediump vec2    vTexCoord;
37
38 void main()
39 {
40   mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
41   gl_Position = uMvpMatrix * position;
42   vTexCoord = aTexCoord;
43 }
44 );
45
46 const char* FRAGMENT_SHADER = MAKE_SHADER(
47 uniform         sampler2D sTexture;
48 varying mediump vec2      vTexCoord;
49
50 void main()
51 {
52   gl_FragColor = texture2D( sTexture, vTexCoord );
53 }
54 );
55
56 const char* VERTEX_SHADER_SHADOW = MAKE_SHADER(
57 attribute mediump vec2    aPosition;
58 attribute mediump vec2    aTexCoord;
59 varying   mediump vec2    vTexCoord;
60
61 void main()
62 {
63   mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
64   gl_Position = position;
65   vTexCoord = aTexCoord;
66 }
67 );
68
69 const char* FRAGMENT_SHADER_SHADOW = MAKE_SHADER(
70 uniform         sampler2D sTexture;
71 uniform lowp    vec4      uColor;
72 varying mediump vec2      vTexCoord;
73
74 void main()
75 {
76   mediump vec4 color = texture2D( sTexture, vTexCoord );
77   gl_FragColor = vec4(uColor.rgb, uColor.a*color.r);
78 }
79 );
80
81 } // unnamed namespace
82
83 namespace Dali
84 {
85
86 namespace Toolkit
87 {
88
89 namespace Internal
90 {
91
92 AtlasGlyphManager::AtlasGlyphManager()
93 {
94   mAtlasManager = Dali::Toolkit::AtlasManager::New();
95   mEffectBufferShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
96   mShadowShader = Shader::New( VERTEX_SHADER_SHADOW, FRAGMENT_SHADER_SHADOW, Dali::Shader::HINT_MODIFIES_GEOMETRY );
97 }
98
99 void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
100                              const BufferImage& bitmap,
101                              Dali::Toolkit::AtlasManager::AtlasSlot& slot )
102 {
103   DALI_LOG_INFO( gLogFilter, Debug::General, "Added glyph, font: %d index: %d\n", glyph.fontId, glyph.index );
104
105   mAtlasManager.Add( bitmap, slot );
106
107   GlyphRecordEntry record;
108   record.mIndex = glyph.index;
109   record.mImageId = slot.mImageId;
110   record.mCount = 1;
111
112   // Have glyph records been created for this fontId ?
113   bool foundGlyph = false;
114   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
115         fontGlyphRecordIt != mFontGlyphRecords.end(); ++fontGlyphRecordIt )
116   {
117     if ( fontGlyphRecordIt->mFontId == glyph.fontId )
118     {
119       fontGlyphRecordIt->mGlyphRecords.PushBack( record );
120       foundGlyph = true;
121       break;
122     }
123   }
124
125   if ( !foundGlyph )
126   {
127     // We need to add a new font entry
128     FontGlyphRecord fontGlyphRecord;
129     fontGlyphRecord.mFontId = glyph.fontId;
130     fontGlyphRecord.mGlyphRecords.PushBack( record );
131     mFontGlyphRecords.push_back( fontGlyphRecord );
132   }
133 }
134
135 void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
136                                           const Vector2& position,
137                                           Toolkit::AtlasManager::Mesh2D& mesh )
138 {
139   // Generate mesh data and tell Atlas Manager not to handle reference counting ( we'll do it )
140   mAtlasManager.GenerateMeshData( imageId, position, mesh, false );
141 }
142
143 void AtlasGlyphManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
144                                     const Toolkit::AtlasManager::Mesh2D& second )
145 {
146   mAtlasManager.StitchMesh( first, second );
147 }
148
149 bool AtlasGlyphManager::Cached( Text::FontId fontId,
150                                 Text::GlyphIndex index,
151                                 Dali::Toolkit::AtlasManager::AtlasSlot& slot )
152 {
153   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
154         fontGlyphRecordIt != mFontGlyphRecords.end();
155         ++fontGlyphRecordIt )
156   {
157     if ( fontGlyphRecordIt->mFontId == fontId )
158     {
159       for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
160             glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
161             ++glyphRecordIt )
162       {
163         if ( glyphRecordIt->mIndex == index )
164         {
165           slot.mImageId = glyphRecordIt->mImageId;
166           slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
167           return true;
168         }
169       }
170     }
171   }
172   slot.mImageId = 0;
173   return false;
174 }
175
176 Vector2 AtlasGlyphManager::GetAtlasSize( uint32_t atlasId )
177 {
178   Toolkit::AtlasManager::AtlasSize size = mAtlasManager.GetAtlasSize( atlasId );
179   return Vector2( static_cast< float >( size.mWidth ), static_cast< float >( size.mHeight ) );
180 }
181
182 void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight )
183 {
184   Toolkit::AtlasManager::AtlasSize size;
185   size.mWidth = width;
186   size.mHeight = height;
187   size.mBlockWidth = blockWidth;
188   size.mBlockHeight = blockHeight;
189   mAtlasManager.SetNewAtlasSize( size );
190 }
191
192 Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
193 {
194   return mAtlasManager.GetPixelFormat( atlasId );
195 }
196
197 const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
198 {
199   std::ostringstream verboseMetrics;
200
201   mMetrics.mGlyphCount = 0u;
202   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
203         fontGlyphRecordIt != mFontGlyphRecords.end();
204         ++fontGlyphRecordIt )
205   {
206     mMetrics.mGlyphCount += fontGlyphRecordIt->mGlyphRecords.Size();
207
208     verboseMetrics << "[FontId " << fontGlyphRecordIt->mFontId << " Glyph ";
209     for ( Vector< GlyphRecordEntry >::Iterator glyphRecordEntryIt = fontGlyphRecordIt->mGlyphRecords.Begin();
210           glyphRecordEntryIt != fontGlyphRecordIt->mGlyphRecords.End();
211           ++glyphRecordEntryIt )
212     {
213       verboseMetrics << glyphRecordEntryIt->mIndex << "(" << glyphRecordEntryIt->mCount << ") ";
214     }
215     verboseMetrics << "] ";
216   }
217   mMetrics.mVerboseGlyphCounts = verboseMetrics.str();
218
219   mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
220
221   return mMetrics;
222 }
223
224 void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta )
225 {
226   if( 0 != delta )
227   {
228     DALI_LOG_INFO( gLogFilter, Debug::General, "AdjustReferenceCount %d, font: %d index: %d\n", delta, fontId, index );
229
230     for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
231           fontGlyphRecordIt != mFontGlyphRecords.end();
232           ++fontGlyphRecordIt )
233     {
234       if ( fontGlyphRecordIt->mFontId == fontId )
235       {
236         for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
237               glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
238               ++glyphRecordIt )
239         {
240           if ( glyphRecordIt->mIndex == index )
241           {
242             glyphRecordIt->mCount += delta;
243             DALI_ASSERT_DEBUG( glyphRecordIt->mCount >= 0 && "Glyph ref-count should not be negative" );
244
245             if ( !glyphRecordIt->mCount )
246             {
247               mAtlasManager.Remove( glyphRecordIt->mImageId );
248               fontGlyphRecordIt->mGlyphRecords.Remove( glyphRecordIt );
249             }
250             return;
251           }
252         }
253       }
254     }
255
256     // Should not arrive here
257     DALI_ASSERT_DEBUG( false && "Failed to adjust ref-count" );
258   }
259 }
260
261 Material AtlasGlyphManager::GetMaterial( uint32_t atlasId ) const
262 {
263   return mAtlasManager.GetMaterial( atlasId );
264 }
265
266 Sampler AtlasGlyphManager::GetSampler( uint32_t atlasId ) const
267 {
268   return mAtlasManager.GetSampler( atlasId );
269 }
270
271 AtlasGlyphManager::~AtlasGlyphManager()
272 {
273   // mAtlasManager handle is automatically released here
274 }
275
276 } // namespace Internal
277
278 } // namespace Toolkit
279
280 } // namespace Dali