Merge "SVACE Error fix TextureManager Thread bounds" into devel/master
[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 namespace
24 {
25
26 #if defined(DEBUG_ENABLED)
27   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING");
28 #endif
29
30 } // unnamed namespace
31
32 namespace Dali
33 {
34
35 namespace Toolkit
36 {
37
38 namespace Internal
39 {
40
41 AtlasGlyphManager::AtlasGlyphManager()
42 {
43   mAtlasManager = Dali::Toolkit::AtlasManager::New();
44 }
45
46 void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
47                              const uint32_t outlineWidth,
48                              const PixelData& bitmap,
49                              Dali::Toolkit::AtlasManager::AtlasSlot& slot )
50 {
51   DALI_LOG_INFO( gLogFilter, Debug::General, "Added glyph, font: %d index: %d\n", glyph.fontId, glyph.index );
52
53   // If glyph added to an existing or new atlas then a new glyph record is required.
54   // Check if an existing atlas will fit the image, create a new one if required.
55   if ( mAtlasManager.Add( bitmap, slot ) )
56   {
57     // A new atlas was created so set the texture set details for the atlas
58     Dali::Texture atlas = mAtlasManager.GetAtlasContainer( slot.mAtlasId );
59     TextureSet textureSet = TextureSet::New();
60     textureSet.SetTexture( 0u, atlas );
61     mAtlasManager.SetTextures( slot.mAtlasId, textureSet );
62   }
63
64   GlyphRecordEntry record;
65   record.mIndex = glyph.index;
66   record.mOutlineWidth = outlineWidth;
67   record.mImageId = slot.mImageId;
68   record.mCount = 1;
69
70   // Have glyph records been created for this fontId ?
71   bool foundGlyph = false;
72   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
73         fontGlyphRecordIt != mFontGlyphRecords.end(); ++fontGlyphRecordIt )
74   {
75     if ( fontGlyphRecordIt->mFontId == glyph.fontId )
76     {
77       fontGlyphRecordIt->mGlyphRecords.PushBack( record );
78       foundGlyph = true;
79       break;
80     }
81   }
82
83   if ( !foundGlyph )
84   {
85     // We need to add a new font entry
86     FontGlyphRecord fontGlyphRecord;
87     fontGlyphRecord.mFontId = glyph.fontId;
88     fontGlyphRecord.mGlyphRecords.PushBack( record );
89     mFontGlyphRecords.push_back( fontGlyphRecord );
90   }
91 }
92
93 void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
94                                           const Vector2& position,
95                                           Toolkit::AtlasManager::Mesh2D& mesh )
96 {
97   // Generate mesh data and tell Atlas Manager not to handle reference counting ( we'll do it )
98   mAtlasManager.GenerateMeshData( imageId, position, mesh, false );
99 }
100
101 bool AtlasGlyphManager::IsCached( Text::FontId fontId,
102                                 Text::GlyphIndex index,
103                                 uint32_t outlineWidth,
104                                 Dali::Toolkit::AtlasManager::AtlasSlot& slot )
105 {
106   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
107         fontGlyphRecordIt != mFontGlyphRecords.end();
108         ++fontGlyphRecordIt )
109   {
110     if ( fontGlyphRecordIt->mFontId == fontId )
111     {
112       for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
113             glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
114             ++glyphRecordIt )
115       {
116         if ( glyphRecordIt->mIndex == index && glyphRecordIt->mOutlineWidth == outlineWidth )
117         {
118           slot.mImageId = glyphRecordIt->mImageId;
119           slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
120           return true;
121         }
122       }
123     }
124   }
125   slot.mImageId = 0;
126   return false;
127 }
128
129 Vector2 AtlasGlyphManager::GetAtlasSize( uint32_t atlasId )
130 {
131   Toolkit::AtlasManager::AtlasSize size = mAtlasManager.GetAtlasSize( atlasId );
132   return Vector2( static_cast< float >( size.mWidth ), static_cast< float >( size.mHeight ) );
133 }
134
135 void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight )
136 {
137   Toolkit::AtlasManager::AtlasSize size;
138   size.mWidth = width;
139   size.mHeight = height;
140   size.mBlockWidth = blockWidth;
141   size.mBlockHeight = blockHeight;
142   mAtlasManager.SetNewAtlasSize( size );
143 }
144
145 Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
146 {
147   return mAtlasManager.GetPixelFormat( atlasId );
148 }
149
150 const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
151 {
152   std::ostringstream verboseMetrics;
153
154   mMetrics.mGlyphCount = 0u;
155   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
156         fontGlyphRecordIt != mFontGlyphRecords.end();
157         ++fontGlyphRecordIt )
158   {
159     mMetrics.mGlyphCount += fontGlyphRecordIt->mGlyphRecords.Size();
160
161     verboseMetrics << "[FontId " << fontGlyphRecordIt->mFontId << " Glyph ";
162     for ( Vector< GlyphRecordEntry >::Iterator glyphRecordEntryIt = fontGlyphRecordIt->mGlyphRecords.Begin();
163           glyphRecordEntryIt != fontGlyphRecordIt->mGlyphRecords.End();
164           ++glyphRecordEntryIt )
165     {
166       verboseMetrics << glyphRecordEntryIt->mIndex << "(" << glyphRecordEntryIt->mCount << ") ";
167     }
168     verboseMetrics << "] ";
169   }
170   mMetrics.mVerboseGlyphCounts = verboseMetrics.str();
171
172   mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
173
174   return mMetrics;
175 }
176
177 void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, uint32_t outlineWidth, int32_t delta )
178 {
179   if( 0 != delta )
180   {
181     DALI_LOG_INFO( gLogFilter, Debug::General, "AdjustReferenceCount %d, font: %d index: %d\n", delta, fontId, index );
182
183     for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
184           fontGlyphRecordIt != mFontGlyphRecords.end();
185           ++fontGlyphRecordIt )
186     {
187       if ( fontGlyphRecordIt->mFontId == fontId )
188       {
189         for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
190               glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
191               ++glyphRecordIt )
192         {
193           if ( glyphRecordIt->mIndex == index && glyphRecordIt->mOutlineWidth == outlineWidth )
194           {
195             glyphRecordIt->mCount += delta;
196             DALI_ASSERT_DEBUG( glyphRecordIt->mCount >= 0 && "Glyph ref-count should not be negative" );
197
198             if ( !glyphRecordIt->mCount )
199             {
200               mAtlasManager.Remove( glyphRecordIt->mImageId );
201               fontGlyphRecordIt->mGlyphRecords.Remove( glyphRecordIt );
202             }
203             return;
204           }
205         }
206       }
207     }
208
209     // Should not arrive here
210     DALI_ASSERT_DEBUG( false && "Failed to adjust ref-count" );
211   }
212 }
213
214 TextureSet AtlasGlyphManager::GetTextures( uint32_t atlasId ) const
215 {
216   return mAtlasManager.GetTextures( atlasId );
217 }
218
219 AtlasGlyphManager::~AtlasGlyphManager()
220 {
221   // mAtlasManager handle is automatically released here
222 }
223
224 } // namespace Internal
225
226 } // namespace Toolkit
227
228 } // namespace Dali