Merge "(AutomatedTests) Synchronise TestSingletonService with Adaptor" into devel...
[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/public-api/actors/image-actor.h>
22 #include <dali/public-api/common/stage.h>
23
24 #define MAKE_SHADER(A)#A
25
26 namespace
27 {
28 const char* VERTEX_SHADER = MAKE_SHADER(
29 attribute mediump vec2    aPosition;
30 attribute mediump vec2    aTexCoord;
31 uniform   mediump mat4    uMvpMatrix;
32 uniform   mediump vec3    uSize;
33 varying   mediump vec2    vTexCoord;
34
35 void main()
36 {
37   mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
38   position.xyz *= uSize;
39   gl_Position = uMvpMatrix * position;
40   vTexCoord = aTexCoord;
41 }
42 );
43
44 const char* FRAGMENT_SHADER = MAKE_SHADER(
45 uniform         sampler2D sTexture;
46 varying mediump vec2      vTexCoord;
47
48 void main()
49 {
50   gl_FragColor = texture2D( sTexture, vTexCoord );
51 }
52 );
53
54 const char* VERTEX_SHADER_SHADOW = MAKE_SHADER(
55 attribute mediump vec2    aPosition;
56 attribute mediump vec2    aTexCoord;
57 uniform   mediump vec3    uSize;
58 varying   mediump vec2    vTexCoord;
59
60 void main()
61 {
62   mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
63   position.xyz *= uSize;
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
82 namespace Dali
83 {
84
85 namespace Toolkit
86 {
87
88 namespace Internal
89 {
90
91 AtlasGlyphManager::AtlasGlyphManager()
92 {
93   mAtlasManager = Dali::Toolkit::AtlasManager::New();
94   mEffectBufferShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
95   mShadowShader = Shader::New( VERTEX_SHADER_SHADOW, FRAGMENT_SHADER_SHADOW, Dali::Shader::HINT_MODIFIES_GEOMETRY );
96 }
97
98 AtlasGlyphManager::~AtlasGlyphManager()
99 {
100   // Clear up any remaining references
101   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
102         fontGlyphRecordIt != mFontGlyphRecords.end();
103         ++fontGlyphRecordIt )
104   {
105     for ( Vector< GlyphRecordEntry >::Iterator glyphRecordEntryIt = fontGlyphRecordIt->mGlyphRecords.Begin();
106           glyphRecordEntryIt != fontGlyphRecordIt->mGlyphRecords.End();
107           ++glyphRecordEntryIt )
108     {
109       mAtlasManager.Remove( glyphRecordEntryIt->mImageId );
110     }
111   }
112 }
113
114 AtlasGlyphManagerPtr AtlasGlyphManager::New()
115 {
116   AtlasGlyphManagerPtr internal = new AtlasGlyphManager();
117   return internal;
118 }
119
120 void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
121                              const BufferImage& bitmap,
122                              Dali::Toolkit::AtlasManager::AtlasSlot& slot )
123 {
124   mAtlasManager.Add( bitmap, slot );
125
126   GlyphRecordEntry record;
127   record.mIndex = glyph.index;
128   record.mImageId = slot.mImageId;
129   record.mCount = 1;
130
131   // Have glyph records been created for this fontId ?
132   bool foundGlyph = false;
133   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
134         fontGlyphRecordIt != mFontGlyphRecords.end(); ++fontGlyphRecordIt )
135   {
136     if ( fontGlyphRecordIt->mFontId == glyph.fontId )
137     {
138       fontGlyphRecordIt->mGlyphRecords.PushBack( record );
139       foundGlyph = true;
140       break;
141     }
142   }
143
144   if ( !foundGlyph )
145   {
146     // We need to add a new font entry
147     FontGlyphRecord fontGlyphRecord;
148     fontGlyphRecord.mFontId = glyph.fontId;
149     fontGlyphRecord.mGlyphRecords.PushBack( record );
150     mFontGlyphRecords.push_back( fontGlyphRecord );
151   }
152 }
153
154 void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
155                                           const Vector2& position,
156                                           Toolkit::AtlasManager::Mesh2D& mesh )
157 {
158   // Generate mesh data and tell Atlas Manager not to handle reference counting ( we'll do it )
159   mAtlasManager.GenerateMeshData( imageId, position, mesh, false );
160 }
161
162 void AtlasGlyphManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
163                                     const Toolkit::AtlasManager::Mesh2D& second )
164 {
165   mAtlasManager.StitchMesh( first, second );
166 }
167
168 bool AtlasGlyphManager::Cached( Text::FontId fontId,
169                                 uint32_t index,
170                                 Dali::Toolkit::AtlasManager::AtlasSlot& slot )
171 {
172   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
173         fontGlyphRecordIt != mFontGlyphRecords.end();
174         ++fontGlyphRecordIt )
175   {
176     if ( fontGlyphRecordIt->mFontId == fontId )
177     {
178       for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
179             glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
180             ++glyphRecordIt )
181       {
182         if ( glyphRecordIt->mIndex == index )
183         {
184           slot.mImageId = glyphRecordIt->mImageId;
185           slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
186           return true;
187         }
188       }
189     }
190   }
191   slot.mImageId = 0;
192   return false;
193 }
194
195 Vector2 AtlasGlyphManager::GetAtlasSize( uint32_t atlasId )
196 {
197   Toolkit::AtlasManager::AtlasSize size = mAtlasManager.GetAtlasSize( atlasId );
198   return Vector2( static_cast< float >( size.mWidth ), static_cast< float >( size.mHeight ) );
199 }
200
201 void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight )
202 {
203   Toolkit::AtlasManager::AtlasSize size;
204   size.mWidth = width;
205   size.mHeight = height;
206   size.mBlockWidth = blockWidth;
207   size.mBlockHeight = blockHeight;
208   mAtlasManager.SetNewAtlasSize( size );
209 }
210
211 Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
212 {
213   return mAtlasManager.GetPixelFormat( atlasId );
214 }
215
216 const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
217 {
218   mMetrics.mGlyphCount = 0u;
219   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
220         fontGlyphRecordIt != mFontGlyphRecords.end();
221         ++fontGlyphRecordIt )
222   {
223     mMetrics.mGlyphCount += fontGlyphRecordIt->mGlyphRecords.Size();
224   }
225   mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
226   return mMetrics;
227 }
228
229 void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta )
230 {
231   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
232         fontGlyphRecordIt != mFontGlyphRecords.end();
233         ++fontGlyphRecordIt )
234   {
235     if ( fontGlyphRecordIt->mFontId == fontId )
236     {
237       for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
238             glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
239             ++glyphRecordIt )
240       {
241         if ( glyphRecordIt->mImageId == imageId )
242         {
243           glyphRecordIt->mCount += delta;
244           if ( !glyphRecordIt->mCount )
245           {
246             mAtlasManager.Remove( glyphRecordIt->mImageId );
247             fontGlyphRecordIt->mGlyphRecords.Remove( glyphRecordIt );
248           }
249           return;
250         }
251       }
252     }
253   }
254 }
255
256 Material AtlasGlyphManager::GetMaterial( uint32_t atlasId ) const
257 {
258   return mAtlasManager.GetMaterial( atlasId );
259 }
260
261 Sampler AtlasGlyphManager::GetSampler( uint32_t atlasId ) const
262 {
263   return mAtlasManager.GetSampler( atlasId );
264 }
265
266 } // namespace Internal
267
268 } // namespace Toolkit
269
270 } // namespace Dali