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